Request Lifecycle¶
What happens when a client calls a REST endpoint on dichit-backend, end to end.
Sequence¶
sequenceDiagram
autonumber
participant C as Client
participant F as Fastify
participant P as Plugins
participant R as Route/Controller
participant UC as Use case
participant RPO as Repository (infra)
participant DB as PostgreSQL
C->>F: HTTP request
F->>P: shared + infrastructure plugins
P->>P: security (helmet), CORS, correlation id, request logging, auth
F->>R: route matched + JSON-schema validation (body/query/params)
alt validation fails
R-->>C: 400/422 error response
end
R->>UC: controller calls use case (thin)
UC->>UC: business rules, authz checks, UnitOfWork when needed
UC->>RPO: repository interface
RPO->>DB: Prisma / raw SQL
DB-->>RPO: rows
RPO-->>UC: mapped result
UC-->>R: result
R-->>C: HTTP response (BigInt serialized to string) Stage details¶
1. Boot & env¶
server.ts → init.ts loads the env file for NODE_ENV and initializes Sentry before the app is built (see overview.md).
2. Plugins (ordered)¶
Plugins in src/infrastructure/plugins are autoloaded in numeric order:
00-websocket 01-security 02-correlation-id 03-error-handler
04-cors 05-route-not-found-handler 06-auth
07-cookie 08-sentry 09-raw-body 10-request-logging
01-security— Helmet headers.02-correlation-id— request/correlation id used by logs.03-error-handler— maps typed errors to HTTP responses (see development/error-handling).04-cors— allowed origins from config.06-auth— JWT strategy/hooks (see development/authentication).10-request-logging— structured pino logging with the request id.
3. Route validation¶
Every route declares a JSON schema (built with @fastify/type-provider-json-schema-to-ts and/or Zod). Fastify validates body, querystring, params, and headers; a failed validation short-circuits to an error response (see development/validation).
4. Thin controller → use case¶
Controllers validate input, delegate to an application use case, and format the response. Business rules live in use cases, never in the controller.
5. Data access¶
Use cases go through repository interfaces. Repositories live under src/infrastructure/db/postgres/repositories. Multi-step writes use the UnitOfWork transaction pattern (see database/optimization).
6. Response¶
Responses are serialized with bigint: 'string', so BigInt column values are returned as JSON strings. Errors are handled centrally and never leak stack traces (see development/error-handling).
Lifecycle for background work¶
Heavy or asynchronous work is offloaded to BullMQ queue processors rather than done inline (see event-driven.md):
flowchart LR
R["Request handler"] -->|enqueue| Q["BullMQ (Redis)"]
Q --> W["Queue worker"]
W --> S["S3 / FCM / mail / SMS"]