docs: update documentation to OKF v0.1 format
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
---
|
||||
type: architecture
|
||||
title: System Overview
|
||||
description: High-level layout of the HIPCTF monorepo (NestJS API + Angular SPA) and how they communicate.
|
||||
tags: [architecture, backend, frontend, overview]
|
||||
timestamp: 2026-07-21T14:18: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` route guard |
|
||||
| CSRF | `CsrfMiddleware` (skips `/api/v1/auth/login` and `/api/v1/auth/register-first-admin`) | `csrfInterceptor` reads `csrf` cookie |
|
||||
| Errors | `ApiError` → `GlobalExceptionFilter` returns `{code, message, details, path, timestamp}` | Components display `error?.error?.message` |
|
||||
| Config | `envSchema` (zod) + `validateEnv` | None (consumed via bootstrap) |
|
||||
|
||||
# See also
|
||||
|
||||
- [Backend Module Map](/architecture/backend-modules.md)
|
||||
- [Frontend Structure](/architecture/frontend-structure.md)
|
||||
- [REST API Overview](/api/rest-overview.md)
|
||||
Reference in New Issue
Block a user