99 lines
3.4 KiB
Markdown
99 lines
3.4 KiB
Markdown
# Gem Track Backend Starter
|
|
|
|
This repository is scaffolded as a production-ready modular monolith using:
|
|
|
|
- Node.js
|
|
- TypeScript
|
|
- Express
|
|
- TypeORM
|
|
- TSOA
|
|
- Swagger UI
|
|
|
|
## Architecture Goals
|
|
|
|
- Clean Architecture + Domain Driven Design
|
|
- Strict separation of `domain`, `application`, `infrastructure`, and `interfaces`
|
|
- Multi-tenant SaaS readiness
|
|
- Scalability through bounded contexts
|
|
- Swagger/OpenAPI documentation via TSOA
|
|
|
|
## Folder Structure
|
|
|
|
```text
|
|
src/
|
|
bootstrap/ # Composition root and dependency wiring
|
|
main.ts # Process startup and graceful shutdown
|
|
app.ts # Express application assembly
|
|
|
|
shared/
|
|
domain/ # Pure business abstractions
|
|
application/ # Cross-cutting use-case ports/contracts
|
|
infrastructure/ # DB, security, logging, config, messaging
|
|
interfaces/http/ # Middleware, presenters, TSOA, Swagger
|
|
|
|
modules/
|
|
tenancy/
|
|
domain/ # Aggregate, repository contract, events
|
|
application/ # Commands, queries, DTOs, handlers
|
|
infrastructure/ # TypeORM entity, mapper, repository impl
|
|
interfaces/http/controllers/ # TSOA controllers
|
|
|
|
types/ # Framework type augmentation
|
|
```
|
|
|
|
## Dependency Flow
|
|
|
|
Dependencies always point inward:
|
|
|
|
`interfaces -> application -> domain`
|
|
|
|
`infrastructure` implements ports defined by `application` or contracts defined by `domain`.
|
|
|
|
Rules:
|
|
|
|
- `domain` does not import Express, TSOA, TypeORM, or database code.
|
|
- `application` orchestrates use cases and depends only on domain contracts and abstract ports.
|
|
- `interfaces` is transport-only and should never hold business rules.
|
|
- `repositories` return domain aggregates, not ORM entities.
|
|
- `TypeORM entities` stay in infrastructure and are mapped to/from domain aggregates.
|
|
|
|
## Multi-Tenant Strategy
|
|
|
|
The scaffold is built around a tenant-aware request context:
|
|
|
|
- `tenant.middleware` resolves tenant from headers, subdomain, or request metadata.
|
|
- `TenantContext` flows from the HTTP edge into application and infrastructure.
|
|
- `tenant-data-source.resolver.ts` centralizes tenancy-aware database access.
|
|
- Shared-schema is the default mode, but the resolver is intentionally shaped so you can grow into schema-per-tenant or database-per-tenant.
|
|
|
|
## Swagger
|
|
|
|
Swagger is exposed from:
|
|
|
|
- `GET /docs`
|
|
- `GET /swagger.json`
|
|
|
|
TSOA controller decorators are used for OpenAPI generation, and the generated artifacts are written to:
|
|
|
|
- `src/shared/interfaces/http/tsoa/generated/routes.ts`
|
|
- `src/shared/interfaces/http/tsoa/generated/swagger.json`
|
|
|
|
The repository also includes starter generated files so the scaffold is understandable before running code generation.
|
|
|
|
## Sample Module
|
|
|
|
The included `tenancy` bounded context demonstrates:
|
|
|
|
- Domain aggregate with business invariants
|
|
- Application command/query handlers
|
|
- Repository contract in the domain layer
|
|
- TypeORM repository implementation in infrastructure
|
|
- TSOA controller in interfaces
|
|
|
|
## Suggested Next Steps
|
|
|
|
1. Install dependencies with `npm install`.
|
|
2. Generate TSOA artifacts with `npm run tsoa:spec && npm run tsoa:routes`.
|
|
3. Extend `modules/` with bounded contexts such as `identity-access`, `catalog`, `billing`, and `orders`.
|
|
4. Add migrations, outbox processing, authentication policies, and integration tests.
|