--- type: architecture title: Backend Module Map description: NestJS modules, controllers, services, and how they are wired together. tags: [architecture, backend, nestjs, modules] timestamp: 2026-07-21T14:43:00Z --- # Module Map All modules are imported in `backend/src/app.module.ts`. The root module also registers two global providers: | Global provider | Purpose | |---------------------------|--------------------------------------------------------| | `APP_GUARD = JwtAuthGuard` | Enforces JWT auth unless the handler is `@Public()` | | `APP_FILTER = GlobalExceptionFilter` | Normalizes errors into the standard envelope | # Modules | Module | Path | Responsibility | |------------------|-----------------------------------------------|-------------------------------------------------------------------------------------------------| | `DatabaseModule` | `backend/src/database/database.module.ts` | Configures TypeORM with `better-sqlite3`, registers entities, runs migrations, enforces WAL. | | `CommonModule` | `backend/src/common/common.module.ts` | Provides shared services (CSRF middleware class, backoff, registration rate limit, SSE hub, theme loader, etc.). | | `SettingsModule` | `backend/src/modules/settings/settings.module.ts` | Exposes `SettingsService` (get/set/getAll over `setting` table). | | `AuthModule` | `backend/src/modules/auth/auth.module.ts` | `AuthController` (`/api/v1/auth/*`) + `AuthService` (login/refresh/logout/register-first-admin).| | `UsersModule` | `backend/src/modules/users/users.module.ts` | `UsersController` (`/api/v1/auth/register-first-admin`) + `UsersService` (last-admin invariant). | | `SetupModule` | `backend/src/modules/setup/setup.module.ts` | `SetupController` (`POST /api/v1/setup/create-admin`) + `SetupService`. Returns 404 once any admin exists (route hidden). | | `SystemModule` | `backend/src/modules/system/system.module.ts` | `SystemController` (`/api/v1/bootstrap`, `/event/status`, SSE streams) + `SystemService`. | | `AdminModule` | `backend/src/modules/admin/admin.module.ts` | `AdminController` (`/api/v1/admin/users*`) + `AdminService`. Gated by `AdminGuard` + `@Roles('admin')`. | | `UploadsModule` | `backend/src/modules/uploads/uploads.module.ts` | `UploadsController` (`/api/v1/uploads/*`). Admin-only multipart. | | `FrontendModule` | `backend/src/frontend/frontend.module.ts` | Registers `SpaFallbackMiddleware` and the uploads static helper. | # Controllers | Controller | Path prefix | Auth | Source | |------------------------|-------------------------|--------------|--------------------------------------------------------------| | `AuthController` | `/api/v1/auth` | Mostly public (login, refresh, logout, csrf) | `backend/src/modules/auth/auth.controller.ts` | | `UsersController` | `/api/v1/auth/register-first-admin` | Public (bootstrap-only) | `backend/src/modules/users/users.controller.ts` | | `SetupController` | `/api/v1/setup/create-admin` | Public (bootstrap-only; 404 once an admin exists) | `backend/src/modules/setup/setup.controller.ts` | | `AdminController` | `/api/v1/admin` | Admin only | `backend/src/modules/admin/admin.controller.ts` | | `SystemController` | `/api/v1` | Public | `backend/src/modules/system/system.controller.ts` | | `UploadsController` | `/api/v1/uploads` | Admin only | `backend/src/modules/uploads/uploads.controller.ts` | # Common services | Service | Path | Purpose | |----------------------------------|---------------------------------------------------------------|--------------------------------------------------------| | `CsrfMiddleware` | `backend/src/common/middleware/csrf.middleware.ts` | Mints/validates CSRF tokens via cookie + header. | | `JwtAuthGuard` | `backend/src/common/guards/jwt-auth.guard.ts` | Global guard; honors `@Public()` decorator. | | `AdminGuard` | `backend/src/common/guards/admin.guard.ts` | Requires authenticated user with `role === 'admin'`. | | `RolesGuard` | `backend/src/common/guards/roles.guard.ts` | Enforces `@Roles(...)` metadata. | | `GlobalExceptionFilter` | `backend/src/common/filters/global-exception.filter.ts` | Converts exceptions to standard envelope. | | `EventStatusService` | `backend/src/common/services/event-status.service.ts` | Computes `Stopped`/`Running` and `countdownMs`. | | `LoginBackoffService` | `backend/src/common/services/login-backoff.service.ts` | Per-IP+username brute-force throttle. | | `RegistrationRateLimitService` | `backend/src/common/services/registration-rate-limit.service.ts` | Per-IP rate limit on first-admin registration. | | `SseHubService` | `backend/src/common/services/sse-hub.service.ts` | In-process pub/sub for SSE streams. | | `ThemeLoaderService` | `backend/src/common/utils/theme-loader.service.ts` | Loads + validates the 10 canonical themes. | | `ZodValidationPipe` | `backend/src/common/pipes/zod-validation.pipe.ts` | Replaces `ValidationPipe` for zod-validated DTOs. | | `TransformInterceptor` | `backend/src/common/interceptors/transform.interceptor.ts` | Optional response transformer. | # Decorators | Decorator | Path | Purpose | |-----------------|------------------------------------------------------------|----------------------------------| | `@Public()` | `backend/src/common/decorators/public.decorator.ts` | Mark a route as unauthenticated. | | `@Roles(...)` | `backend/src/common/decorators/roles.decorator.ts` | Required role(s). | | `@SkipCsrf()` | `backend/src/common/decorators/skip-csrf.decorator.ts` | Exempt a route from CSRF check. | # Startup chain `main.ts` → `AppModule` (loads `ConfigModule`, then all feature modules) → `DatabaseInitService.init()` (runs migrations + WAL) → `app.use(...)` middlewares (helmet, parsers, CSRF, static) → `SwaggerModule.setup(...)` (OpenAPI 3.1) → `SpaFallbackMiddleware` → `app.listen()`. # See also - [System Overview](/architecture/overview.md) - [Key Files Index](/architecture/key-files.md) - [REST API Overview](/api/rest-overview.md)