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
       │
  ┌────▼─────┐
  │ Middleware │  security → cors → sanitization → rateLimiter → auth
  ├───────────┤
  │  Routes   │  OpenAPI-typed endpoint handlers (164 files)
  ├───────────┤
  │ Services  │  Business logic, orchestration (98 files)
  ├───────────┤
  │    DB     │  Drizzle ORM queries, schema (140 tables)
  └───────────┘

Routes delegate to services. Services contain business logic and database access. See Service Layer Pattern for conventions.

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/ (48 files).

Directory Structure

DirectoryFilesPurpose
src/routes/164API endpoint handlers with OpenAPI schemas
src/services/98Business logic and data access
src/lib/126Shared utilities (auth, encryption, sanitization)
src/interfaces/48TypeScript interfaces for DI contracts
src/middleware/10Request processing pipeline
src/db/Schema, seeds, shared schemas
src/test/Unit and integration tests

Middleware Stack

Processing order defined in backend/src/index.ts. See Backend Middleware and Middleware Stack for details.

MiddlewareFilePurpose
Securitymiddleware/security.tsCSP, HSTS, X-Frame-Options headers
CORS(Hono built-in)Cross-origin request handling
Sanitizationmiddleware/sanitization.tsDOMPurify XSS protection
Rate Limitermiddleware/rateLimiter.tsAuth: 5/15min, API: 100/min
Authmiddleware/auth.tsJWT verification, user context
Portal Authmiddleware/portal-auth.tsExternal stakeholder auth
RBACmiddleware/rbac.tsRole-based access control
Audit Loggermiddleware/auditLogger.tsAction audit trail
Error Handlermiddleware/errorHandler.tsStructured error responses
Timeoutmiddleware/timeout.tsRequest timeout enforcement

Key Libraries

ModulePathPurpose
Authsrc/lib/auth.tsJWT, argon2id password hashing via Bun.password
Encryptionsrc/lib/encryption.tsAES-256-GCM for OAuth tokens, PII
Sanitizationsrc/lib/sanitization-helpers.tsstrictTextField, sanitizedLocalizedText
Ownership Guardssrc/lib/ownership-guards.tsverifyProjectAccess(), verifyBuildingAccess()
File Uploadsrc/lib/file-upload.tsTigris S3-compatible object storage

Testing

  • Runner: Bun’s built-in test runner
  • Unit tests: src/test/unit/ — no database required
  • Integration tests: src/test/integration/ — full API route tests with test DB
  • Helpers: setupTestServer(), resetTestDatabase(), createAuthenticatedTestUser(), apiRequest()
  • Coverage: 70% threshold, enforced in CI

See Error Handling Pattern and Validation Pattern for request/response handling conventions.