Kulcare Docs
DeveloperCare plansCare planFuture state

Episode of Care Comprehensive Implementation Plan

Status: In Progress (Refined & Aligned with Codebase Architecture)
Priority: High
Target Branch: feature/episodes-of-care
Architecture Principle: Maximum reuse of existing Clinical Domain models, controllers, blueprints, and CMS components.


Table of Contents

  1. Executive Summary & Current Architecture Baseline
  2. Entity Relationships & Data Architecture
  3. Database Schema & Delta Migrations
  4. Episode Lifecycle & State Machine
  5. Appointment & CMS Queue Integration (Maximum Reuse)
  6. Multi-Specialty Integrated Care
  7. API Surface & Controller Re-use
  8. Frontend & UI Integration Strategy
  9. Permissions, Authorization & Security
  10. Re-Baselined Implementation Roadmap
  11. Appendices

1. Executive Summary & Current Architecture Baseline

1.1 Purpose

An Episode of Care represents a longitudinal course of clinical treatment spanning multiple encounters and scheduled appointments. It groups sessions, tracks progress against multi-disciplinary treatment goals, and connects acute and chronic encounters into coherent care plans.

1.2 Architectural Realignment (Codebase Audit)

A critical audit of the kulcare-platform revealed that key foundations are already built. Rather than recreating tables or creating parallel endpoints, this plan extends existing structures and hooks directly into the running domain architecture:

System LayerCurrent Codebase BaselinePlan Strategy
Database Schemaclinical.episodes_of_care and clinical.treatment_goals exist in db/structure.sql with native PG Enums, UUIDv7, and RLS.Apply incremental non-breaking migrations (ALTER TABLE) to add integrated care, session quotas, and appointment FK.
Core ModelsClinical::EpisodeOfCare and Clinical::TreatmentGoal models exist with transition state machines and validations.Enhance models with session calculations, integrated care helpers, and quota validations.
Routing & APIsEndpoints already live under /clinical/episodes_of_care and /clinical/treatment_goals in domains/clinical/routes.rb.Reuse all existing REST endpoints. Add episode_of_care_id to appointment_params in AppointmentsController.
CMS QueueDriven by QueueController using Queue::GenerateToday and AppointmentBlueprint (view: :queue).Extend AppointmentBlueprint's queue view to serialize episode context and preload associations to maintain O(1) query performance.
CMS FrontendExisting pages in frontend/apps/cms/src/features/episode/ (EpisodeListPage, EpisodeDetailPage, EpisodeFormPage, EpisodeStatusBadge).Retain existing CMS pages and @kulcare/shared-services hooks; add CMS Queue badges, filter controls, and session linker modals.
Patient App (PHR)Contains patient appointments, visits, and timeline in patient/src/features/.Introduce the patient-facing "My Care Programs" tab using serialized episode summaries.

2. Entity Relationships & Data Architecture

2.1 High-Level Architecture

2.2 Session Lifecycle (Appointment to Encounter)

An Episode tracks both scheduled sessions (appointments) and delivered care (encounters):

2.3 Complete Entity Relationship Diagram

2.4 Multi-Specialty (Integrated Care) Model

For complex care pathways (e.g., Post-Surgical ACL Rehabilitation, Bariatric Program, Cardiac Rehab), sessions and goals span multiple specialties under a single episode container:


3. Database Schema & Delta Migrations

3.1 Existing Baseline Tables (structure.sql)

The database already defines the core tables:

  1. clinical.episodes_of_care:
    • Status ENUM: planned, waitlist, active, onhold, finished, cancelled, entered_in_error.
    • Type ENUM: rehabilitation, chronic_care, mental_health, maternity, oncology, preventive, acute.
    • Columns: id (uuidv7), tenant_id, patient_id, facility_id, managing_practitioner_id, status, type, diagnosis_codes, period_start, period_end, description, patient_facility_id, timestamps.
    • RLS: FORCE ROW LEVEL SECURITY is already active.
  2. clinical.treatment_goals:
    • Status ENUM: proposed, planned, accepted, active, on_hold, achieved, cancelled, entered_in_error.
    • Priority ENUM: high, medium, low.
    • Columns: id (uuidv7), tenant_id, episode_of_care_id, description, status, priority, target_date, outcome, timestamps.
  3. clinical.encounters:
    • Already has episode_of_care_id UUID and foreign key constraint fk_encounters_episode_of_care referencing clinical.episodes_of_care(tenant_id, id).

