rivheal-docs

RivHeal System Architecture

Last updated: 2026-05-30


High-Level Architecture

graph TB
    subgraph Users["Users"]
        PA[Patient — Mobile App]
        CA[Clinical Staff — Web Dashboard]
        HA[Hospital Admin — Web Dashboard]
        GU[Guest — No Login]
    end

    subgraph Edge["Edge / Reverse Proxy"]
        TR[Traefik v3.2<br/>TLS · Rate Limiting · VPN Gate]
    end

    subgraph Backend["Backend Services"]
        API[NestJS API<br/>api.rivheal.com<br/>:8000]
        ML[FastAPI ML Service<br/>ml-service:8000<br/>wait-time · no-show]
        RASA[Rasa NLU 3.6<br/>rasa:5005<br/>health chatbot]
    end

    subgraph Auth["Authentication"]
        KC[Keycloak 26<br/>auth.rivheal.com<br/>SSO · OIDC · JWT]
    end

    subgraph Data["Data Stores"]
        PG[(PostgreSQL 16<br/>Primary store)]
        MG[(MongoDB 7<br/>Documents / audit)]
        RD[(Redis 7<br/>Cache · Bull queues)]
    end

    subgraph AI["AI Pipeline"]
        ANT[Claude API<br/>Haiku 4.5<br/>Symptom triage LLM]
        SKL[scikit-learn Models<br/>wait_time_model.pkl<br/>no_show_model.pkl]
    end

    subgraph External["External Integrations"]
        PS[Paystack / Flutterwave<br/>Payments]
        TM[Termii<br/>SMS OTP]
        GM[Google Maps API<br/>Hospital geo-search]
        CD[Cloudinary<br/>Image storage]
        EX[Expo Push<br/>Notifications]
    end

    PA -->|HTTPS| TR
    CA -->|HTTPS| TR
    HA -->|HTTPS| TR
    GU -->|HTTPS| TR

    TR -->|route| API
    TR -->|route| KC

    API -->|JWT validate| KC
    API -->|SQL| PG
    API -->|documents| MG
    API -->|queue / cache| RD
    API -->|POST /predict/*| ML
    API -->|POST /webhooks/rest| RASA
    API -->|Claude API| ANT
    API -->|payments| PS
    API -->|SMS| TM
    API -->|maps| GM
    API -->|files| CD
    API -->|push| EX

    ML --> SKL

    style Users fill:#dbeafe,stroke:#3b82f6
    style Backend fill:#dcfce7,stroke:#16a34a
    style Auth fill:#fef3c7,stroke:#d97706
    style Data fill:#f3e8ff,stroke:#9333ea
    style AI fill:#fce7f3,stroke:#db2777
    style Edge fill:#f1f5f9,stroke:#64748b
    style External fill:#fff7ed,stroke:#ea580c

Component Descriptions

NestJS API (rivheal-api)

React Admin Dashboard (rivheal-frontend)

Expo Mobile App (rivheal-mobile-app)

FastAPI ML Service (rivheal-ml-service)

Rasa Bot (rasa-bot)

Keycloak (auth.rivheal.com)

Traefik (rivheal-infra)


Feature Flags — AI/ML Toggle

All AI features are controlled by two-level feature flags:

Global Flag

ENABLE_AI_FEATURES=true   # set in .env / docker-compose

When false, all /predict/*, /patients/:id/health-score, and Claude LLM calls return fallback values or 403.

Per-Tenant Flag

Column hospitals.ai_features_enabled (boolean, default false).

The FeatureFlagsService (global NestJS module) checks both:

const enabled = await featureFlagsService.isAiEnabled(hospitalId);
// false if ENABLE_AI_FEATURES=false OR hospital.ai_features_enabled=false

Enable per hospital via the admin API or direct DB update:

UPDATE hospitals SET ai_features_enabled = true WHERE id = '<hospital-uuid>';

Data Flow — Appointment Booking

See flows/appointment-booking.md for the full sequence diagram.

Data Flow — AI Triage

See flows/symptom-checker-llm.md.