Architecture Overview
High-level tour of the two-world monorepo: NestJS/Moleculer backend + React/Vite clinic UI.
2 min read diagramsUpdated 2026-04-15docs-site/docs/architecture/overview.md
Architecture at a glance
flowchart LR
subgraph FE["Frontend · web/"]
UI["React 19 + Vite<br/>92+ miniapps"]
end
subgraph BE["Backend · services/"]
GW["API Gateway :3001"]
NATS(["NATS service mesh"])
SVC["16 Moleculer services<br/>clinical · financial · diagnostic · …"]
MONGO[("MongoDB<br/>system of record")]
end
subgraph RM["Read model · Supabase"]
EDGE["Edge Functions (Deno)"]
PG[("Postgres<br/>read cache")]
end
UI -->|REST via ALB / nginx| GW
GW --> NATS --> SVC --> MONGO
SVC -->|domain events| EDGE --> PG
PG -->|realtime subscription| UI
medOS-ultra is structured as a microservice backend behind an API gateway, a React 19 SPA in the browser, and a Supabase projection layer that acts as the read-model cache for the frontend.
Request flow
Frontend (React 19 / Vite)
│ REST / HTTPS
▼
ALB or nginx
│
▼
API Gateway (Moleculer-web, :3001)
│ JWT validation, routing
▼
NATS message bus
│ request / reply + pub/sub
▼
Microservices (NestJS + Moleculer)
│
├─▶ MongoDB (primary write store)
├─▶ PostgreSQL (E-Form service only)
├─▶ Supabase edge functions (projection)
│ └─▶ Supabase read model tables
│ └─▶ Frontend (realtime subscription)
├─▶ IPFS / S3 (filestore)
└─▶ External systems (FHIR / HL7 / SMART)
Routes every request by service scope. Handles JWT verification and
Moleculer action invocation.
JWT + Keycloak optional. Role-based access with RBAC cached at the
gateway.
Request / reply + fan-out events. Every microservice is a Moleculer node.
Primary store for clinical, admin, medication, financial records.
Read-model tables + edge functions for realtime subscriptions.
The filestore service supports both backends transparently.
Key architectural rules
- Never write directly to Supabase read-model tables from the frontend — go through the backend API.
- Market-pack parity — application code must be identical across regions; only seeds, locale, and insurance-rate tables differ.
- Bilingual seed data — local language + English for every seed.
- All env vars in Docker Compose must be parameterized (no hardcoded URLs).
- Use FHIR for external exchange; use HL7v2 for legacy integration with instruments and ADT feeds.
See also
- System topology — detailed diagram with ports
- Data flow — write path, read path, and projection
- Backend services
- Frontend overview