Skip to main content
Version: v0.1.0

System Architecture

This document provides a comprehensive overview of the Ciyex EHR system architecture, including all components, their interactions, and deployment patterns.

High-Level Architecture​

graph TB
subgraph "Client Layer"
WEB[Web Browser]
MOBILE[Mobile App<br/>Future]
end

subgraph "Load Balancing & Ingress"
LB[Load Balancer<br/>NGINX Ingress]
SSL[SSL/TLS<br/>Cert-Manager]
end

subgraph "Application Layer"
UI1[Next.js UI<br/>Instance 1]
UI2[Next.js UI<br/>Instance 2]
API1[Spring Boot API<br/>Instance 1]
API2[Spring Boot API<br/>Instance 2]
FHIR1[HAPI FHIR<br/>Instance 1]
FHIR2[HAPI FHIR<br/>Instance 2]
end

subgraph "Authentication & Authorization"
KC[Keycloak<br/>Aran ID]
end

subgraph "Data Layer"
PG[(PostgreSQL<br/>Primary)]
PG_REPLICA[(PostgreSQL<br/>Replica)]
end

subgraph "Storage & Cache"
S3[AWS S3<br/>Documents]
CACHE[Redis<br/>Cache]
end

subgraph "External Services"
STRIPE[Stripe<br/>Payments]
JITSI[Jitsi<br/>Video]
SMTP[SMTP<br/>Email]
SMS[Twilio/Telnyx<br/>SMS]
AI[Azure OpenAI<br/>AI Features]
end

subgraph "Monitoring & Logging"
PROM[Prometheus<br/>Metrics]
GRAF[Grafana<br/>Dashboards]
LOKI[Loki<br/>Logs]
end

subgraph "Backup & DR"
VELERO[Velero<br/>K8s Backup]
LONGHORN[Longhorn<br/>Storage]
end

WEB --> LB
MOBILE -.-> LB
LB --> SSL
SSL --> UI1
SSL --> UI2
UI1 --> API1
UI2 --> API2
UI1 --> FHIR1
UI2 --> FHIR2
API1 --> KC
API2 --> KC
FHIR1 --> KC
FHIR2 --> KC
API1 --> PG
API2 --> PG
FHIR1 --> PG
FHIR2 --> PG
PG --> PG_REPLICA
API1 --> S3
API2 --> S3
API1 --> CACHE
API2 --> CACHE
API1 --> STRIPE
API1 --> JITSI
API1 --> SMTP
API1 --> SMS
API1 --> AI
PROM --> API1
PROM --> API2
PROM --> FHIR1
GRAF --> PROM
LOKI --> UI1
LOKI --> API1
VELERO --> LONGHORN

Component Overview​

Frontend Layer​

Next.js UI Application​

  • Technology: Next.js 16, React 18, Tailwind CSS 4.0
  • Features:
    • Server-side rendering (SSR) for better SEO
    • Static site generation (SSG) for performance
    • API routes for backend proxy
    • Responsive design for all devices
  • Key Components:
    • Patient management interface
    • Appointment scheduler
    • Clinical documentation forms
    • Telehealth video interface
    • Billing and payments UI

Backend Layer​

Spring Boot API​

  • Technology: Spring Boot 4.0, Java 21
  • Architecture Pattern: Layered architecture
    • Controllers: REST endpoints
    • Services: Business logic
    • Repositories: Data access
    • Entities: Domain models
  • Key Features:
    • RESTful API
    • OAuth2 resource server
    • Multi-schema support
    • Audit logging
    • File upload/download
    • Payment processing
    • Email/SMS notifications

HAPI FHIR Server​

  • Technology: HAPI FHIR 8.2.1 (R4)
  • Features:
    • Full FHIR R4 compliance
    • Multi-tenant partitioning
    • Custom interceptors
    • SMART on FHIR support
  • Resources Supported:
    • Patient, Practitioner, Organization
    • Encounter, Observation, Condition
    • MedicationRequest, AllergyIntolerance
    • Appointment, Schedule
    • And more...

Authentication & Authorization​

Keycloak (Aran ID)​

  • Features:
    • OAuth2/OIDC provider
    • Single Sign-On (SSO)
    • User federation
    • Group-based access control
    • Multi-factor authentication
  • Integration:
    • JWT token validation
    • Role and group mapping
    • Custom claims support

Data Layer​

PostgreSQL Database​

  • Version: PostgreSQL 15+
  • Architecture: Multi-schema
    • public schema: Shared configuration
    • practice_1, practice_2, etc.: Practice-specific data
  • Features:
    • ACID compliance
    • Row-level security
    • Full-text search
    • JSON/JSONB support
  • Backup Strategy:
    • Continuous WAL archiving
    • Daily full backups
    • Point-in-time recovery

Redis Cache​

  • Purpose: Session management, caching
  • Use Cases:
    • API response caching
    • Rate limiting
    • Real-time features

Storage​

AWS S3​

  • Purpose: Document storage
  • Stored Items:
    • Patient documents
    • Medical images
    • Lab reports
    • Message attachments
    • Backup archives

Longhorn​

  • Purpose: Persistent volumes for Kubernetes
  • Features:
    • Distributed block storage
    • Snapshot and backup
    • Disaster recovery
    • Volume replication

Deployment Architecture​

graph TB
subgraph "Practice 1 Deployment"
UI1[Next.js UI<br/>practice1.example.com]
API1[Spring Boot API<br/>api-practice1.example.com]
FHIR1[HAPI FHIR<br/>fhir-practice1.example.com]
end

subgraph "Practice 2 Deployment"
UI2[Next.js UI<br/>practice2.example.com]
API2[Spring Boot API<br/>api-practice2.example.com]
FHIR2[HAPI FHIR<br/>fhir-practice2.example.com]
end

