A project management API for teams, projects and tasks, with a React client. TypeScript throughout: NestJS + Knex + MySQL on the server, React + TanStack Query on the client, in a pnpm workspace.
Everything runs in Docker. One command brings up the API, the web app and the infrastructure (MySQL, Redis, RabbitMQ), then runs migrations and seeds:
pnpm install
pnpm startThen open:
- Web app — http://localhost:5173
- API — http://localhost:3000 (health check:
curl http://localhost:3000/health)
Log in with alice@acmecorp.com / password123.
See GETTING_STARTED.md for the API reference and setup detail.
apps/
api/ NestJS API
src/
<feature>/ one module per feature — auth, tasks, projects,
*.controller.ts comments, teams, users, notifications, realtime
*.service.ts business rules; throws domain errors, never HTTP
*.repository.ts the only code that touches SQL
*.policy.ts authorization decisions — pure, no I/O
*.search.ts declarative query objects
dto/ request validation + response mappers
entities/ domain types and rules
common/ clock, errors, guards, filters, interceptors, db
migrations/ seeds/ test/
web/ React client
src/
features/ auth, projects, tasks, board, dashboard
shared/ api client, query keys, design system, hooks
app/ providers + routes
e2e/
packages/
contracts/ the HTTP contract shared by both apps — types only
Dependency direction is one way: controller → service → repository, with
entities and policies at the bottom holding no I/O. Only controllers and
common/http know about Express.
packages/contracts is the single source of truth for the wire format. It
exports types only, so every import of it is erased at compile time — nothing to
build, nothing to resolve at runtime. Change a response shape there and both
apps stop compiling until they agree.
Stack: pnpm workspaces · TypeScript 5 · NestJS 11 · Knex + MySQL 8 · class-validator · Jest · React 19 · TanStack Query · Vitest · Playwright · Docker Compose (MySQL, Redis, RabbitMQ)
Run from the repo root. Everything is a pnpm script.
pnpm check # typecheck + lint + all tests — run this before you're done
pnpm dev # API and web dev servers, outside Docker
pnpm test # unit and integration tests, both apps
pnpm test:e2e # Playwright, needs the stack running
pnpm start # bring the whole stack up in Docker and wait for health
pnpm stop # bring it down
pnpm restart
pnpm logs # or logs:api / logs:web
pnpm db:migrate # or db:rollback / db:seed / db:make / db:console
pnpm storybook
pnpm reset # nuke containers, volumes and node_modules, then start overScoping to one package works the usual way:
pnpm --filter @taskflow/api test
pnpm --filter @taskflow/web dev- GETTING_STARTED.md — setup, API endpoints, troubleshooting
- CLAUDE.md — conventions, and where a given kind of change belongs