3.2 Migration: Extend episodes_of_care

Create migration db/migrate/YYYYMMDDHHMMSS_extend_clinical_episodes_of_care.rb:

class ExtendClinicalEpisodesOfCare < ActiveRecord::Migration[7.2]
  def change
    add_column :episodes_of_care, :is_integrated_care, :boolean, default: false, null: false
    add_column :episodes_of_care, :primary_specialty_id, :uuid
    add_column :episodes_of_care, :total_sessions_planned, :integer, default: 0, null: false
    add_column :episodes_of_care, :sessions_completed, :integer, default: 0, null: false
    add_column :episodes_of_care, :period_end_target, :date
    add_column :episodes_of_care, :metadata, :jsonb, default: {}, null: false

    add_index :episodes_of_care, [:tenant_id, :is_integrated_care]
    add_index :episodes_of_care, [:tenant_id, :primary_specialty_id]
  end
end

3.3 Migration: Add episode_of_care_id to appointments

Create migration db/migrate/YYYYMMDDHHMMSS_add_episode_of_care_to_appointments.rb:

class AddEpisodeOfCareToAppointments < ActiveRecord::Migration[7.2]
  disable_ddl_transaction!

  def change
    add_column :appointments, :episode_of_care_id, :uuid

    # Concurrent index to prevent table lock in production
    add_index :appointments,
              [:tenant_id, :episode_of_care_id],
              name: 'idx_appointments_tenant_episode',
              algorithm: :concurrently

    add_foreign_key :appointments,
                    :episodes_of_care,
                    column: :episode_of_care_id,
                    on_delete: :nullify,
                    validate: false
  end
end

(A subsequent migration runs validate_foreign_key :appointments, :episodes_of_care to ensure zero lock contention).

3.4 Migration: Extend treatment_goals

Create migration db/migrate/YYYYMMDDHHMMSS_extend_clinical_treatment_goals.rb:

class ExtendClinicalTreatmentGoals < ActiveRecord::Migration[7.2]
  def change
    add_column :treatment_goals, :progress_percentage, :integer, default: 0, null: false
    add_column :treatment_goals, :specialty_id, :uuid
    add_column :treatment_goals, :created_by_id, :uuid

    add_check_constraint :treatment_goals,
                         'progress_percentage >= 0 AND progress_percentage <= 100',
                         name: 'chk_treatment_goals_progress_range'
    add_index :treatment_goals, [:tenant_id, :specialty_id]
  end
end

3.5 Multi-Tenancy & Row Level Security (RLS)

All tables exist in the clinical schema and inherit Shared::Concerns::TenantScoped. PostgreSQL enforces RLS:

ALTER TABLE ONLY clinical.episodes_of_care FORCE ROW LEVEL SECURITY;
ALTER TABLE ONLY clinical.treatment_goals FORCE ROW LEVEL SECURITY;
ALTER TABLE ONLY clinical.appointments FORCE ROW LEVEL SECURITY;

Every query issued by Rails automatically includes tenant_id = current_setting('app.current_tenant_id').


4. Episode Lifecycle & State Machine

4.1 Status Definitions & FHIR R4 Alignment

Internal StatusFHIR R4 StatusMeaning
plannedplannedEpisode created but therapy has not commenced.
waitlistwaitlistPatient is waiting for slot/specialist availability.
activeactiveCare is currently ongoing; sessions can be held.
onholdonholdCare temporarily suspended (patient travelling, post-op rest).
finishedfinishedTreatment plan concluded; goals met or course done.
cancelledcancelledPatient withdrew or program discontinued prior to completion.
entered_in_errorentered-in-errorRecord made in error; marked invalid.

