Production-ready monorepo skeleton for a Catan-like web game with an authoritative backend and a pure, deterministic rules engine.
- Node.js 20+
- pnpm 8+
- Python 3.11+
- Docker (optional, for infra services)
pnpm devThis runs:
apps/web(Next.js) on port 3000apps/api(NestJS + Socket.IO) on port 3001apps/rules-service(Node) on port 4001apps/ai(FastAPI) on port 8001
Optional infra services:
docker compose -f infra/docker-compose.yml up -d +----------------------+
| Next.js Web |
| /apps/web (client) |
+----------+-----------+
|
| Socket.IO
v
+----------------------+ +-----+----------------+
| Rules Service | | NestJS API |
| /apps/rules-service |<--->| /apps/api (author.) |
+----------+-----------+ +----------+----------+
| |
| direct import | uses rules for validation
v v
+----------------------+ +----------------------+
| Rules Engine | | Shared Schemas |
| /packages/rules |<--->| /packages/shared |
+----------------------+ +----------------------+
^
|
+----------+-----------+
| FastAPI AI Service |
| /apps/ai |
+----------------------+
- The single source of truth for state and move schemas lives in
packages/shared(Zod). - The deterministic, pure rules logic is implemented in
packages/rulesand imports those schemas. - The backend (
apps/api) validates all moves server-side throughapplyMove. - The frontend may import rules for previews only (non-authoritative).
The AI service calls the Node rules service to verify legality and apply moves:
POST /legal-movesfor candidate movesPOST /apply-moveto advance game state
Configure the target URL with RULES_SERVICE_URL (defaults to http://localhost:4001).
pnpm dev- run all servicespnpm build- build all packages/appspnpm lint- lint TypeScript (and Python if ruff is installed)pnpm test- placeholder tests