gemtrack-backend/docs/architecture.md

52 lines
2.0 KiB
Markdown

# Backend Architecture
## Layer Responsibilities
### Domain
- Encapsulates business rules and invariants.
- Contains aggregates, entities, value objects, domain events, and repository interfaces.
- Has no knowledge of HTTP, databases, or frameworks.
### Application
- Implements use cases through command and query handlers.
- Coordinates domain models, authorization, transactional boundaries, and DTO shaping.
- Depends on domain contracts and abstract infrastructure ports.
### Infrastructure
- Implements technical details such as TypeORM repositories, database connections, JWT, logging, caching, messaging, and external services.
- Maps ORM entities to domain aggregates.
- Can be swapped without changing use-case or domain logic.
### Interfaces
- Adapts delivery mechanisms such as HTTP, queues, or scheduled jobs to application use cases.
- TSOA controllers parse requests and delegate to application handlers.
- Middleware resolves request-scoped concerns like tenant context, authentication, tracing, and error formatting.
## Interaction Flow
1. HTTP request reaches Express.
2. Middleware enriches the request with `RequestContext` and `TenantContext`.
3. TSOA controller transforms the request into a command/query DTO.
4. Application handler invokes domain behavior using repository contracts.
5. Infrastructure repository loads/persists aggregates through TypeORM entities and mappers.
6. Controller returns a response DTO.
7. Error middleware converts exceptions into consistent API responses.
## Multi-Tenant Notes
The recommended progression is:
1. Shared database / shared schema with `tenant_id` enforcement in repositories.
2. Schema-per-tenant for higher isolation.
3. Database-per-tenant for top-tier compliance or noisy-neighbor isolation.
Keep tenancy decisions at the edge and in infrastructure:
- Controllers should not manually enforce tenant filters.
- Application handlers should accept tenant context only when the use case is tenant-specific.
- Infrastructure repositories must apply tenant scope consistently.