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

Monafiss platform architecture A legacy SQL Server ERP feeds a validating sync service, which writes to PostgreSQL. A NestJS API reads that database and serves four Flutter apps and a Next.js dashboard over REST and WebSockets, with Redis carrying socket events between API instances. Legacy ERP SQL Server · on-prem LAN Sync service Next.js · validates holds risky diffs pull PostgreSQL 105 Prisma models NestJS API 72 modules clustered, all cores 16 scheduled jobs Redis socket fan-out · cache Customer app Flutter Driver app Flutter Picker app Flutter Manager app Flutter · Roeya Ops dashboard Next.js REST + WebSocket
The ERP stays the source of truth.

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
APINestJS Prisma Enforced boundaries, typed data access.
DatabasePostgreSQL Transactions and constraints.
RealtimeSocket.IO Redis Events cross worker boundaries.
CallsLiveKit In-app voice without leaving the flow.
DashboardNext.js Leaflet Recharts Maps and charts, all day.
Watching itSentry New Relic Pino Know before the customer calls.

Where it stands

What I would do differently

Infrastructure deserves its own dashboard on day one.