Skip to main content

Patient Chart Service — Service Overview

Status: populated Owner: TBD Last updated: 2026-04-17 Companion: Service Template · 03 platform-services · 02 DDD · FHIR-First

1. Purpose

The patient-chart-service is the authoritative longitudinal chart aggregate for the Ghasi-eHealth platform. It owns the structured clinical facts that describe a patient over time — the problem list, allergies/intolerances, vital signs, clinical notes, and the chart composition/sections that clinicians read and write from the bedside, clinic, ward, or virtual-care surface.

Unlike a read-only aggregator, this service is the source of truth for these clinical aggregates. It writes Condition, AllergyIntolerance, Observation (vital-signs), Composition, and DocumentReference FHIR resources; it emits a full domain event stream on every mutation; and it exposes both a product REST surface (/v1/chart/*, /v1/problems/*, /v1/allergies/*, /v1/vitals/*, /v1/clinical-notes/*) and a FHIR R4 read surface via interop-service.

2. Bounded Context

Patient Chart (previously scattered across five module specs: patient-chart, problem-list, allergies, vitals, clinical-notes) — classified as Core (mission-critical clinical domain). Consolidating the five modules into one service eliminates chart-shaped data being split across five datastores, each with its own RLS rules and outbox.

TraitValue
DDD classificationCore
Hexagonal layoutdomain/ application/ infrastructure/ presentation/
FHIR ownershipCondition, AllergyIntolerance, Observation (vital-signs), Composition, DocumentReference for chart documents, optional Provenance
RuntimeNestJS 11 / Node 22 / TS 5.x
PersistencePostgres 16 with RLS; one logical schema patient_chart
EventsNATS JetStream — stream PATIENT_CHART

3. Responsibilities

AreaWhat Patient Chart Owns
Chart headerBanner composition (demographics proxy + alerts); encounter context mode (chart-only vs encounter-scoped)
Chart summarySummary widget composition over owned aggregates + remote reads from medication-service, laboratory-service, radiology-service, immunizations-service, care-plan-service
Chart timelineLongitudinal timeline with filters; cursor-paginated merge over owned aggregates + downstream reads
Problem listFull lifecycle: active/inactive/resolved/entered-in-error; ICD-10/11 + SNOMED CT coding via terminology-service
Allergies/intolerancesSubstance coding; reaction manifestations; severity; NKA/NKDA assertions; advisory safety check API for medication-service/orders-service
Vital signsLOINC-coded Observation panels with UCUM units; range validation; abnormal flagging; trending
Clinical notesTemplated note authoring (SOAP, H&P, consult, procedure, discharge); draft → signed → amended lifecycle; cosign/attestation routing; AI-assist provenance capture
Chart snapshotHandoff/rounding snapshot composition; export/print with audit and permission gate
Break-glassReason-captured emergency access with audit event emission
Chart access auditPer-item access logging to audit-service

4. Non-Responsibilities

AreaOwnerWhy Not Patient Chart
Patient demographics & MRNregistration-serviceChart reads via remote query; registration is source of truth
Encountersregistration-serviceChart consumes Encounter; does not mint
Medicationsmedication-serviceChart displays summary widget; medication-service owns MedicationRequest/MedicationAdministration
Orders / CPOEorders-serviceChart links to orders; orders-service writes ServiceRequest
Lab resultslaboratory-serviceChart displays results widget; LIS owns DiagnosticReport + lab Observation
Imaging reportsradiology-serviceChart displays filed imaging summaries (via DiagnosticReport read)
Immunizationsimmunizations-serviceChart displays immunization widget
Care planscare-plan-serviceChart displays active plans/goals widget
Document bytes (Binary)document-serviceClinical-note PDFs referenced via DocumentReferenceBinary in DMS
Terminology lookupterminology-serviceChart consumes code lookup, value-set expansion, ICD/SNOMED search
Authorizationidentity + tenant servicesChart calls access-policy checks; does not store roles

5. Dependencies

5.1 Upstream (Chart calls out)

DependencyPatternPurpose
registration-serviceSync REST + registration.patient.* event consumerPatient exists check; encounter context resolution
terminology-serviceSync REST (/internal/terminology/lookup, /validate, /expand)Coded value rendering, value-set constraint, ICD/SNOMED search
provider-directory-serviceSync RESTPractitioner / PractitionerRole display resolution for performer, author, cosigner
facility-serviceSync RESTLocation resolution for collection-location / encounter location
medication-serviceSync REST / event consumerSummary widget data; allergy-check consumer on its side
laboratory-serviceSync RESTSummary & timeline widgets (DiagnosticReport, lab Observation)
radiology-serviceSync RESTSummary widget — filed imaging summaries
immunizations-serviceSync RESTImmunization widget
care-plan-serviceSync RESTActive care-plan widget
audit-serviceEvent producerEvery mutation + chart access emits audit
ai-gateway-serviceSync REST (only via Kong /v1/ai/*)Clinical-note AI assist (Tier A) with HITL accept
document-serviceSync RESTDocumentReference + Binary for signed-note PDFs and scanned attachments

5.2 Downstream (consumers)

ConsumerPatternWhat They Consume
medication-serviceEvent consumerpatient_chart.allergy.added.v1, ...updated.v1 — refresh allergy safety-check cache
orders-serviceSync REST GET /v1/allergies/advisory?patientId=CDS allergy check at order entry
population-health-serviceEvent consumerProblem-list and vitals events for cohort builders / HMIS indicator exports
patient-portal-serviceSync REST (scoped) + event consumerPatient-visible chart read
interop-service (FHIR gateway)Sync REST /fhir/R4/*Partner read/search for Condition, AllergyIntolerance, Observation, Composition, DocumentReference
communication-serviceEvent consumerCosign-requested routing, abnormal-vitals notifications

5.3 Events consumed by Patient Chart

EventProducerPurpose
registration.patient.merged.v1registration-serviceRe-home chart aggregates to surviving patient id
registration.encounter.created.v1registration-servicePre-fetch encounter cache for chart banner
gdpr.subject_request.received.v1platformParticipate in GDPR erasure saga — redact author PII on historical records, retain clinical content per retention policy

6. Slice Involvement

SliceScopeMilestone
S0 — Core BaselineProblem list CRUD + lifecycle; allergy CRUD + advisory API; vitals capture + trending; draft note + sign; chart summary (owned aggregates); bannerM0
S1 — Integration + OfflineMedication/lab/imaging summary widgets; timeline cursor API; offline capture queue for vitals + allergies on tablet devicesM1
S2 — Handoff + SensitiveChart snapshot export with audit; break-glass; sensitive-segment policyM2
S3 — AI-Assist + Advanced NotesClinical-notes AI assist (Tier A: template fill, summarize, STT from virtual-care), cosign routing, amendments with provenanceM3

7. Architectural Freeze Points

FreezeWhat Is FrozenFrozen By
F03Branded IDs: ProblemId (prb_*), AllergyId (alg_*), VitalsSetId (vit_*), ObservationId (obs_*), NoteId (note_*), ChartId (cha_*)M0
F01EventEnvelope — all chart events conform to platform envelopeM0
F05Allergy advisory payload shape — orders-service and medication-service contractEnd of M1

8. Service Readiness Levels

LevelDescriptionTarget
L2Core aggregate CRUD live, FHIR read surface on Condition/AllergyIntolerance/Observation availableM0
L3Full summary + timeline, contract tests against medication/lab/rad/imm/care-planM1
L4Break-glass + snapshot + AI-assist + SLO-governed, chaos-testedM3

9. Architecture Diagram

10. Key Design Decisions

  1. Five modules consolidated into one service. Legacy patient-chart, problem-list, allergies, vitals, clinical-notes ship as a single bounded context because the aggregates share the same tenancy, RLS model, audit path, and consumer set. Cross-aggregate invariants (e.g., "NKA blocks adding a substance allergy", "signed notes can reference active problems atomically") are enforced in-process.
  2. FHIR is canonical meaning; Postgres is authoritative state. Writes go to REST on /v1/*; FHIR read/search is composed by adapters in infrastructure/fhir/. Writes via FHIR HTTP are out-of-scope until an explicit release declares them (per FHIR_FIRST_STANDARD.md §6).
  3. Clinical notes use Composition + DocumentReference. Draft and signed notes are structured Composition resources with sections; on sign, a rendered PDF is uploaded to document-service and referenced by DocumentReference. Legal record tracking lives on the ClinicalNote aggregate; PDF bytes live in document-service.
  4. Allergy advisory is a synchronous internal API. orders-service and medication-service call GET /v1/allergies/advisory?patientId=&rxnorm= at order entry / prescribe sign. Fail-open is enforced by callers, not by the chart service.
  5. Vitals are one Observation per measurement, grouped by a vitals_set_id. Panel pattern supported for list/read; storage is per-measurement to preserve FHIR fidelity.
  6. AI assist writes a NoteAIProvenance row on accept. No AI output ever replaces signed content without explicit clinician "accept" action.
  7. Summary widgets are composed, not duplicated. Chart does not shadow-store medications or lab results; it calls downstream read APIs with per-user scope.

11. Source reconciliation (five-module merge decisions)

DecisionRationale
Single patient_chart DB schema with sub-folders problems/, allergies/, vitals/, notes/, chart/.One RLS policy, one outbox, one migration pipeline.
Unified event stream PATIENT_CHART with subject pattern patient_chart.{aggregate}.{event}.v{N}. Subjects preserved: patient_chart.problem.added.v1, patient_chart.allergy.added.v1, patient_chart.vitals.recorded.v1, patient_chart.note.signed.v1, patient_chart.breakglass.invoked.v1.Legacy subjects (PROBLEMS.*, ALLERGIES.*, VITALS.*, CLINICAL_NOTES.*) are deprecated and dual-published for M0→M1; see MIGRATION_PLAN.md.
Unified FR-CHART-* prefix for synthesized FRs in this service. Legacy FR refs (FR-PCHART-*, FR-PROB-*, FR-ALG-*, FR-VIT-*, FR-NOTES-*) preserved in the "Legacy ref" column of EPICS.md and USER_STORIES.md.Single FR domain for the merged service.
Banner + Summary + Timeline remain part of this service rather than being extracted as a read-only aggregator.Chart-shaped composition requires access to owned aggregates' RLS; keeping the composition in-process avoids double-RLS and latency.
UX_UI_SPEC (from _sources/patient-chart/UX_UI_SPEC.md, ~595 lines) is treated as informative for the UI layer in the patient-portal-service and provider-web app; the backend service offers the API surface required to satisfy it.UI belongs to the app package, not the service.
STT APSO integration (_sources/clinical-notes/STT_APSO_INTEGRATION.md) is delegated to ai-gateway-service. Chart consumes finalized STT drafts via the standard AI-assist contract.Keep AI plumbing centralized.
requisitions-referrals touches (cross-links from clinical-notes) are redirected to orders-service per ADR-0046.Retired module.