4.2 Valid Transition Matrix

Transition Truth Table

From \ Toplannedwaitlistactiveonholdfinishedcancelledentered_in_error
planned—✅✅❌✅✅✅
waitlist❌—✅❌✅✅✅
active❌❌—✅✅✅✅
onhold❌❌✅—✅✅✅
finished❌❌❌❌—❌✅
cancelled❌❌❌❌❌—✅
entered_in_error❌❌❌❌❌❌—

4.3 State Transition Methods & Model Logic

The model Clinical::EpisodeOfCare already implements these state transitions:

  • activate!: Sets period_start ||= Date.current and transitions to :active.
  • put_on_hold!: Transitions to :onhold.
  • resume!: Transitions from :onhold back to :active.
  • finish!: Sets period_end ||= Date.current and transitions to :finished.
  • cancel!: Sets period_end ||= Date.current and transitions to :cancelled.
# In Clinical::EpisodeOfCare
def can_transition_to?(new_status)
  VALID_TRANSITIONS[status.to_sym]&.include?(new_status.to_sym) || false
end

4.4 Business Rules & Action Matrix

Operationplannedwaitlistactiveonholdfinishedcancelledentered_in_error
Book / Add New Appointment✅❌✅❌❌❌❌
Link Existing Encounter✅❌✅❌❌❌❌
Add / Edit Treatment Goals✅✅✅✅❌❌❌
Update Progress Percentage❌❌✅❌❌❌❌
Auto-completion Check❌❌Triggered when sessions_completed >= total_sessions_planned❌N/AN/AN/A

5. Appointment & CMS Queue Integration (Maximum Reuse)

5.1 Appointment Linking Architecture

Appointments scheduled in CMS or through online booking can belong directly to an Episode.

  • In Clinical::Appointment:
    belongs_to :episode_of_care, class_name: 'Clinical::EpisodeOfCare', optional: true
  • In Clinical::AppointmentsController: Permit :episode_of_care_id in appointment_params.

5.2 Extending AppointmentBlueprint (Zero-New-Endpoint Queue Data)

The CMS Queue is powered by QueueController using AppointmentBlueprint.render_as_hash(..., view: :queue). By extending the existing :queue view in AppointmentBlueprint, queue responses automatically include episode details without requiring any new queue APIs:

# In domains/clinical/blueprints/appointment_blueprint.rb
view :queue do
  # ... existing fields (status, waiting_room, patient, practitioner, encounter) ...

  field :episode_of_care do |appt, _|
    next nil unless appt.episode_of_care.present?

    episode = appt.episode_of_care
    {
      id: episode.id,
      type: episode.type,
      status: episode.status,
      description: episode.description,
      is_integrated_care: episode.is_integrated_care,
      sessions_completed: episode.sessions_completed,
      total_sessions_planned: episode.total_sessions_planned,
      progress_percentage: episode.total_sessions_planned.positive? ?
        ((episode.sessions_completed.to_f / episode.total_sessions_planned) * 100).round : 0
    }
  end
end

5.3 Performance: Preloading in Queue::GenerateToday

To avoid N+1 queries across the queue listing, update Queue::GenerateToday#fetch_todays_appointments:

# In domains/clinical/services/queue/generate_today.rb
Clinical::Appointment
  .for_practitioner(@practitioner.id)
  .for_facility(@facility.id)
  .for_date(@date, @timezone)
  .includes(
    :patient,
    :facility,
    :practitioner,
    :episode_of_care, # <-- Add eager loading here
    encounter: { video_sessions: :participants }
  )
  .order(:start_time)

5.4 Dual-Sync Rule: Synchronous Appointment-Encounter Linking

When an appointment with an episode_of_care_id starts:

  1. Encounters::StartService creates the Clinical::Encounter and copies appointment.episode_of_care_id to encounter.episode_of_care_id.
  2. When the encounter is finished, Encounters::StatusService increments episode.sessions_completed if linked.
  3. If a provider retroactively links a standalone encounter to an episode, its parent appointment is updated simultaneously.
