medOS ultra

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

  1. Never write directly to Supabase read-model tables from the frontend — go through the backend API.
  2. Market-pack parity — application code must be identical across regions; only seeds, locale, and insurance-rate tables differ.
  3. Bilingual seed data — local language + English for every seed.
  4. All env vars in Docker Compose must be parameterized (no hardcoded URLs).
  5. Use FHIR for external exchange; use HL7v2 for legacy integration with instruments and ADT feeds.

See also

Ask Anything