Files
HIPCTF2/docs/architecture/overview.md
T
2026-07-21 15:07:41 +00:00

4.0 KiB

type, title, description, tags, timestamp
type title description tags timestamp
architecture System Overview High-level layout of the HIPCTF monorepo (NestJS API + Angular SPA) and how they communicate.
architecture
backend
frontend
overview
2026-07-21T15:05:00Z

Overview

HIPCTF is delivered as a Node.js npm workspace containing two packages:

Package Path Stack
Backend backend/ NestJS 10 + TypeORM + better-sqlite3
Frontend frontend/ Angular 17 standalone components

The backend also serves the built Angular SPA as static files and falls back to index.html for client-side routes, so a single Node process hosts the whole application.

Topology

Browser  ──HTTPS──▶  NestJS process (PORT, default 3000)
                       │
                       ├── /api/v1/*  ── controllers → services → TypeORM
                       │                                 │
                       │                                 ▼
                       │                         better-sqlite3
                       │                          (DATABASE_PATH)
                       │
                       ├── /api/docs, /api/docs-json ── Swagger UI (OpenAPI 3.1)
                       │
                       ├── /uploads/*  ── static file server (UPLOAD_DIR)
                       │
                       └── /*  ── SPA fallback (FRONTEND_DIST/index.html)

Backend entrypoint flow

backend/src/main.ts orchestrates startup in this order:

  1. Create the Nest application.
  2. Read configuration via ConfigService (validated against backend/src/config/env.schema.ts).
  3. Call DatabaseInitService.init() so migrations + WAL PRAGMA run before HTTP traffic is accepted.
  4. Register global middleware: helmet, cookieParser, JSON / URL-encoded parsers, then CsrfMiddleware (registered explicitly so it can read the parsed body).
  5. Mount /uploads static and Angular static (FRONTEND_DIST).
  6. Build the OpenAPI 3.1 document via toOpenApi31() and expose Swagger UI at /api/docs and JSON at /api/docs-json.
  7. Install SpaFallbackMiddleware so non-/api, non-/uploads, extensionless GET requests return index.html.
  8. app.listen(port).

Frontend entrypoint flow

frontend/src/main.ts bootstraps a standalone Angular app:

  1. provideHttpClient(withInterceptors([csrfInterceptor, authInterceptor])) attaches the CSRF header on unsafe methods and the Bearer access token on every request.
  2. provideRouter(APP_ROUTES, withComponentInputBinding()).
  3. AppComponent.ngOnInit() calls BootstrapService.load() which fetches GET /api/v1/bootstrap and applies the returned theme tokens to CSS custom properties on document.documentElement.

Cross-cutting concepts

Concern Backend Frontend
Authentication JwtAuthGuard (global) + AuthGuard('jwt') strategy AuthService signal + authInterceptor
Authorization AdminGuard + @Roles('admin') decorator authGuard for /, adminGuard for /admin (delegates to pure decideAdminGuard)
CSRF CsrfMiddleware (skips /api/v1/auth/login and /api/v1/auth/register-first-admin) csrfInterceptor reads csrf cookie
Errors ApiErrorGlobalExceptionFilter returns {code, message, details, path, timestamp} Components display error?.error?.message
Config envSchema (zod) + validateEnv None (consumed via bootstrap)

See also