subgraph "Shared Services"
KC[Keycloak]
PG[(PostgreSQL)]
S3[AWS S3]
end

UI1 --> API1
UI1 --> FHIR1
UI2 --> API2
UI2 --> FHIR2
API1 --> KC
API2 --> KC
API1 --> PG
API2 --> PG
FHIR1 --> PG
FHIR2 --> PG
API1 --> S3
API2 --> S3

style UI1 fill:#e1f5ff
style API1 fill:#e1f5ff
style FHIR1 fill:#e1f5ff
style UI2 fill:#fff3e0
style API2 fill:#fff3e0
style FHIR2 fill:#fff3e0

Benefits:

  • Complete process isolation
  • Independent scaling per practice
  • Simpler troubleshooting
  • Better security and compliance
  • No tenant header required

Multi-Tenant (Legacy)​

graph TB
subgraph "Shared Deployment"
UI[Next.js UI<br/>app.example.com]
API[Spring Boot API<br/>api.example.com]
FHIR[HAPI FHIR<br/>fhir.example.com]
end

subgraph "Shared Services"
KC[Keycloak]
PG[(PostgreSQL)]
end

UI -->|X-Tenant-Name: practice1| API
UI -->|X-Tenant-Name: practice2| API
API --> KC
API -->|SET search_path| PG
FHIR --> PG

Drawbacks:

  • Shared resources and memory
  • Complex tenant resolution
  • Header-based routing risk
  • Harder to troubleshoot

See Deployment Models for detailed comparison.

Data Flow​

Patient Creation Flow​

sequenceDiagram
participant UI as Next.js UI
participant API as Spring Boot API
participant KC as Keycloak
participant DB as PostgreSQL
participant FHIR as HAPI FHIR

UI->>KC: Login (username/password)
KC->>UI: JWT Token

UI->>API: POST /api/patients (JWT)
API->>KC: Validate JWT
KC->>API: Token Valid + Claims
API->>DB: INSERT INTO practice_1.patients
DB->>API: Patient Created
API->>FHIR: POST /fhir/Patient
FHIR->>DB: Store FHIR Resource
DB->>FHIR: Success
FHIR->>API: FHIR Patient ID
API->>UI: Patient Created Response

Appointment Scheduling Flow​

sequenceDiagram
participant UI as Next.js UI
participant API as Spring Boot API
participant DB as PostgreSQL
participant EMAIL as SMTP Service
participant SMS as Twilio/Telnyx

UI->>API: POST /api/appointments
API->>DB: Check provider availability
DB->>API: Available slots
API->>DB: INSERT appointment
DB->>API: Appointment created
API->>EMAIL: Send confirmation email
API->>SMS: Send SMS reminder
API->>UI: Appointment confirmed

Security Architecture​

Authentication Flow​

sequenceDiagram
participant User
participant UI as Next.js UI
participant KC as Keycloak
participant API as Spring Boot API

User->>UI: Enter credentials
UI->>KC: POST /realms/master/protocol/openid-connect/token
KC->>KC: Validate credentials
KC->>UI: Access Token + Refresh Token
UI->>UI: Store tokens in localStorage
UI->>API: API Request (Bearer Token)
API->>KC: Validate token (JWK)
KC->>API: Token valid + user info
API->>API: Check permissions
API->>UI: Response

Authorization Layers​

  1. Network Layer: Kubernetes NetworkPolicies
  2. Ingress Layer: NGINX authentication
  3. Application Layer: Spring Security
  4. Data Layer: PostgreSQL row-level security

Monitoring & Observability​

Metrics Collection​

graph LR
APP[Applications] -->|Metrics| PROM[Prometheus]
PROM -->|Query| GRAF[Grafana]
PROM -->|Alerts| AM[Alertmanager]
AM -->|Notifications| TEAMS[MS Teams]
AM -->|Notifications| EMAIL[Email]

Metrics Collected:

  • HTTP request rates and latencies
  • Database connection pool stats
  • JVM memory and GC metrics
  • Custom business metrics

Logging Architecture​

graph LR
APP[Applications] -->|Logs| LOKI[Loki]
LOKI -->|Query| GRAF[Grafana]
APP -->|Structured Logs| JSON[JSON Format]

Log Levels:

  • ERROR: Application errors
  • WARN: Warning conditions
  • INFO: General information
  • DEBUG: Detailed debugging (dev only)

Scalability​

Horizontal Scaling​

  • Frontend: Scale UI pods based on CPU/memory
  • Backend: Scale API pods based on request rate
  • FHIR: Scale FHIR pods based on FHIR API usage
  • Database: Read replicas for read-heavy workloads

Vertical Scaling​

  • Increase pod resource limits
  • Upgrade database instance size
  • Optimize JVM heap settings

Disaster Recovery​

Backup Strategy​

  1. Database Backups:

    • Continuous WAL archiving to S3
    • Daily full backups
    • 30-day retention
  2. Kubernetes Backups:

    • Velero daily backups
    • Includes all resources and PVCs
    • 7-day retention
  3. Document Backups:

    • S3 versioning enabled
    • Cross-region replication

Recovery Procedures​

  • RTO (Recovery Time Objective): 4 hours
  • RPO (Recovery Point Objective): 1 hour

See Backup Strategies for detailed procedures.

Performance Considerations​

Database Optimization​

  • Connection pooling (HikariCP)
  • Query optimization and indexing
  • Partitioning for large tables
  • Read replicas for reporting

Caching Strategy​

  • Redis for session data
  • Application-level caching (Caffeine)
  • HTTP caching headers
  • CDN for static assets

API Performance​

  • Async processing for long operations
  • Pagination for large result sets
  • Compression (gzip)
  • Rate limiting

Next Steps​