Kulcare Docs
DeveloperCare plansCare planArchitecture

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:

ConceptDefinitionScope
Longitudinal Health Record (LHR)Patient-centric aggregate view of all clinical dataEntire patient history
Episode of CareProgram-specific treatment container spanning multiple visitsOne treatment program
EncounterSingle visit/session between patient and practitionerOne 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 appointments

Relationship 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 encounters

Key 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
end

Key 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
end

Key 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, alerts

Top-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 visit

Context-Dependent Entry Points

Entry point varies based on user role and workflow:

User RolePrimary EntryRationale
Doctor (general)LHR DashboardNeeds full patient context for diagnosis
PhysiotherapistEpisode ViewWorks within specific rehab program
PsychologistEpisode ViewTracks therapy program progress
DietitianEpisode ViewManages nutrition program
ReceptionistEncounter ListSchedules individual appointments
Clinic AdminLHR DashboardReviews patient records

Workflow-Based Entry

WorkflowEntry PointFlow
New patient visitCreate EncounterOptionally create Episode after initial assessment
Continuing careEpisodeCreate new Encounter within existing Episode
Patient reviewLHR DashboardDrill into episodes/encounters as needed
Acute care/emergencyCreate EncounterStandalone, no Episode needed
Program completionEpisodeReview progress, complete/discharge Episode

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.]          |
+-----------------------------------------------------------+

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 Record

UI/UX Integration Points

LHR Components (Existing)

The existing LHR implementation at frontend/apps/cms/src/pages/care-plan/ needs Episode awareness:

ComponentCurrent StateEpisode Integration
PatientSummaryDashboardHealth score, alerts, key metricsAdd "Active Episodes" card
VitalsTrendChartAll vitals over timeAdd "Filter by Episode" option
ProblemListManagerAll patient problemsLink problems to Episodes
MedicationTimelineAll medicationsShow Episode context
EncounterHistoryFlat list of encountersGroup by Episode (collapsible)

Episode Components (New)

New components needed for Episode management:

ComponentPurpose
EpisodeListList all episodes for a patient
EpisodeDetailEpisode overview with progress, goals, sessions
EpisodeCreateCreate new treatment program
EpisodeProgressVisual progress tracking (sessions, goals)
TreatmentGoalManagerCRUD for treatment goals within Episode

Encounter Components (Updates)

Existing encounter components need Episode context:

ComponentUpdate Needed
EncounterHeaderShow Episode badge if linked
EncounterCreateOption to link to existing Episode or create new
PrescriptionPageShow 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_goals

LHR 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_timeline

Enhanced 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

  1. Phase 1: Add Episode model, no UI changes
  2. Phase 2: Add Episode context to existing components
  3. Phase 3: New Episode management UI
  4. 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

On this page