# In domains/clinical/services/episodes_of_care/link_encounter_service.rb
class LinkEncounterService < Shared::BaseService
  def initialize(encounter:, episode:)
    @encounter = encounter
    @episode = episode
  end

  def call
    ActiveRecord::Base.transaction do
      @encounter.update!(episode_of_care: @episode)
      @encounter.appointment&.update!(episode_of_care: @episode)
      @episode.increment!(:sessions_completed)
    end
    Success(@encounter)
  end
end

5.5 Retroactive & Batch Linking Services

Providers can link an existing encounter or appointment directly from the queue or encounter summary:

  • Direct update via existing endpoint:
    PATCH /clinical/encounters/:id
    Content-Type: application/json
    
    {
      "encounter": {
        "episode_of_care_id": "019234a5-b67c-7890-abcd-1234567890ab"
      }
    }
  • Direct appointment link via existing endpoint:
    PATCH /clinical/appointments/:id
    Content-Type: application/json
    
    {
      "appointment": {
        "episode_of_care_id": "019234a5-b67c-7890-abcd-1234567890ab"
      }
    }

5.6 CMS Queue UI Integration

5.6.1 Queue Row with Episode Badge

┌─────────────────────────────────────────────────────────────────────────────┐
│ CMS QUEUE - TODAY'S APPOINTMENTS                                            │
├─────────────────────────────────────────────────────────────────────────────┤
│ 10:00 AM  │ John Doe (M, 32)      │ Physio Session 6    │ [Start Encounter] │
│           │ Walk-in               │ Dr. Physio          │                   │
│           │ [Badge: Post-Surgery Recovery (5/12 • 42%)] │ [Episode Options▼]│
├───────────┼───────────────────────┼─────────────────────┼───────────────────┤
│ 10:30 AM  │ Jane Smith (F, 28)    │ Consultation        │ [Start Encounter] │
│           │ Fixed                 │ Dr. General         │                   │
│           │ No Episode Linked                           │ [+ Link Episode]  │
└─────────────────────────────────────────────────────────────────────────────┘

5.6.2 Queue Filter by Episode

The CMS queue includes an episode filter populated from GET /clinical/episodes_of_care?active=true&facility_id=:facility_id:

  • Filters: [All Episodes ▼] | Post-Surgery Recovery (4) | Knee Rehab Program (2) | No Episode (8)

6. Multi-Specialty Integrated Care

6.1 Single vs Integrated Episode Models

  • Single Specialty: e.g., 12-session Physiotherapy program where all sessions belong to one practitioner type.
  • Integrated Care (is_integrated_care: true): e.g., Comprehensive Post-Surgical Rehab involving Physiotherapist, Nutritionist, and Psychologist.

6.2 Specialty Quota & Session Distribution

In an integrated care program, quotas are tracked by specialty:

{
  "total_sessions_planned": 26,
  "sessions_completed": 10,
  "specialty_distribution": {
    "physiotherapy": { "planned": 12, "completed": 5 },
    "nutrition": { "planned": 6, "completed": 3 },
    "psychology": { "planned": 8, "completed": 2 }
  }
}

6.3 Multi-Specialty Progress Aggregation

In Clinical::EpisodeOfCareBlueprint (view: :detailed), aggregate counts dynamically:

field :specialty_breakdown do |episode|
  next nil unless episode.is_integrated_care

  episode.encounters.group(:specialty_id).count
end

7. API Surface & Controller Re-use

All APIs operate under the standard Rails routing scope :clinical, module: 'clinical' in domains/clinical/routes.rb.

7.1 Existing Clinical Endpoints (To Reuse Directly)

