1 Development and Testing
Emily edited this page 2026-11-04 23:26:39 +01:00

Development and Testing

Requirements

  • Node.js 20+ (the Docker image uses Node 22).
  • npm.
  • Docker and Docker Compose for PostgreSQL, or SQLite for a quick local run.
  • python3, make and g++ only if better-sqlite3 needs to build from source.

Local setup

git clone https://git.emilyh.de/Emily/UniversalGamingApp-Backend.git
cd UniversalGamingApp-Backend
npm ci
cp .env.example .env

For a quick SQLite run, set a development secret and leave PostgreSQL variables empty:

NODE_ENV=development
JWT_SECRET=development-only-secret-at-least-32-characters
DATABASE_PATH=./data/accounts.db
CORS_ORIGINS=*
REQUEST_LOGGING=true
npm run dev
curl http://127.0.0.1:6767/healthz

For PostgreSQL, use Compose:

docker compose up -d db
# Point POSTGRES_* at 127.0.0.1:5432 for a host-run Node process.
npm run dev

Or run the full stack:

docker compose up -d --build

Scripts

Command Purpose
npm start Run the server
npm run dev Run with Node's watch mode
npm test Run the full test suite
node src/migrate.js Apply PostgreSQL migrations and exit

Test suite

npm test
npm audit --omit=dev

At release 1.4.0:

  • 45 tests pass.
  • npm audit --omit=dev reports 0 vulnerabilities.

The tests use an in-memory SQLite database and do not need PostgreSQL, SMTP or network access. HTTP calls to the release feed are mocked.

Test files

File Focus
test/accounts.test.js Registration, login, profile, leaderboard, chess, releases, CORS, management
test/config.test.js Defaults, SMTP TLS inference, URL validation, proxy parsing, database URL encoding
test/mailer.test.js Port 465 vs STARTTLS ports, auto-correction, transport options
test/migrations.test.js Migration ordering, baseline schema, reset/session migration
test/password_reset.test.js Confirmed-address requirement, anti-enumeration, reset flow, missing SMTP
test/passwords.test.js Full-length passwords beyond 72 bytes, legacy hash upgrade
test/request_logging.test.js Client IP logging and query-string stripping

Run one file:

node --test test/password_reset.test.js

Adding an endpoint

  1. Add validation helpers near the top of src/app.js.
  2. Add the route inside createApp().
  3. Use auth for protected routes.
  4. Use asyncHandler and throw HttpError for expected failures.
  5. Add database methods to both the PostgreSQL and SQLite implementations in src/db.js.
  6. Add a test to test/accounts.test.js or a focused file.
  7. Document the endpoint in API Reference.
  8. Bump the version and update the changelog.

Adding a migration

  1. Append the next integer version to POSTGRES_MIGRATIONS in src/migrations.js.
  2. Keep statements idempotent.
  3. Never edit an already released migration.
  4. Add a test in test/migrations.test.js.
  5. Run against a disposable PostgreSQL database.
  6. Deploy with ./update.sh, which takes a pre-update backup.

Configuration changes

src/config.js merges defaults with the environment and validates:

  • JWT_SECRET length.
  • PUBLIC_BASE_URL and APP_PUBLIC_URL schemes.
  • TRUSTED_PROXIES entries.
  • SMTP TLS mode.
  • Numeric ranges for TTLs, bcrypt rounds, ports and cache time.

Invalid configuration exits at startup with a clear message. Add a test in test/config.test.js for every new variable.

Versioning

Update the version in:

  • package.json
  • src/config.js (version)
  • src/app.js (User-Agent)
  • docker-compose.yml default image tag
  • README.md
  • update.sh if it references a version
  • .env.example if it references an image tag

Then commit and tag:

git tag v1.4.0
git push origin main --tags

Release process

  1. npm test
  2. npm audit --omit=dev
  3. Build the image.
  4. Push X.Y.Z and latest to the Gitea registry.
  5. Create a Gitea release with notes.
  6. Deploy with ./update.sh.
  7. Verify /healthz, /api/v1/meta, a login and a leaderboard read.
  8. Confirm migrations and data are intact.
  9. Copy a post-update dump off-host.
docker build -t git.emilyh.de/emily/universal-gaming-backend:1.4.0 .
docker tag git.emilyh.de/emily/universal-gaming-backend:1.4.0 \
  git.emilyh.de/emily/universal-gaming-backend:latest
docker push git.emilyh.de/emily/universal-gaming-backend:1.4.0
docker push git.emilyh.de/emily/universal-gaming-backend:latest

CI

The repository may include a Forgejo/Gitea workflow. Jobs remain queued if the instance has no registered Actions runner. Until a runner is available, run the test suite locally and publish images manually.

Code style

  • ES modules, Node 20+.
  • Async/await throughout.
  • Throw HttpError(status, message) for expected client errors.
  • Do not log secrets, bodies, tokens or e-mail addresses.
  • Keep database access behind src/db.js.
  • Keep chess validation in src/chess.js and leaderboard validation in src/leaderboard.js.