- Read the current docs for the area you are changing, then inspect the code or tests that define the behavior.
- Keep file ownership and module boundaries explicit.
- Implement a small logical slice with happy-path and failure-path coverage.
- Run the narrowest useful checks first:
pnpm format:check,pnpm lint,pnpm typecheck,pnpm package:checkwhen package payloads change, and the smallest relevant test suite. - Stage only intended files, inspect
git diff --cached, and confirm that no credentials, tokens, dotenv files, or personal data are staged.
Use Conventional Commits with a focused scope, for example:
feat(seating): add atomic redis seat holds
test(bookings): cover duplicate payment callbacks
docs(architecture): document payment confirmation sequence
Do not mix unrelated domains, generated files, or drive-by formatting in the same commit.
Describe the behavior changed, the invariants protected, checks run, migration impact, and any follow-up work. A PR is not ready when tests are merely expected to pass; include fresh command output.
Use Docker Compose for PostgreSQL, Redis, Mailpit, API, and web. docker compose up --build is the full-stack smoke path; docker compose up -d postgres redis mailpit is the lighter host-development path. Never use production credentials
locally or commit a local .env file.
Pull requests must pass the same format, lint, typecheck, package payload,
Prisma migration, API test, web test, web build, audit, Compose validation,
and image-build checks defined in .github/workflows/pull-request.yml.
Text files are normalized and checked out as LF through .gitattributes, so
local formatting checks match Linux CI. A Windows checkout created before that
policy may still contain CRLF files after pulling the update. If
pnpm format:check reports widespread line-ending differences, keep any
uncommitted work and use a fresh clone or worktree at the current commit.