01 / Problem
A monitoring view is only useful when its data retains context.
Measurements cannot be treated as isolated numbers. A clinical application needs to preserve which patient, encounter, code, unit, time and source are associated with a value—while keeping access to the underlying data controlled.
- Structured measurements over time
- Patient and encounter context
- Interoperable boundaries rather than an export-only model
02 / Architecture
FHIR sits inside the system, not at the edge of it.
The implemented stack treats FHIR as the active contract between the React clinical UI, FastAPI BFF/API, internal HAPI FHIR server and PostgreSQL. The browser never becomes an uncontrolled integration client.
- 01React / TypeScriptClinical frontend presentation
- 02Same-origin gatewayNginx serves UI, /api and /auth
- 03FastAPI BFF / APIValidated clinical contractsimplemented
- 04Keycloak + RedisOIDC, encrypted server sessionimplemented
- 05FHIR integrationControlled REST access and mapping
- 06HAPI FHIR R4Internal clinical resource serverimplemented
- 07PostgreSQLHAPI persistence layerimplemented
03 / Data flow
A traceable route from measurements to a monitoring view.
Server-side mapped FHIR Observations provide the structured basis for patient trends and clinician-facing details. The optional ML simulation is disabled by default and explicitly marked synthetic, preliminary and not clinically validated.
- 01FHIR Observations
- 02Validated API / query boundary
- 03FHIR mapper
- 04Time series
- 05Clinical monitoring view
Monitoring can show a trend. It does not replace clinical assessment or make a recommendation.
04 / Clinical data model
Identity and encounter anchor each observation.
Stable cross-system identity starts with an identifier system and identifier value, not a name-and-date-of-birth match. Encounter context makes it possible to understand where a measurement belongs in a course of care.
Patient.identifier system + value → Patient → Encounter → Observation
- Heart rate
- LOINC 8867-4
- Blood pressure panel
- LOINC 85354-9
- Systolic / diastolic
- 8480-6 / 8462-4
- Body temperature
- LOINC 8310-5
The code, subject and encounter reference describe what was measured and in which care context. Units and values must satisfy the profile and data-quality rules of the receiving system.
{
"resourceType": "Observation",
"status": "final",
"code": {
"coding": [{ "system": "http://loinc.org", "code": "8867-4" }]
},
"subject": { "reference": "Patient/synthetic-1042" },
"encounter": { "reference": "Encounter/synthetic-enc-37" }
}05 / Interoperability
Clinical monitoring needs relationships, not a resource catalogue.
The relevant resource set follows the product’s clinical scope. Observations drive measurement views; Patient and Encounter establish identity and context; documentation and planning resources become relevant only when a workflow calls for them.
Patient
Carries stable identity through identifier system + identifier value.
Encounter
Connects observations to the episode or context of care.
Observation
Represents coded measurements, units, timing and references.
Composition
A possible structured-document concept for nursing documentation.
CarePlan / RiskAssessment
Future workflow concepts; not presented as an implemented recommendation engine.
FHIR / terminologyLOINC codes are shown for common vital signs. SNOMED CT and UCUM remain terminology concerns that need approved value sets, profile rules and governance in a real implementation.
06 / Security
Trust boundaries make integrations controllable.
The implementation keeps HAPI FHIR and both databases on internal Docker networks. The BFF holds encrypted server-side OAuth sessions; the backend validates signature, issuer, audience, authorized client, token type and roles before clinical access.
Browser
Uses same-origin /auth and /api; it does not receive OAuth tokens or unrestricted FHIR credentials.
Identity provider
Keycloak provides OIDC Authorization Code + PKCE with state, nonce and CSRF-bound sessions.
Backend
Validates requests and enforces least privilege: pflege_read, pflege_write, pflege_delete and pflege_admin.
FHIR server
Receives constrained requests from the API and is not published on a host port.
The repository documents implemented controls; external penetration testing and clinical approval remain outside the demonstrated scope.
07 / Engineering decisions
Key engineering decisions
- 01
FHIR as a system contract
FHIR is the active integration path, not a final export format.
- 02
Narrow clinical write contracts
The backend maps measurement type, code and units server-side so a browser cannot replace terminology with arbitrary payloads.
- 03
Least privilege at the backend
Keycloak roles and patient-area checks are enforced before controlled FHIR access.
- Selecting profiles and query patterns that retain clinical meaning without over-fetching data.
- Showing late, missing or conflicting measurements without silently hiding data-quality problems.
- Distinguishing a technical trend view from clinical guidance in both UX and product governance.
08 / State & direction
Current state
IMPLEMENTED DEMONSTRATIONThe repository implements React/Vite, FastAPI, HAPI FHIR R4, PostgreSQL, Keycloak, Redis-backed encrypted BFF sessions, a versioned interop gateway, patient/Encounter admission, controlled clinical writes, trend views and synthetic demo seeding.
FUTURE DIRECTION
Future direction
Remaining work includes profile and terminology governance, production TLS/Keycloak mode, explicit no-store coverage for clinical GET responses, external security review and clinical validation. The synthetic ML mode remains deliberately non-clinical.
09 / What this demonstrates
What this project demonstrates
- 01Full-stack boundary design for clinical systems
- 02FHIR R4 resource relationships and clinical context
- 03Security-aware API and authorization architecture
- 04A data path designed for explainable future analytics, not AI theatre