Prerequisites: Go 1.25, Node 22+, pnpm, PostgreSQL 16.
cd apps/api
cp .env.example .env # set DB_URL and JWT_SECRET
go mod download
go run ./cmd/serverOn first start the server migrates the schema and seeds the tenant, roles, permissions and the admin user.
To also load a demo project with engagements and findings:
cd apps/api && go run ./cmd/seed-dataIn a second terminal:
cd apps/web
cp .env.example .env.local # NEXT_PUBLIC_API_URL, default http://localhost:8080/api/v1
pnpm install
pnpm devPort conflicts.
apps/web/.env.exampleassumes the API is on:8080. If something else already holds that port, set bothPORTinapps/api/.envandNEXT_PUBLIC_API_URLinapps/web/.env.localto match.
# API
cd apps/api && go build ./... && go vet ./... && go test ./...
# Web
cd apps/web && pnpm lint && npx tsc --noEmit && pnpm testRun gofmt -l . in apps/api before committing; CI fails on unformatted files.
CI (.github/workflows/ci.yml) runs all of the above — go test against a real
Postgres service, and lint, typecheck, unit tests and a production build for the
web app.
Playwright specs live in apps/web/e2e and expect a running stack:
cd apps/web && pnpm test:e2e # or pnpm test:e2e:uicd apps/web
pnpm build
pnpm start:standalone # :3001 by default; PORT=3000 to overridenext.config.js sets output: "standalone", so the supported entrypoint is
.next/standalone/server.js with .next/static and public/ copied next to
it — serving the standalone server without them starts fine and returns 404s
for every asset. pnpm start:standalone does exactly that, matching what the
Dockerfile performs for the published image.
docker compose up --build # postgres + api + web from the repo root