Files
HIPCTF2/docs/architecture/backend-modules.md
T
2026-07-22 20:26:26 +00:00

8.8 KiB

type, title, description, tags, timestamp
type title description tags timestamp
architecture Backend Module Map NestJS modules, controllers, services, and how they are wired together.
architecture
backend
nestjs
modules
2026-07-21T22:19:08Z

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/{register,login,refresh,logout,me,change-password,csrf}) + AuthService (login/refresh/logout/register-first-admin + public register + getMe + changePassword). Imports SettingsModule so the public-register flow can read the registrationsEnabled flag, and UsersModule (forwardRef) for UsersRankService.
UsersModule backend/src/modules/users/users.module.ts UsersController (/api/v1/auth/register-first-admin) + UsersService (last-admin invariant) + UsersRankService (rankOfUser(manager, userId) -> {rank, points} over the solve table).
SetupModule backend/src/modules/setup/setup.module.ts SetupController (POST /api/v1/setup/create-admin) + SetupService. Returns 409 SYSTEM_INITIALIZED once any admin exists; serializes concurrent first-admin attempts via an in-process promise chain.
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 Four controllers (AdminController for /api/v1/admin/users*, AdminGeneralController for /api/v1/admin/general/*, AdminCategoriesController for /api/v1/admin/categories*, AdminChallengesController for /api/v1/admin/challenges*) plus their services (AdminService, AdminGeneralService, AdminCategoriesService, AdminChallengesService, ChallengeFilesService). Gated by AdminGuard + @Roles('admin'). Imports TypeOrmModule.forFeature([UserEntity, CategoryEntity, ChallengeEntity, ChallengeFileEntity, SolveEntity]), AuthModule, UsersModule, SettingsModule, and CommonModule (for SseHubService, ThemeLoaderService).
UploadsModule backend/src/modules/uploads/uploads.module.ts UploadsController (/api/v1/uploads/*). Admin-only multipart.
BlogModule backend/src/modules/blog/blog.module.ts BlogController (GET /api/v1/blog/posts) + BlogService (lists status='published' rows).
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; 409 SYSTEM_INITIALIZED once an admin exists) backend/src/modules/setup/setup.controller.ts
AdminController /api/v1/admin Admin only backend/src/modules/admin/admin.controller.ts
AdminGeneralController /api/v1/admin/general Admin only backend/src/modules/admin/admin-general.controller.ts
AdminCategoriesController /api/v1/admin/categories Admin only backend/src/modules/admin/admin-categories.controller.ts
AdminChallengesController /api/v1/admin/challenges Admin only backend/src/modules/admin/admin-challenges.controller.ts
SystemController /api/v1 Mixed (bootstrap/event/scoreboard/settings are public; events/status SSE is JWT-protected) backend/src/modules/system/system.controller.ts
UploadsController /api/v1/uploads Admin only backend/src/modules/uploads/uploads.controller.ts
BlogController /api/v1/blog Public backend/src/modules/blog/blog.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 the 4-state event state machine (countdown/running/stopped/unconfigured) via getState() plus the legacy getStatus() shape (Stopped/Running + 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.tsAppModule (loads ConfigModule, then all feature modules) → DatabaseInitService.init() (runs migrations + WAL) → app.use(...) middlewares (helmet, parsers, CSRF, static) → SwaggerModule.setup(...) (OpenAPI 3.1) → SpaFallbackMiddlewareapp.listen().

See also