Modular monolith
Architecture
One deployable, explicit modules, replaceable adapters. Realtime and the worker are the only processes you extract when traffic earns them.
backend/
schemas/entities.ts # Users, Vehicles, Trips, Locations, Payments
modules/{geo,dispatch,trips,fleet,payments,communications,trust,safety}/
shared/{authz,cache,events,idempotency,rate-limit,region,golive}/
realtime/socket-server.ts # Socket.io + Redis adapter
workers/index.ts # match tick + AMQP
app/api/v1/ # HTTP
prisma/ # Postgres + PostGISHTTP handlers do not contain business rules. They parse, authorize, rate-limit, then call a module. The investor demo calls those modules directly so a meeting cannot get stuck on cookies.
| Module | Owns | Extract when |
|---|---|---|
| geo | H3, presence, ETA | Ping volume needs its own process |
| dispatch | Hungarian + surge | Match latency SLO requires an isolated worker |
| trips | FSM | Keep with the API |
| payments | Ledger + Stripe | Audit/compliance team wants a hard boundary |
| fleet | Unlock, inspection, insurance quote | IoT vendor integration |
| golive | Mode, tax gates, backups, headers | Never extract — it is policy |