OperationExisting HTTP RouteController & Action
List EpisodesGET /clinical/episodes_of_careClinical::EpisodesOfCareController#index
Show EpisodeGET /clinical/episodes_of_care/:idClinical::EpisodesOfCareController#show
Create EpisodePOST /clinical/episodes_of_careClinical::EpisodesOfCareController#create
Update EpisodePATCH /clinical/episodes_of_care/:idClinical::EpisodesOfCareController#update
Delete EpisodeDELETE /clinical/episodes_of_care/:idClinical::EpisodesOfCareController#destroy
Transition StatusPOST /clinical/episodes_of_care/:id/transitionClinical::EpisodesOfCareController#transition
List Episode GoalsGET /clinical/episodes_of_care/:id/goalsClinical::EpisodesOfCareController#goals
List Episode EncountersGET /clinical/episodes_of_care/:id/encountersClinical::EpisodesOfCareController#encounters
List Episode NotesGET /clinical/episodes_of_care/:id/notesClinical::EpisodesOfCareController#notes
Export FHIRGET /clinical/episodes_of_care/:id/exportClinical::EpisodesOfCareController#export
Patient EpisodesGET /clinical/patients/:id/episodes_of_careHandled via index?patient_id=:id
List Treatment GoalsGET /clinical/treatment_goalsClinical::TreatmentGoalsController#index
Create Treatment GoalPOST /clinical/treatment_goalsClinical::TreatmentGoalsController#create
Update Treatment GoalPATCH /clinical/treatment_goals/:idClinical::TreatmentGoalsController#update
Transition GoalPOST /clinical/treatment_goals/:id/transitionClinical::TreatmentGoalsController#transition
Achieve GoalPOST /clinical/treatment_goals/:id/achieveClinical::TreatmentGoalsController#achieve

7.2 Parameter Extensions on Existing Controllers

1. In Clinical::EpisodesOfCareController#episode_params

Add the new attributes to permitted parameters:

def episode_params
  params.require(:episode_of_care).permit(
    :patient_id, :facility_id, :managing_practitioner_id,
    :status, :type, :period_start, :period_end, :period_end_target,
    :is_integrated_care, :primary_specialty_id,
    :total_sessions_planned, :description,
    diagnosis_codes: [
      :text, :role, :rank,
      { coding: %i[system code display] }
    ],
    metadata: {}
  )
end

2. In Clinical::AppointmentsController#appointment_params

Permit :episode_of_care_id:

def appointment_params
  params.require(:appointment).permit(
    :appointment_type, :start_time, :end_time,
    :patient_instruction, :note, :episode_of_care_id,
    reason_codes: [:text, { coding: %i[system code display] }]
  )
end

3. In Clinical::TreatmentGoalsController#goal_params

Permit :progress_percentage, :specialty_id, :created_by_id:

def goal_params
  params.require(:treatment_goal).permit(
    :episode_of_care_id, :description, :status, :priority,
    :target_date, :progress_percentage, :specialty_id, :outcome
  )
end

7.3 Detailed Endpoint Contracts

Status Transition Contract

POST /clinical/episodes_of_care/019234a5-b67c-7890-abcd-1234567890ab/transition
Content-Type: application/json

{
  "status": "active"
}

Response (200 OK):

{
  "id": "019234a5-b67c-7890-abcd-1234567890ab",
  "status": "active",
  "type": "rehabilitation",
  "period_start": "2026-10-06",
  "period_end": null,
  "duration_days": 0,
  "active": true,
  "terminal": false,
  "clinical_summary": "Rehabilitation Episode (active) - John Doe at City Clinic since 2026-10-06",
  "allowed_transitions": ["onhold", "finished", "cancelled", "entered_in_error"],
  "encounter_count": 0,
  "goal_count": 3
}

8. Frontend & UI Integration Strategy

8.1 Existing CMS Episode Components (To Reuse & Extend)

Located in frontend/apps/cms/src/features/episode/:

  1. EpisodeListPage.tsx: Displays list of episodes filterable by patient and status.
  2. EpisodeDetailPage.tsx: Overview card, progress display, sessions, and linked goals.
  3. EpisodeFormPage.tsx: Creation/editing form.
  4. EpisodeStatusBadge.tsx: Visual badge for episode status.
  5. EpisodeCard.tsx: Summary card widget.
  6. useEpisode.ts: Hook importing from @kulcare/shared-services:
    • useEpisodeList, useEpisode, useEpisodeEncounters, useCreateEpisode, useUpdateEpisode, useDeleteEpisode, useTransitionEpisode.

