# Child Gold Land — Nest API (primary backend) NestJS API for Child Gold Land (primary backend since G2). Legacy Fastify `backend/` was removed in G4 (2026-08-01). ## Requirements - **Node.js:** `^22.18.0` or `>=24.12.0` (`package.json` → `engines`) - **Pinned for local dev / CI:** `22.18.0` (see `.nvmrc`) ```powershell nvm install 22.18.0 nvm use 22.18.0 ``` After switching Node on a new machine, ensure **better-sqlite3** matches the Node ABI: ```powershell npm ci # if load fails: npm rebuild better-sqlite3 ``` On Linux CI/runners, native build needs `build-essential` and `python3`. ## Configuration Copy `.env.example` to `.env` for a new machine. Do not commit `.env`. | Variable | Local development | |----------|-------------------| | `PORT` | `3000` | | `CORS_ORIGIN` | `http://localhost:5174` (Vite dev server) | | `DB_PATH` | optional; defaults to `backend-nest/data/app.db` | | `JWT_SECRET` | dev value in `.env.example`; required in production | **CI/tests** use temporary SQLite paths or env overrides — never commit or upload `data/app.db`. ## Development (this repo) ```powershell npm ci npm run build # first time or after src changes if not using dev watch npm run dev # nest start --watch # or run compiled: npm run start ``` - Health: http://127.0.0.1:3000/health - API prefix: `/api/...` ## Frontend (sibling repo) Vue app: `gold_land_user` on Gitea — dev http://localhost:5174, proxies `/api` to this backend. ## CI (Gitea Actions) Workflow: [`.gitea/workflows/ci.yml`](.gitea/workflows/ci.yml) (runs on **push** / **pull_request** when **act_runner** is available — **not verified** on `get.feep.ir` from this repo alone). ### Job **checks** ```powershell npm ci npm run type-check npm run build npm run test ``` - **Node:** `22.18.0` - **Env in job:** `NODE_ENV=test`, `JWT_SECRET=ci-test-jwt-not-for-production` (not production secrets) - **Timeout:** 25 minutes - **Cache:** npm optional via `actions/setup-node` ### Local equivalent Same commands as the CI job above. Use a **clean** tree: ```powershell Remove-Item -Recurse -Force node_modules -ErrorAction SilentlyContinue npm ci npm run type-check npm run build npm run test ``` ### E2E (frontend repo) Browser E2E lives in **frontend** (`.gitea/workflows/ci.yml` job **e2e**). It clones this repo at a **pinned ref** (`frontend/e2e/backend.contract.json` + optional variable `E2E_BACKEND_REF`). Backend CI does not run Playwright. ### Runner prerequisites - Node **22.18.0** - Toolchain for **better-sqlite3** native module on Linux ### Secrets This workflow needs **no** repository secrets. Frontend E2E may use `E2E_BACKEND_CHECKOUT_TOKEN` to clone this repo if it is private. ### Not yet verified on a real runner - Workflow execution on `get.feep.ir` with registered **act_runner** - `npm ci` + full test suite on a clean Linux runner (validated locally in a temp checkout — see stage 7 report) ## Optional: start backend + frontend (Windows) ```powershell powershell -ExecutionPolicy Bypass -File .\scripts\dev-local-stack.ps1 ``` Test ports + temp DB (does not touch `data/app.db`): ```powershell powershell -ExecutionPolicy Bypass -File .\scripts\dev-local-stack.ps1 -UseTestPorts -SmokeTest ``` ## Production ```powershell npm run build npm run start ``` Set `NODE_ENV=production` and a strong `JWT_SECRET` via environment or `.env` on the server. ## Tests Uses **temporary SQLite files only** — not `data/app.db`. ```powershell npm run test ``` Includes: progression, integration, concurrency, gold-precision, lesson-rewards, dual-connection. Removed historical `test:cutover:*` scripts — see [docs/cutover-scripts-removed.md](docs/cutover-scripts-removed.md). ## Docker `docker-compose.yml` in this repo runs backend only. Full stack compose lives in the **frontend** repo. Trial deploy guide (6 lessons, placeholders, backup, rollback): [../frontend/docs/DEPLOY-TRIAL.md](../frontend/docs/DEPLOY-TRIAL.md) when repos are siblings, or `frontend/docs/DEPLOY-TRIAL.md` in the user repo. ## Backup / restore (SQLite) WAL-safe backup (not raw copy): ```powershell $env:DB_PATH = ".\data\app.db" $env:BACKUP_DIR = ".\backups" $env:BACKUP_RETENTION_DAYS = "14" npm run backup:sqlite npm run restore:sqlite -- backups\app-....db .\restored-trial.db ``` **Live database path:** the script cannot restore directly onto configured `DB_PATH`. Stop the service, restore to a sibling file, swap files, remove stale `-wal`/`-shm`. See [docs/restore-production-db.md](docs/restore-production-db.md). `RESTORE_ACK_STOPPED=YES` is operator acknowledgment only — not a service stop detector. ## Production smoke (local, temp DB) ```powershell npm run build npm run smoke:trial-production ```