Files
HIPCTF2/docs/guides/dev-workflow.md
T

5.4 KiB

type, title, description, tags, timestamp
type title description tags timestamp
guide Local Development Workflow How to run the backend and frontend together in development, including the root dev script, Angular dev-server proxy, and project-local data directory.
guide
dev
dev-server
proxy
concurrently
setup
tester
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