Kulcare Docs
DeveloperCare plansCare planBackend

Longitudinal Health Records (LHR) System Design

Overview

This document outlines the system design for implementing FHIR-compliant Longitudinal Health Records while maintaining backward compatibility with the existing Kulcare platform.

Frontend Integration: LHR UI exists at /cms/careplan/patient/:patientId with complete dashboard implementation expecting specific API structure.

Current System Analysis

Existing Architecture

  • Current "Careplan": Actually a prescription + lab order system, will be renamed to prescriptions
  • Patient History Log: Polymorphic tracking system capturing all patient events
  • Patient Medicines: Active medication tracking copied from prescription_medicines
  • Document Architecture: Medical records with background document generation
  • Frontend LHR: Complete implementation with aggregation service expecting longitudinal data

Key Insights

  1. Current system works well for encounter-based care delivery
  2. Patient History Log already captures comprehensive event tracking
  3. Need to add patient-level problem tracking for true LHR
  4. Existing patient_medicines provides current medication status

FHIR-Compliant Architecture Design

Healthcare Data Hierarchy

Patient
├── Encounters (Appointments)
│   ├── Clinical Impressions (Diagnosis + Observations)
│   ├── Medication Requests (Individual Prescriptions)
│   └── Service Requests (Lab Tests/Procedures)
├── Problems (Patient-Level Conditions)
├── Care Plans (Aggregated Care Plans)
└── Longitudinal Summary (Aggregated View)

Core Entities

1. Encounters (Existing Appointments)

  • Purpose: Represents patient visits/consultations
  • Status: No changes needed - appointments already serve this role
  • Enhancement: Add clinical_impression field for structured diagnosis

2. Prescriptions (Renamed Careplans)

  • Purpose: Maintains current prescription + lab order workflow
  • Status: Rename from "careplan" to "prescriptions" for simplicity
  • Enhancement: Add links to individual FHIR resources
  • Independence: May or may not belong to an appointment (encounter)

3. Clinical Impressions (New)

  • Purpose: FHIR-compliant clinical assessment and diagnosis
  • Source: Generated from prescription diagnosis + observations
  • Features: Structured diagnosis with ICD-10 codes, clinical reasoning

4. Medication Requests (New)

  • Purpose: Individual FHIR-compliant medication orders
  • Source: Generated from prescription medicines
  • Features: Separate document generation, status tracking

5. Service Requests (New)

  • Purpose: Individual FHIR-compliant service orders (labs, imaging)
  • Source: Generated from prescription tests
  • Features: Separate document generation, status tracking

6. Patient Problems (New)

  • Purpose: Patient-level problem/condition tracking
  • Scope: Aggregated across all encounters within clinic
  • Integration: Links to encounters and medication requests

7. Care Plans (New - True FHIR)

  • Purpose: High-level care coordination plans
  • Scope: Aggregated view of patient care across encounters
  • Content: Goals, care team, active problems, care activities

Data Flow Architecture

1. Encounter Creation Flow

Doctor creates Prescription
└── Background Jobs Trigger
    ├── Generate Clinical Impression record
    ├── Generate Medication Request records
    ├── Generate Service Request records  
    ├── Update Patient Problems
    ├── Generate individual documents
    └── Update Care Plan aggregation

2. LHR Data Aggregation

Patient LHR Request
├── Current Medications (from patient_medicines)
├── Problem List (from patient_problems + encounter history)
├── Encounter History (from appointments + prescriptions)
├── Clinical Assessments (from clinical_impressions)
├── Medication History (from medication_requests)
├── Test History (from service_requests)
└── Care Plans (from care_plans)

3. Document Generation Strategy

Following existing medical_records architecture:

  • Prescription: Full prescription document (current behavior)
  • Clinical Impression: Clinical assessment and diagnosis document
  • Medication Request: Individual medication-specific document
  • Service Request: Individual lab/test order document
  • Care Plan: Care plan summary document

Database Schema Changes

New Tables

clinical_impressions

