Getting started
From a clean checkout to a running stack.
docs/GETTING_STARTED.md
From a clean checkout to a running stack.
Prerequisites
| Need | Why |
|---|---|
| Node 22+ | Both apps target it; the API bundle is built for node22 |
| Docker | Postgres, RabbitMQ and MinIO run as containers |
| npm 10+ | This is an npm-workspaces monorepo — not pnpm or bun |
First run
cp .env.example .env # then set JWT_SECRET and ENCRYPTION_KEY
npm install
docker compose up -d # postgres · rabbitmq · minio
npm run db:push # create the schema
npm run seed # optional: demo data
npm run dev:api # terminal 1 → :4000
npm run dev # terminal 2 → :3000
Two commands because there are two deployables. That is the point of the split — see Architecture.
What runs where
| Port | Notes | |
|---|---|---|
| Web | 3000 | Landing, /docs, /dashboard, and the authenticated app |
| API | 4000 | The only process with database credentials |
| Postgres | 5433 | Offset so it never collides with another local stack |
| RabbitMQ | 5673 | Management UI on 15673 (app / app) |
| MinIO | 9100 | Console on 9101 |
Check it came up:
curl -s localhost:4000/api/v1/health
# {"status":"ok","db":"up","queue":"up"}
A degraded here is informative, not fatal: the API keeps serving reads and most writes without
the broker. db: down is the one that takes the service out of rotation.
Two secrets with no default
JWT_SECRET and ENCRYPTION_KEY deliberately have no fallback value. A default would mean
production secrets signed and encrypted with a key that lives in the source tree — so the API
refuses to handle secrets without one rather than quietly using a known key.
openssl rand -base64 32 # run twice
The gate
npm run verify # typecheck → lint → test → build
npm run test:e2e # Playwright, needs the web dev server free on :3100
npm test needs Postgres. The queue's integration cases need RabbitMQ, and say so loudly and
skip rather than passing vacuously if it is not up.
Common first problems
| Symptom | Cause |
|---|---|
The table public.users does not exist | Schema not pushed to this volume. npm run db:push. |
queue: down right after boot | The API connects to the broker at startup; if it was not up yet, restart the API. |
Another next dev server is already running | A previous dev server survived. pkill -f "next dev". |
| 401 loops in the browser | A token from a previous database. Clear localStorage and sign in again. |