8.2 CMS Queue Components (Delta Deliverables)

Located in frontend/apps/cms/src/features/queue/:

  1. QueueEpisodeBadge.tsx: Displays badge directly in queue appointment rows using appointment.episode_of_care.
  2. QueueEpisodeDropdown.tsx: Dropdown to quickly link an unlinked appointment to an active episode.
  3. QueueEpisodeFilter.tsx: Filter queue items by active episode name.

8.3 LHR (Provider) View Integration

Located in frontend/apps/cms/src/features/patient-record/:

  • Add "Active Programs" section to the Patient Summary dashboard.
  • In Encounter History: Group encounters belonging to the same Episode into a collapsible section with progress indicator.

8.4 PHR (Patient Web App) Care Programs Integration

Located in patient/src/features/:

  • Add "My Care Programs" tab displaying:
    • Program Title and Care Team members.
    • Visual progress bar (sessions_completed / total_sessions_planned).
    • Treatment Goals list with progress badges.
    • Upcoming scheduled sessions with quick calendar view.

9. Permissions, Authorization & Security

9.1 Pundit Policy Architecture

All episode operations are gated through the existing policy Clinical::EpisodeOfCarePolicy:

# domains/clinical/policies/episode_of_care_policy.rb
def index?
  tenant_member? && has_any_permission?(:view_episodes, :manage_episodes, :view_patients)
end

def show?
  index? && record_in_tenant?
end

def create?
  tenant_member? && has_any_permission?(:create_episodes, :manage_episodes)
end

def update?
  has_any_permission?(:manage_episodes, :create_episodes) && record_in_tenant?
end

def transition?
  has_any_permission?(:manage_episodes, :create_episodes) && record_in_tenant?
end

9.2 Role-Based Access Control (RBAC) Matrix

ActionAdminStaffPractitionerPatient (PHR)
View Episode Details✅✅✅✅ (Own programs only)
Create Episode✅✅✅❌
Update Episode Metadata✅✅✅❌
Transition Episode Status✅✅✅❌
Link Appointment / Encounter✅✅✅❌
View Treatment Goals✅✅✅✅ (Own goals only)
Create / Update Goals✅✅✅❌
Delete Episode✅❌❌❌

9.3 Multi-Tenant Isolation Enforcement

  1. Every table enforces PostgreSQL Row Level Security (RLS).
  2. Data leaking across tenants is physically blocked at the database engine level via tenant session variables.

10. Re-Baselined Implementation Roadmap

10.1 Phase 1: Database Delta Migrations & Model Extensions

  • Run migration ExtendClinicalEpisodesOfCare (is_integrated_care, total_sessions_planned, etc.).
  • Run concurrent migration AddEpisodeOfCareToAppointments (episode_of_care_id on appointments).
  • Run migration ExtendClinicalTreatmentGoals (progress_percentage, specialty_id).
  • Update Clinical::EpisodeOfCare with integrated care validations and session calculation scopes.
  • Add belongs_to :episode_of_care to Clinical::Appointment.

10.2 Phase 2: Serializer & Linking Service Enhancements

  • Extend Clinical::AppointmentBlueprint (view: :queue) with episode_of_care metadata.
  • Update Queue::GenerateToday#fetch_todays_appointments with .includes(:episode_of_care).
  • Permit :episode_of_care_id in AppointmentsController#appointment_params.
  • Implement LinkEncounterService to keep appointment and encounter episode links in sync.

10.3 Phase 3: CMS Queue & LHR Integration

  • Implement QueueEpisodeBadge and QueueEpisodeFilter in CMS Queue UI.
  • Add "Link to Episode" action dropdown to unlinked queue appointments.
  • Update CMS EpisodeDetailPage to display multi-specialty breakdown charts.
  • Add episode grouping to EncounterHistory component in LHR.