CREATE TABLE clinical_impressions (
  id BIGSERIAL PRIMARY KEY,
  clinic_id BIGINT NOT NULL,
  patient_id BIGINT NOT NULL,
  doctor_id BIGINT NOT NULL,
  encounter_id BIGINT, -- nullable - prescriptions may not belong to appointment
  prescription_id BIGINT NOT NULL,
  
  -- FHIR ClinicalImpression fields
  status VARCHAR(20) DEFAULT 'completed',
  subject_reference VARCHAR(255),
  assessment_date TIMESTAMP,
  
  -- Clinical assessment
  summary TEXT,
  finding_codes JSONB DEFAULT '[]', -- ICD-10 codes array
  finding_display JSONB DEFAULT '[]', -- Human-readable diagnoses
  clinical_notes TEXT,
  
  -- Outcome and recommendations
  prognostic_reference TEXT,
  plan_reference TEXT,
  
  -- Links to other resources
  supports_prescriptions BIGINT[], -- references to prescription ids
  
  -- Document generation
  document_generated BOOLEAN DEFAULT FALSE,
  document_url TEXT,
  metadata JSONB DEFAULT '{}',
  
  deleted BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL
);

medication_requests

CREATE TABLE medication_requests (
  id BIGSERIAL PRIMARY KEY,
  clinic_id BIGINT NOT NULL,
  patient_id BIGINT NOT NULL,
  doctor_id BIGINT NOT NULL,
  encounter_id BIGINT NOT NULL, -- links to appointment
  prescription_id BIGINT NOT NULL,
  
  -- FHIR fields
  status VARCHAR(20) DEFAULT 'active',
  intent VARCHAR(20) DEFAULT 'order',
  medication_name VARCHAR(255) NOT NULL,
  dosage_instruction TEXT,
  frequency VARCHAR(100),
  duration_value INTEGER,
  duration_unit VARCHAR(20),
  instructions TEXT,
  
  -- Document generation
  document_generated BOOLEAN DEFAULT FALSE,
  document_url TEXT,
  
  deleted BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL
);

service_requests

CREATE TABLE service_requests (
  id BIGSERIAL PRIMARY KEY,
  clinic_id BIGINT NOT NULL,
  patient_id BIGINT NOT NULL,
  doctor_id BIGINT NOT NULL,
  encounter_id BIGINT NOT NULL,
  prescription_id BIGINT NOT NULL,
  
  -- FHIR fields
  status VARCHAR(20) DEFAULT 'active',
  intent VARCHAR(20) DEFAULT 'order',
  service_type VARCHAR(50), -- 'lab_test', 'imaging', 'procedure'
  service_name VARCHAR(255) NOT NULL,
  service_code VARCHAR(50),
  instructions TEXT,
  
  -- Document generation
  document_generated BOOLEAN DEFAULT FALSE,
  document_url TEXT,
  
  deleted BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL
);

patient_problems

CREATE TABLE patient_problems (
  id BIGSERIAL PRIMARY KEY,
  clinic_id BIGINT NOT NULL,
  patient_id BIGINT NOT NULL,
  doctor_id BIGINT NOT NULL,
  
  -- Problem details
  problem_code VARCHAR(50), -- ICD-10 code
  problem_name VARCHAR(255) NOT NULL,
  problem_category VARCHAR(100),
  severity VARCHAR(20),
  
  -- Timeline
  onset_date DATE,
  resolved_date DATE,
  status VARCHAR(20) DEFAULT 'active', -- active, resolved, chronic
  
  -- Clinical context
  first_encounter_id BIGINT, -- first appointment where identified
  last_encounter_id BIGINT,  -- last appointment where addressed
  
  -- Notes
  clinical_notes TEXT,
  
  deleted BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL
);

care_plans

CREATE TABLE care_plans (
  id BIGSERIAL PRIMARY KEY,
  clinic_id BIGINT NOT NULL,
  patient_id BIGINT NOT NULL,
  doctor_id BIGINT NOT NULL,
  
  -- FHIR CarePlan fields
  status VARCHAR(20) DEFAULT 'active',
  intent VARCHAR(20) DEFAULT 'plan',
  title VARCHAR(255),
  description TEXT,
  
  -- Timeline
  period_start DATE,
  period_end DATE,
  
  -- Care coordination
  goals JSONB DEFAULT '{}',
  activities JSONB DEFAULT '{}',
  care_team JSONB DEFAULT '[]',
  
  -- Problem references
  addresses_problems BIGINT[], -- array of patient_problem ids
  
  deleted BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP NOT NULL,
  updated_at TIMESTAMP NOT NULL
);

