Clinical Data Hierarchy Architecture
Status: Planning Created: 2025-12-25 Last Updated: 2025-12-25 Related: Multi-Practitioner Encounter Types
Overview
This document defines the hierarchical relationship between three core clinical data concepts in Kulcare:
| Concept | Definition | Scope |
|---|---|---|
| Longitudinal Health Record (LHR) | Patient-centric aggregate view of all clinical data | Entire patient history |
| Episode of Care | Program-specific treatment container spanning multiple visits | One treatment program |
| Encounter | Single visit/session between patient and practitioner | One appointment |
These three levels form a clinical data hierarchy that must be preserved in the data model and reflected in the UI/UX.
Clinical Data Hierarchy
Patient
|
+-- Longitudinal Health Record (LHR) <-- AGGREGATE VIEW (computed, not stored)
| |
| +-- Problems (can be linked to episodes)
| +-- Medications (from encounters, linked to episodes)
| +-- Vitals/Measurements (from encounters)
| +-- Assessments (from encounters, trended by episode)
| +-- Encounter History (grouped by episode)
| +-- Health Score (computed from problems, vitals, medications)
|
+-- Episodes of Care <-- PROGRAM CONTAINERS (stored)
| |
| +-- Episode: "Post-ACL Rehab" (physiotherapy)
| | +-- Treatment Goals
| | +-- Progress Notes
| | +-- Encounters (1..N physio sessions)
| |
| +-- Episode: "Anxiety Treatment" (therapy)
| | +-- Treatment Goals
| | +-- Safety Plans
| | +-- Encounters (1..N therapy sessions)
| |
| +-- Episode: "Weight Management" (nutrition)
| +-- Meal Plans
| +-- Nutritional Assessments
| +-- Encounters (1..N consultations)
|
+-- Standalone Encounters <-- NO EPISODE
+-- One-off visits
+-- Acute care
+-- Walk-in appointmentsRelationship Definitions
LHR and Episodes
The Longitudinal Health Record is a computed aggregate view that pulls data from all Episodes and Encounters. It is not stored as a separate entity but constructed on demand.
# LHR aggregates data from:
- Patient.episodes_of_care.active # Current treatment programs
- Patient.encounters # All visits (with and without episodes)
- Patient.problems # Tracked conditions
- Patient.medications # Active and historical medications
- Patient.clinical_measurements # All vitals from all encounters
- Patient.assessment_responses # All assessments from all encountersKey Points:
- LHR provides the "big picture" view of patient health
- Episodes appear as cards/sections within LHR showing active treatment programs
- Problems can optionally link to the Episode addressing them
- Trends (vitals, assessments) can be filtered by Episode
Episodes and Encounters
An Episode of Care is a container for related encounters representing a course of treatment.
class EpisodeOfCare
belongs_to :patient
belongs_to :clinic
belongs_to :primary_provider, class_name: 'User'
has_many :encounters
has_many :treatment_goals
has_many :progress_notes
# Episode metadata
# - episode_type: therapy | physio | nutrition | chronic_care
# - status: active | on_hold | completed | discharged
# - total_sessions_planned
# - sessions_completed
# - frequency: weekly | biweekly | monthly | as_needed
endKey Points:
- Encounters can exist without an Episode (standalone visits)
- Encounters within an Episode share treatment context
- Episode tracks progress: sessions completed, goals achieved
- Episode has a lifecycle: active → completed → discharged
Encounters as Atomic Units
An Encounter is the atomic clinical event where documentation is created.
class Encounter
belongs_to :patient
belongs_to :clinic
belongs_to :episode_of_care, optional: true # Can be standalone
has_many :encounter_documents # 1:N documents per encounter
has_many :clinical_measurements # Vitals, ROM, anthropometrics
has_many :assessment_responses # PHQ-9, GAD-7, etc.
has_many :encounter_notes # Clinical notes with visibility
has_many :encounter_attachments # Files, images, videos
endKey Points:
- Encounter contains all clinical documentation for one visit
- Multiple document types per encounter (prescription + notes + certificate)
- Measurements and assessments are linked to encounters
- Encounters contribute data to both Episode progress and LHR aggregates
Data Flow
Bottom-Up: Encounter to LHR
Encounter (atomic)
|
+-- Creates: Vitals, Medications, Notes, Assessments
|
v
Episode of Care (if linked)
|
+-- Aggregates: Session count, Goal progress, Treatment timeline
|
v
Longitudinal Health Record (computed)
|
+-- Aggregates: All data across all encounters and episodes
+-- Computes: Health score, trends, alertsTop-Down: LHR to Encounter
Longitudinal Health Record
|
+-- Displays: Active Episodes with progress
|
v
Episode of Care
|
+-- Lists: All sessions in this treatment program
|
v
Encounter
|
+-- Shows: Full clinical documentation for this visitNavigation Design
Context-Dependent Entry Points
Entry point varies based on user role and workflow:
| User Role | Primary Entry | Rationale |
|---|---|---|
| Doctor (general) | LHR Dashboard | Needs full patient context for diagnosis |
| Physiotherapist | Episode View | Works within specific rehab program |
| Psychologist | Episode View | Tracks therapy program progress |
| Dietitian | Episode View | Manages nutrition program |
| Receptionist | Encounter List | Schedules individual appointments |
| Clinic Admin | LHR Dashboard | Reviews patient records |
Workflow-Based Entry
| Workflow | Entry Point | Flow |
|---|---|---|
| New patient visit | Create Encounter | Optionally create Episode after initial assessment |
| Continuing care | Episode | Create new Encounter within existing Episode |
| Patient review | LHR Dashboard | Drill into episodes/encounters as needed |
| Acute care/emergency | Create Encounter | Standalone, no Episode needed |
| Program completion | Episode | Review progress, complete/discharge Episode |
Navigation Affordances
Each view provides quick access to related levels:
+-----------------------------------------------------------+
| LHR Dashboard |
| +-------------------------------------------------------+ |
| | Active Episodes [View All ->] | |
| | * Post-ACL Rehab (5/12 sessions) [Open Episode] | |
| | * Anxiety Treatment (3/10) [Open Episode] | |
| +-------------------------------------------------------+ |
| +-------------------------------------------------------+ |
| | Recent Encounters [View All ->] | |
| | * Dec 24 - Physio (in Post-ACL) [Open] | |
| | * Dec 20 - Therapy (in Anxiety) [Open] | |
| | * Dec 18 - GP Visit (standalone) [Open] | |
| +-------------------------------------------------------+ |
+-----------------------------------------------------------+
+-----------------------------------------------------------+
| Episode: Post-ACL Rehab [<- Back to LHR] |
| Patient: John Doe [View Full LHR] |
| --------------------------------------------------------- |
| Progress: ████████░░░░ 5/12 sessions |
| +-------------------------------------------------------+ |
| | Sessions in this Episode | |
| | * Session 5 - Dec 24 [Open Encounter] | |
| | * Session 4 - Dec 17 [Open Encounter] | |
| | * ... | |
| +-------------------------------------------------------+ |
| [+ Add Session] |
+-----------------------------------------------------------+
+-----------------------------------------------------------+
| Encounter: Physio Session #5 [<- Back to Episode]|
| Episode: Post-ACL Rehab [View Full LHR] |
| Patient: John Doe |
| --------------------------------------------------------- |
| [Encounter content: ROM, exercises, notes, etc.] |
+-----------------------------------------------------------+Breadcrumb Pattern
Navigation breadcrumbs reflect the hierarchy:
For encounter within episode:
Patient: John Doe > Episodes > Post-ACL Rehab > Session 5
For standalone encounter:
Patient: John Doe > Encounters > Dec 18 GP Visit
For LHR view:
Patient: John Doe > Health RecordUI/UX Integration Points
LHR Components (Existing)
The existing LHR implementation at frontend/apps/cms/src/pages/care-plan/ needs Episode awareness:
| Component | Current State | Episode Integration |
|---|---|---|
| PatientSummaryDashboard | Health score, alerts, key metrics | Add "Active Episodes" card |
| VitalsTrendChart | All vitals over time | Add "Filter by Episode" option |
| ProblemListManager | All patient problems | Link problems to Episodes |
| MedicationTimeline | All medications | Show Episode context |
| EncounterHistory | Flat list of encounters | Group by Episode (collapsible) |
Episode Components (New)
New components needed for Episode management:
| Component | Purpose |
|---|---|
| EpisodeList | List all episodes for a patient |
| EpisodeDetail | Episode overview with progress, goals, sessions |
| EpisodeCreate | Create new treatment program |
| EpisodeProgress | Visual progress tracking (sessions, goals) |
| TreatmentGoalManager | CRUD for treatment goals within Episode |
Encounter Components (Updates)
Existing encounter components need Episode context:
| Component | Update Needed |
|---|---|
| EncounterHeader | Show Episode badge if linked |
| EncounterCreate | Option to link to existing Episode or create new |
| PrescriptionPage | Show Episode context in header |
API Design
Episode Endpoints
GET /api/v1/patients/:patient_id/episodes_of_care
POST /api/v1/patients/:patient_id/episodes_of_care
GET /api/v1/episodes_of_care/:id
PATCH /api/v1/episodes_of_care/:id
DELETE /api/v1/episodes_of_care/:id
GET /api/v1/episodes_of_care/:id/encounters
POST /api/v1/episodes_of_care/:id/encounters
GET /api/v1/episodes_of_care/:id/treatment_goals
POST /api/v1/episodes_of_care/:id/treatment_goalsLHR Endpoints (Existing)
GET /api/v1/clinics/:clinic_id/patients/:patient_id/longitudinal_health_record
GET /api/v1/clinics/:clinic_id/patients/:patient_id/longitudinal_health_record/problems
GET /api/v1/clinics/:clinic_id/patients/:patient_id/longitudinal_health_record/vitals_trends
GET /api/v1/clinics/:clinic_id/patients/:patient_id/longitudinal_health_record/medications_timelineEnhanced LHR Response
The LHR endpoint should include Episode summary:
{
"patient": { ... },
"health_score": 78,
"active_episodes": [
{
"id": 123,
"episode_type": "physio",
"title": "Post-ACL Rehab",
"status": "active",
"sessions_completed": 5,
"total_sessions_planned": 12,
"primary_provider": { "id": 456, "name": "Dr. Smith" },
"next_session": "2025-12-27T10:00:00Z"
}
],
"recent_encounters": [
{
"id": 789,
"date": "2025-12-24",
"type": "physio_session",
"episode_id": 123,
"episode_title": "Post-ACL Rehab"
}
],
"problems": [ ... ],
"vitals_trends": [ ... ],
"medications": [ ... ]
}Implementation Considerations
Backward Compatibility
- Existing encounters without episodes continue to work
- Existing Prescription model remains for doctor encounters
- LHR continues to show all data regardless of episode grouping
- Episode linking is optional, not required
Migration Path
- Phase 1: Add Episode model, no UI changes
- Phase 2: Add Episode context to existing components
- Phase 3: New Episode management UI
- Phase 4: Full LHR-Episode integration
Performance
- Episode queries should use eager loading for encounters
- LHR aggregation should cache episode summaries
- Consider pagination for encounters within large episodes
- Index on
encounters.episode_of_care_id
Related Documentation
- Multi-Practitioner Encounter Types - Detailed data model for encounters and documents
- Current State: LHR Feature - What's implemented today
- Future State: Episode of Care - Planned Episode implementation
- Frontend Code: LongitudinalHealthRecord - Component location