10.4 Phase 4: Patient PHR Care Programs Module

  • Create "My Care Programs" screen in patient web app (patient/).
  • Render program progress bars, goal completion status, and upcoming sessions.
  • Add episode tag to patient appointment cards.

10.5 Phase 5: Verification, Tests & Documentation

  • Add RSpec request specs for episode linking in AppointmentsController.
  • Add RSpec unit specs for Queue::GenerateToday eager loading.
  • Add frontend integration tests for CMS Queue episode filtering.
  • Validate end-to-end multi-specialty session flow in staging environment.

11. Appendices

Appendix A: Codebase File References

Appendix B: FHIR R4 EpisodeOfCare Specification Mapping

  • Standard: HL7 FHIR Release 4 - EpisodeOfCare
  • Mapped fields:
    • identifier -> episodes_of_care.id (UUIDv7)
    • status -> episodes_of_care.status (native enum)
    • type -> episodes_of_care.type (native enum)
    • diagnosis.condition -> episodes_of_care.diagnosis_codes
    • patient -> episodes_of_care.patient_id
    • managingOrganization -> episodes_of_care.facility_id
    • period.start / period.end -> episodes_of_care.period_start / period_end
    • careManager -> episodes_of_care.managing_practitioner_id

On this page

Table of Contents1. Executive Summary & Current Architecture Baseline1.1 Purpose1.2 Architectural Realignment (Codebase Audit)2. Entity Relationships & Data Architecture2.1 High-Level Architecture2.2 Session Lifecycle (Appointment to Encounter)2.3 Complete Entity Relationship Diagram2.4 Multi-Specialty (Integrated Care) Model3. Database Schema & Delta Migrations3.1 Existing Baseline Tables (structure.sql)3.2 Migration: Extend episodes_of_care3.3 Migration: Add episode_of_care_id to appointments3.4 Migration: Extend treatment_goals3.5 Multi-Tenancy & Row Level Security (RLS)4. Episode Lifecycle & State Machine4.1 Status Definitions & FHIR R4 Alignment4.2 Valid Transition MatrixTransition Truth Table4.3 State Transition Methods & Model Logic4.4 Business Rules & Action Matrix5. Appointment & CMS Queue Integration (Maximum Reuse)5.1 Appointment Linking Architecture5.2 Extending AppointmentBlueprint (Zero-New-Endpoint Queue Data)5.3 Performance: Preloading in Queue::GenerateToday5.4 Dual-Sync Rule: Synchronous Appointment-Encounter Linking5.5 Retroactive & Batch Linking Services5.6 CMS Queue UI Integration5.6.1 Queue Row with Episode Badge5.6.2 Queue Filter by Episode6. Multi-Specialty Integrated Care6.1 Single vs Integrated Episode Models6.2 Specialty Quota & Session Distribution6.3 Multi-Specialty Progress Aggregation7. API Surface & Controller Re-use7.1 Existing Clinical Endpoints (To Reuse Directly)7.2 Parameter Extensions on Existing Controllers1. In Clinical::EpisodesOfCareController#episode_params2. In Clinical::AppointmentsController#appointment_params3. In Clinical::TreatmentGoalsController#goal_params7.3 Detailed Endpoint ContractsStatus Transition Contract8. Frontend & UI Integration Strategy8.1 Existing CMS Episode Components (To Reuse & Extend)8.2 CMS Queue Components (Delta Deliverables)8.3 LHR (Provider) View Integration8.4 PHR (Patient Web App) Care Programs Integration9. Permissions, Authorization & Security9.1 Pundit Policy Architecture9.2 Role-Based Access Control (RBAC) Matrix9.3 Multi-Tenant Isolation Enforcement10. Re-Baselined Implementation Roadmap10.1 Phase 1: Database Delta Migrations & Model Extensions10.2 Phase 2: Serializer & Linking Service Enhancements10.3 Phase 3: CMS Queue & LHR Integration10.4 Phase 4: Patient PHR Care Programs Module10.5 Phase 5: Verification, Tests & Documentation11. AppendicesAppendix A: Codebase File ReferencesAppendix B: FHIR R4 EpisodeOfCare Specification Mapping