A real-time, multi-service Computer-Aided Dispatch system. Built as a learning rig for WebSocket fan-out, event sourcing, geospatial dispatch, RBAC, and AI triage — not a product. See the Notion CAD System page for the canonical product and architecture spec.
Need Node 22 LTS and pnpm 11. Quickest path:
npm install -g pnpm@11.5.1 # or `corepack enable` (see note below)
pnpm installWindows:
corepack enableoften fails withEPERM ... pnpxbecause it writes shims intoC:\Program Files\nodejs. Use thenpm install -g pnpmline above instead — pnpm honors the version pinned inpackage.json. Full per-OS setup, including the Volta/WSL options, is indocs/development.md.
Two interchangeable dev modes — both hot-reload:
# A. Local: services on host, deps in Docker
pnpm dev:deps # Postgres + PostGIS, Redis, NATS, Jaeger
pnpm dev # all services + apps via Turborepo (watch)
# B. Docker: everything in containers, source synced from host
pnpm dev:docker # docker compose watch — great on WindowsJaeger UI at http://localhost:16686. Full comparison and the
production-like pnpm stack are in docs/development.md.
Want to actually use it? docs/playing.md is a
hands-on walkthrough: boot the stack, pnpm seed some incidents, open the
operator console at http://localhost:3000/?operator=alex&tier=fire&name=Alex,
and drive an incident through its lifecycle while a second window updates live.
pnpm typecheck
pnpm lint
pnpm test
pnpm smoke # gRPC health-check sweep across services- docs/development.md — full dev setup for Windows, macOS, and Linux; the inner loop, generators, and troubleshooting.
- docs/deployment.md — running the whole stack on a Linux host with Docker (the production-like target).
Not yet hardened. This is an exploration project; nothing is deployed publicly.
Phase 6 introduces Kubernetes overlays under infra/k8s/. Until then,
docker compose -f infra/docker-compose.yml up -d --build on a Linux host is
the production target — see docs/deployment.md.
apps/ React + Vite + vanilla-extract operator consoles
services/ Node + Fastify + gRPC microservices (Python exception: triage)
packages/ Shared TS libraries (ui, proto, events, observability, db, config)
infra/ Docker Compose for local; K8s + Terraform later
tools/ Generators (Plop) and scripts (smoke, codegen)
docs/ ADRs and PRD stubs (canonical PRDs are in Notion)
.claude/ Skills and settings for Claude Code sessions
pnpm new-app <app.name> # React + Vite app
pnpm new-lib <lib.name> # Shared TS package
pnpm new-service <service.name> # Node + Fastify + gRPC serviceSee .claude/skills/new-* for the full step-by-step.
Per-service PRDs live in Notion as sub-pages of the CAD System page. The
repo-side stubs at docs/prd/<service>.md link to them.
| Service | One-liner | Port | Code | PRD |
|---|---|---|---|---|
| gateway | BFF + WebSocket terminator + RBAC enforcement at the edge. | 5000 | services/service.gateway | docs/prd/gateway.md |
| auth | Login, JWT issuing, CASL ability synthesis. | 5010 | services/service.auth | docs/prd/auth.md |
| incident | Incident aggregate (event-sourced state machine). | 5020 | services/service.incident | docs/prd/incident.md |
| dispatch | Stateless unit-allocation recommender. | 5030 | services/service.dispatch | docs/prd/dispatch.md |
| resource | Unit roster, status, last-known location. | 5040 | services/service.resource | docs/prd/resource.md |
| geo | Geocoding, nearest-K, route ETA over PostGIS. | 5050 | services/service.geo | docs/prd/geo.md |
| notification | NATS → Redis fan-out spine for WebSockets. | 5065 | services/service.notification | docs/prd/notification.md |
| audit | Append-only audit log consumer. | 5070 | services/service.audit | docs/prd/audit.md |
| triage | AI severity classification via local Ollama (Python). | 5080 | services/triage | docs/prd/triage.md |
- Trunk-based development; short-lived branches off
main. - Conventional Commits. The Husky hook blocks non-conforming messages.
- TypeScript strict everywhere. No
anyoutside test fixtures. Python is permitted only insideservices/triageand the reason is documented inCLAUDE.md. - Styling: vanilla-extract
vars.*tokens only. No hex literals in*.css.ts.
See CLAUDE.md for the full stack, behavioral directives, and per-area skill
references for Claude Code sessions.