From 3c146a92f9d103cf53954149c9671bf972f0bbff Mon Sep 17 00:00:00 2001 From: OpenVelo Agent Date: Wed, 22 Jul 2026 19:56:30 +0000 Subject: [PATCH] docs: update documentation to OKF v0.1 format --- docs/architecture/key-files.md | 5 + docs/architecture/overview.md | 6 +- docs/database/category-repair-migration.md | 3 +- docs/database/schema.md | 5 +- docs/guides/dev-workflow.md | 119 +++++++++++++++++++++ docs/index.md | 5 +- 6 files changed, 136 insertions(+), 7 deletions(-) create mode 100644 docs/guides/dev-workflow.md diff --git a/docs/architecture/key-files.md b/docs/architecture/key-files.md index d7e3a95..e7e8839 100644 --- a/docs/architecture/key-files.md +++ b/docs/architecture/key-files.md @@ -12,6 +12,7 @@ timestamp: 2026-07-22T19:18:00Z |---|---| | `backend/src/main.ts` | Bootstraps Nest, middleware, OpenAPI, static assets, and SPA fallback. | | `backend/src/app.module.ts` | Wires feature modules and global providers. | +| `backend/src/config/env.schema.ts` | Zod-validated runtime config; canonical defaults for `DATABASE_PATH` (`./data/db.sqlite`) and `UPLOAD_DIR` (`./data/uploads`). | | `backend/src/database/database.module.ts` | Configures TypeORM with SQLite. | | `backend/src/database/database-init.service.ts` | Initializes the database and runs migrations; `verifySeed()` also asserts the canonical six system-category keys and reports missing/duplicate rows. | | `backend/src/database/migrations/1700000000400-RepairCategorySchemaAndSystemCategories.ts` | Forward-only repair migration: adds `created_at`/`updated_at` to legacy six-column `category` tables, deletes obsolete `FOR`/`OSI` system rows, rewrites canonical row metadata, inserts any missing canonical key, and re-asserts unique indexes. Exports `CANONICAL_SYSTEM_CATEGORIES`. | @@ -35,6 +36,10 @@ timestamp: 2026-07-22T19:18:00Z | File | Responsibility | |---|---| | `frontend/src/main.ts` | Bootstraps Angular and registers HTTP interceptors. | +| `frontend/proxy.conf.json` | Angular dev-server proxy: forwards `/api` and `/uploads` to `http://localhost:3000`. | +| `frontend/angular.json` | Angular workspace config; the `serve` target references `proxy.conf.json`. | +| `package.json` (root) | Root npm scripts; `dev` runs both workspaces via `concurrently`, `dev:backend` / `dev:frontend` run one at a time. | +| `setup.sh` | Idempotent setup: installs root + workspace deps, builds both packages, creates `./data/uploads`. | | `frontend/src/app/app.routes.ts` | Defines public, shell, child, and admin routes. | | `frontend/src/app/core/services/bootstrap.service.ts` | Caches and exposes bootstrap state, refreshes it after admin updates, and applies the resolved theme. | | `frontend/src/app/core/services/bootstrap.types.ts` | Defines bootstrap/theme payload types and maps theme tokens to CSS custom properties. | diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md index 9f5e6bc..84e2ad4 100644 --- a/docs/architecture/overview.md +++ b/docs/architecture/overview.md @@ -27,12 +27,12 @@ Browser ──HTTPS──▶ NestJS process (PORT, default 3000) ├── /api/v1/* ── controllers → services → TypeORM │ │ │ ▼ - │ better-sqlite3 - │ (DATABASE_PATH) + │ better-sqlite3 + │ (DATABASE_PATH, default ./data/db.sqlite) │ ├── /api/docs, /api/docs-json ── Swagger UI (OpenAPI 3.1) │ - ├── /uploads/* ── static file server (UPLOAD_DIR) + ├── /uploads/* ── static file server (UPLOAD_DIR, default ./data/uploads) │ └── /* ── SPA fallback (FRONTEND_DIST/index.html) ``` diff --git a/docs/database/category-repair-migration.md b/docs/database/category-repair-migration.md index 809a910..b59a825 100644 --- a/docs/database/category-repair-migration.md +++ b/docs/database/category-repair-migration.md @@ -8,7 +8,8 @@ timestamp: 2026-07-22T16:44:54Z # Purpose -Some persistent `/data/hipctf/db.sqlite` databases were created before +Some persistent HIPCTF databases (default path +[`./data/db.sqlite`](/database/schema.md)) were created before the canonical six system categories existed. They contain a legacy six-column `category` table (no `created_at` / `updated_at`) and system rows whose `system_key` / `abbreviation` no longer match the diff --git a/docs/database/schema.md b/docs/database/schema.md index d39fa50..f4667c7 100644 --- a/docs/database/schema.md +++ b/docs/database/schema.md @@ -10,8 +10,9 @@ timestamp: 2026-07-22T16:44:54Z HIPCTF uses **SQLite via better-sqlite3** with TypeORM migrations. The database is a single file (`DATABASE_PATH`, default -`/data/hipctf/db.sqlite`) running in **WAL journal mode** for better -concurrent read/write performance. +`./data/db.sqlite`, resolved relative to the process working directory) +running in **WAL journal mode** for better concurrent read/write +performance. The schema is created by a single migration (`backend/src/database/migrations/1700000000000-InitSchema.ts`) and seeded diff --git a/docs/guides/dev-workflow.md b/docs/guides/dev-workflow.md new file mode 100644 index 0000000..6162af5 --- /dev/null +++ b/docs/guides/dev-workflow.md @@ -0,0 +1,119 @@ +--- +type: guide +title: Local Development Workflow +description: How to run the backend and frontend together in development, including the root dev script, Angular dev-server proxy, and project-local data directory. +tags: [guide, dev, dev-server, proxy, concurrently, setup, tester] +timestamp: 2026-07-22T19:54:00Z +--- + +# Overview + +The HIPCTF monorepo ships a single root command — `npm run dev` — that +boots the NestJS backend and the Angular dev server in parallel, with +the Angular dev server proxying `/api` and `/uploads` calls to the +backend on port 3000. All persistent runtime files (SQLite database, +uploaded icons / attachments / logos) live under the project-local +`./data/` directory. + +# How to start the full stack (tester steps) + +1. From the repository root, install workspace dependencies once: + ``` + npm ci + ``` +2. Start both servers in parallel: + ``` + npm run dev + ``` + This uses `concurrently` to run: + * `npm --workspace backend run start:dev` (NestJS watch mode on `http://localhost:3000`) + * `npm --workspace frontend run start` (Angular dev server on `http://localhost:4200`) + Process names `backend` and `frontend` are prefixed per output line. + If either process exits with a non-zero status, the other is killed + (`--kill-others-on-fail`). +3. Open the browser: + * **Frontend (preferred for app work):** `http://localhost:4200/` + * **Backend (single-port mode, serves built SPA later):** `http://localhost:3000/` +4. To run them individually during debugging: + ``` + npm run dev:backend + npm run dev:frontend + ``` + +# Project-local data directory + +| Path | Purpose | Backed by env var | +|-------------------|-------------------------------------------------------|---------------------| +| `./data/` | Root runtime data directory (gitignored). | — | +| `./data/db.sqlite`| SQLite database file (created on first boot). | `DATABASE_PATH` | +| `./data/uploads/` | Uploaded category icons, challenge files, site logos. | `UPLOAD_DIR` | + +Both defaults are declared in `backend/src/config/env.schema.ts` and +re-declared as fallbacks in every backend code path that calls +`ConfigService.get` so direct/unit construction cannot silently revert +to the legacy absolute paths. Relative paths are resolved with +`path.resolve` against the process working directory — when launched +via the root scripts, that is the repository root. + +The legacy absolute defaults (`/data/hipctf/db.sqlite`, +`/data/hipctf/uploads`) have been removed; set `DATABASE_PATH` and +`UPLOAD_DIR` explicitly if you need to point at an external location +(e.g. a mounted volume in production). + +The data directory is created automatically: +* `DatabaseModule` ensures the parent directory of `DATABASE_PATH` + exists before connecting. +* `main.ts`, `UploadsController`, `buildMulter`, and + `UploadsStaticMiddleware` all `mkdir -p` the upload directory on + startup. +* `setup.sh` creates `./data/uploads` before any build so first-boot + Multer writes never fail. + +# Angular dev-server proxy + +`frontend/proxy.conf.json` is wired into the `serve` target in +`frontend/angular.json` so relative URLs from the SPA hit the backend +without CORS prompts: + +| Origin path | Target | Notes | +|-------------|-------------------------|--------------------------------------------------------| +| `/api` | `http://localhost:3000` | All REST controllers + SSE endpoints. `changeOrigin: true`. | +| `/uploads` | `http://localhost:3000` | Static files served by `UploadsStaticMiddleware`. | + +The proxy is **development-only.** In production (`npm start` / +`backend/dist/main.js`) the backend serves the built SPA directly and +no proxy is involved. + +# Root scripts + +| Script | What it does | +|---------------------|--------------------------------------------------------------------| +| `npm run dev` | Start backend + frontend together via `concurrently`. | +| `npm run dev:backend` | Start only the NestJS backend in watch mode. | +| `npm run dev:frontend` | Start only the Angular dev server. | +| `npm start` | Run the **production** backend (`node backend/dist/main.js`). | +| `npm run build` | Build both workspaces (frontend first, then backend). | +| `npm run start:dev` | Alias for `npm run dev` (kept for backwards compatibility). | +| `npm test` | Run the full Jest project (backend + frontend). | + +# Expected behavior (tester) + +* `npm run dev` displays interleaved backend and frontend logs, each + prefixed with the process name and a color. +* The Angular dev server prints `Application bundle generation complete` + within a few seconds and the page is reachable at + `http://localhost:4200/`. +* Visiting `http://localhost:4200/` triggers + `GET /api/v1/bootstrap` (proxied to port 3000) and shows the + appropriate public, login, or bootstrap page. +* Uploads (e.g. category icons via the admin UI) land under + `./data/uploads/` and are immediately readable from the dev frontend + via `/uploads/...` (proxied). +* Pressing `Ctrl+C` once terminates both processes cleanly. + +# See also + +- [System Overview](/architecture/overview.md) +- [Database Schema Overview](/database/schema.md) +- [Uploads Endpoints](/api/uploads.md) +- [Key Files Index](/architecture/key-files.md) diff --git a/docs/index.md b/docs/index.md index b68315a..130a4ae 100644 --- a/docs/index.md +++ b/docs/index.md @@ -11,7 +11,7 @@ scoreboard, an event window with a public countdown, theming, and admin controls. The docs below are organized by purpose so agents can pull just the slice -they need. Last regenerated 2026-07-22T19:18:00Z. +they need. Last regenerated 2026-07-22T19:54:00Z. # Architecture @@ -80,6 +80,9 @@ they need. Last regenerated 2026-07-22T19:18:00Z. * [Cross-Tab Authenticated Shell Invalidation](/guides/cross-tab-invalidation.md) - How a logout in one tab, or an unauthorized SSE response, instantly clears and redirects every other open tab of the SPA. +* [Local Development Workflow](/guides/dev-workflow.md) - How to run the + backend and frontend together (`npm run dev`), the Angular dev-server + proxy, and the project-local `./data/` directory. * [Session Restoration on Reload](/guides/session-restoration.md) - How the SPA keeps a user signed in across hard refreshes and how the guards wait for bootstrap + auth hydration before deciding where to