Case study
One backend, four apps and a legacy ERP
Four apps and a dashboard on one backend.
750–1,000orders a day
SAR 177.89average basket
72backend modules
105data models
The problem
A grocery order touches four people within an hour.
Four apps, one order — the constraint was keeping one truth.
The shape of the system
One API, five clients, one state change.
Three decisions worth defending
1. The ERP is upstream, and it is not negotiable
Price and stock stay upstream in the ERP.
The flow is one-way, by design.
The gate that matters
Dangerous diffs wait for a human.
2. Realtime had to survive more than one process
Sockets break quietly across processes.
Clustered API, Redis fan-out between workers.
3. Modules drawn around the business, not the tables
Modules follow the operation, not the schema.
The test is where a new rule lands.
What runs it
| Layer | Choice | Why |
|---|---|---|
| API | NestJS Prisma |
Enforced boundaries, typed data access. |
| Database | PostgreSQL |
Transactions and constraints. |
| Realtime | Socket.IO Redis |
Events cross worker boundaries. |
| Calls | LiveKit |
In-app voice without leaving the flow. |
| Dashboard | Next.js Leaflet Recharts |
Maps and charts, all day. |
| Watching it | Sentry New Relic Pino |
Know before the customer calls. |
Where it stands
- 750–1,000 orders a day.
- Catalogue syncs itself, with a human gate.
- Managers read the same numbers from a phone.
- A live ERP migration, made survivable by that boundary.
What I would do differently
Infrastructure deserves its own dashboard on day one.