Backend Architecture
The backend is a Bun + Hono TypeScript API server with OpenAPI support, running on port 3000 behind nginx. Entry point: backend/src/index.ts.
Layered Architecture
HTTP Request BullMQ Job
│ │
┌────▼─────┐ │
│ Middleware │ security → cors → sanitization → rateLimiter → auth
├───────────┤ ┌─────▼──────┐
│ Routes │ OpenAPI handlers │ Processors │ ← presentation (HTTP / batch)
├───────────┤ └─────┬──────┘
│ Services │ actor, authz, Zod, DTO │
├───────────┴─────────────────────────▼┐
│ Domain modules │ operations, invariants — sole Drizzle owner
├───────────────────────────────────────┤
│ DB Drizzle ORM, schema │
└───────────────────────────────────────┘
Routes delegate to services; services delegate persistence to domain modules; job processors consume domain modules directly (peer clients of services, no services slice). Legacy direct DB access is allowlisted and migrates on touch — see Persistence Topology (I#2013) and Service Layer Pattern.
Dependency Injection
The backend uses a DI container pattern through Hono’s context variables. See Dependency Injection for full details.
// In route handlers — access services via c.var
const { documentRequests, portal } = c.var.services;
// Infrastructure and cross-cutting concerns
const { logger, cache } = c.var.container.infrastructure;Container is initialized at startup and injected into every request via middleware. Service interfaces are defined in backend/src/interfaces/ (71 files).
Directory Structure
File counts as of 2026-06 (excluding co-located tests):
| Directory | Files | Purpose |
|---|---|---|
src/routes/ | 199 | API endpoint handlers with OpenAPI schemas |
src/services/ | 148 | Business logic (persistence delegated to domain modules) |
src/lib/ | 163 | Shared utilities + domain modules (jobs/, billing/, file-operations/) |
src/interfaces/ | 71 | TypeScript interfaces for DI contracts |
src/middleware/ | 11 | Request processing pipeline |
src/db/ | — | Schema, mocks, shared schemas |
src/test/ | — | Shared test infrastructure (new tests are co-located) |
Middleware Stack
Processing order defined in backend/src/index.ts. See Backend Middleware and Middleware Stack for details.
| Middleware | File | Purpose |
|---|---|---|
| Security | middleware/security.ts | CSP, HSTS, X-Frame-Options headers |
| CORS | (Hono built-in) | Cross-origin request handling |
| Sanitization | middleware/sanitization.ts | DOMPurify XSS protection |
| Rate Limiter | middleware/rateLimiter.ts | Auth: 5/15min, API: 100/min |
| Auth | middleware/auth.ts | JWT verification, user context |
| Portal Auth | middleware/portal-auth.ts | External stakeholder auth |
| RBAC | middleware/rbac.ts | Role-based access control |
| Internal User | middleware/require-internal-user.ts | Restrict routes to internal employees |
| Audit Logger | middleware/auditLogger.ts | Action audit trail |
| Error Handler | middleware/errorHandler.ts | Structured error responses |
| Timeout | middleware/timeout.ts | Request timeout enforcement |
Key Libraries
| Module | Path | Purpose |
|---|---|---|
| Auth | src/lib/auth.ts | JWT, argon2id password hashing via Bun.password |
| Encryption | src/lib/encryption.ts | AES-256-GCM via ENCRYPTION_KEY for OAuth tokens, PII |
| Sanitization | src/lib/sanitization-helpers.ts | strictTextField, sanitizedLocalizedText |
| Ownership Guards | src/lib/ownership-guards.ts | verifyProjectAccess(), verifyBuildingAccess() |
| Storage | src/lib/storage.ts | Tigris S3 client — stream-based access goes through FileService (buffer helpers deprecated) |
Testing
- Runner: Bun’s built-in test runner
- New tests are co-located with production code:
.unit.test.ts(no DB/network) and.integration.test.ts(real DB or HTTP routes) — convention from PR#1690; legacy tests undersrc/test/{unit,integration}/stay put - Shared test infrastructure:
src/test/(setup.ts,utils/db.ts,fixtures/) - Helpers:
setupTestServer(),resetTestDatabase(),createAuthenticatedTestUser(),apiRequest() - Coverage: 70% threshold; CI runs backend tests in 3 shards with merged coverage + diff-coverage gate (PR#2000)
See Error Handling Pattern and Validation Pattern for request/response handling conventions.
Related Pages
- Architecture Overview — System-wide architecture
- Service Layer Pattern — How services are structured
- Dependency Injection — Container pattern details
- Middleware Stack — Full middleware pipeline
- Routes Overview — All API endpoints
- Services Overview — All service modules
- Backend Middleware — Middleware implementation details
- Library Utilities — Utility module catalog
- Database Architecture — ORM and schema
- RBAC Authorization — Permission model
- Authentication — JWT and password handling
- External Integrations — Third-party connectors