API Design

LHR Endpoints

# GET /api/patients/:patient_id/longitudinal_health_record
{
  patient: { ... },
  current_problems: [...], 
  current_medications: [...],
  encounter_history: [...],
  clinical_assessments: [...],
  medication_history: [...],
  test_history: [...],
  care_plans: [...],
  health_trends: { ... }
}

New FHIR Resource Endpoints

# Clinical assessment management
GET    /api/clinical_impressions
POST   /api/clinical_impressions
PUT    /api/clinical_impressions/:id
DELETE /api/clinical_impressions/:id

# Medication management
GET    /api/medication_requests
POST   /api/medication_requests  
PUT    /api/medication_requests/:id
DELETE /api/medication_requests/:id

# Service management  
GET    /api/service_requests
POST   /api/service_requests
PUT    /api/service_requests/:id
DELETE /api/service_requests/:id

# Problem management
GET    /api/patient_problems
POST   /api/patient_problems
PUT    /api/patient_problems/:id
DELETE /api/patient_problems/:id

# Care plan management
GET    /api/care_plans
POST   /api/care_plans
PUT    /api/care_plans/:id  
DELETE /api/care_plans/:id

Integration Points

1. Patient History Log Integration

  • ClinicalImpression, MedicationRequest, ServiceRequest, and CarePlan will automatically log to patient_history_logs
  • Use existing trackable polymorphic pattern
  • Maintain existing filtering and search capabilities

2. Document Generation Integration

  • Follow existing medical_records + documents pattern
  • Background jobs for individual document generation
  • Maintain combined prescription document for pharmacy workflow

3. Real-time Updates Integration

  • Use existing Pusher channels for real-time prescription updates
  • Add new channels for medication/service request status changes
  • Maintain existing queue management integration

Security & Privacy

Access Control

  • Maintain existing Pundit authorization patterns
  • Clinic-scoped data access for all new entities
  • Doctor-patient relationship validation for all operations

FHIR Compliance

  • Follow FHIR R4 standard for resource definitions
  • Maintain required FHIR fields and terminology
  • Support FHIR Bundle export for ABDM integration

Data Retention

  • Follow existing soft delete patterns
  • Maintain audit trails for all medical data changes
  • Support data export for patient portability

Performance Considerations

Indexing Strategy

-- Core performance indices
CREATE INDEX idx_medication_requests_patient ON medication_requests(patient_id, status);
CREATE INDEX idx_service_requests_patient ON service_requests(patient_id, status);  
CREATE INDEX idx_patient_problems_clinic ON patient_problems(clinic_id, patient_id, status);
CREATE INDEX idx_care_plans_patient ON care_plans(patient_id, status);

-- LHR aggregation indices
CREATE INDEX idx_patient_problems_active ON patient_problems(patient_id) WHERE status = 'active';
CREATE INDEX idx_medication_requests_active ON medication_requests(patient_id) WHERE status = 'active';

Caching Strategy

  • Redis caching for frequently accessed LHR data
  • Cache patient problem lists and current medications
  • Invalidate cache on medical record updates

Background Processing

  • Use existing Sidekiq infrastructure
  • Separate queues for document generation vs. data aggregation
  • Retry logic for failed document generation

Migration Approach

Backward Compatibility

  1. Phase 1: Add new tables alongside existing careplan table
  2. Phase 2: Rename careplan to prescription with aliases
  3. Phase 3: Update frontend gradually with feature flags
  4. Phase 4: Remove aliases after full migration

Data Migration Strategy

  • No data loss - existing careplans become prescriptions
  • Generate MedicationRequest/ServiceRequest records from existing data
  • Create initial patient_problems from historical diagnosis data
  • Build care_plans from aggregated encounter data

Success Metrics

Technical Metrics

  • API response time < 200ms for LHR endpoints
  • Document generation completion rate > 99%
  • Zero data loss during migration
  • Backward compatibility maintained for 30 days

Business Metrics

  • No disruption to existing prescription workflow
  • Enhanced patient care coordination capabilities
  • Improved medication adherence tracking
  • Better care plan compliance monitoring

On this page