Architecture

System Overview

┌──────────────┐     ┌──────────────────┐     ┌──────────────────┐
│              │     │                  │     │  HAPI FHIR R4    │
│   Next.js    │────▶│  Spring Boot     │────▶│  (port 8092)     │
│  (frontend)  │     │  (port 8091)     │     │  Clinical data   │
│              │     │                  │     └──────────────────┘
└──────────────┘     │                  │     ┌──────────────────┐
                     │                  │────▶│  PostgreSQL 15   │
                     │                  │     │  (port 5433)     │
                     └──────────────────┘     │  Lookup tables   │
                                              └──────────────────┘

The frontend talks exclusively to the Spring Boot backend. The backend routes clinical data operations to the HAPI FHIR server and lookup/reference queries to Postgres.

Data Store Responsibilities

HAPI FHIR Server (Clinical Data)

All clinical records are stored as FHIR R4 resources:

Domain

FHIR Resource

Patients

Patient

Encounters

Encounter

Diagnoses

Condition

Procedures

Procedure

Notes

DocumentReference

PostgreSQL (Lookup & Mapping Data)

Table

Purpose

users

Physicians and staff

icd10_codes

ICD-10 diagnosis code catalog

cpt_codes

CPT procedure code catalog

fhir_id_mapping

Bridges frontend Long IDs ↔ FHIR UUIDs

Backend (Spring Boot + Kotlin)

Package Layout

  • com.ehr.controller — REST controllers

  • com.ehr.service — Business logic

  • com.ehr.fhir — FHIR resource mappers (FhirPatientMapper, FhirEncounterMapper, FhirNoteMapper)

  • com.ehr.model — JPA entities (User, Icd10Code, CptCode, FhirIdMapping)

  • com.ehr.repository — Spring Data JPA repositories

  • com.ehr.dto — Request/response DTOs

  • com.ehr.config — Configuration (FHIR client, CORS)

Key Dependencies

  • Spring Boot 3.5.0

  • Kotlin 1.9.25

  • HAPI FHIR 7.6.0 (base, client, structures-r4)

  • Spring Data JPA + PostgreSQL driver

Frontend (Next.js + TypeScript)

Pages (App Router)

Route

Purpose

/

Home / Dashboard

/patients/new

Create patient

/patients/[id]

Patient workspace

/patients/[id]/edit

Edit patient

/patients/[id]/encounters/new

Create encounter

/patients/[id]/encounters/[encounterId]

View encounter

/patients/[id]/encounters/[encounterId]/edit

Edit encounter

Key Components

  • AppShell — Main application container

  • TabBar — Multi-patient tab switcher with search dropdown

  • PatientWorkspace — Central workspace showing encounters and notes

  • PatientSidebar — Demographic details sidebar

  • CodeSearch — ICD-10 / CPT code lookup

  • LoginScreen — User selection / authentication

State Management (React Context)

  • AuthContext — Current user session; persists user ID to localStorage

  • TabContext — Open patient tabs; persists per-user to localStorage

Docker Compose Services

Service

Image

Host Port

Container Port

Database

postgres

postgres:15

5433

5432

ehr, hapi

hapi-fhir

hapiproject/hapi:v7.6.0

8092

8080

hapi

Both services share the same Postgres instance. An init script (init-hapi-db.sql) creates the hapi database for the FHIR server on first run.

The backend Spring Boot application runs outside Docker on port 8091.