Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.encoreos.io/llms.txt

Use this file to discover all available pages before exploring further.

Feature ID: CL-46 (publisher) ↔ PM-07 (subscriber) Status: 📝 Planned (pending CL-46 Phase 1 + compliance review) Spec Reference: CL-46-problem-list-management-icd10.md Last Updated: 2026-05-12

Table of Contents


Overview

CL-46 owns the longitudinal patient problem list (ICD-10-CM coded, status-managed: active, resolved, inactive, entered_in_error). Two downstream consumers depend on problem-list state:
  1. CL-08 (Clinical Decision Support) — re-evaluates rules (drug-disease interactions, monitoring, quality-measure gaps) when active problems change.
  2. PM-07 (Encounter Diagnosis Capture / Charge Entry) — pre-populates encounter diagnoses from the patient’s active problem list at encounter creation/check-in, so coders/clinicians do not re-enter chronic conditions.
Integration is event-driven (Pattern 2) for write notifications and read-API (Pattern 1, via @/platform/clinical) for synchronous lookups. No direct core-to-core imports.

Quick Reference

CategoryValue
PublisherCL-46 (cl_problems)
SubscribersCL-08 (CDS re-evaluation), PM-07 (encounter diagnosis pre-population)
Event namecl_problem_list_updated
Channeldomain_events (pg_notify) + fw_workflow_events registry (PF-70/FW-16)
Read APIusePatientActiveProblems(patientId) from @/platform/clinical
Server helpercl_get_patient_active_problems(p_organization_id, p_patient_id) (SECURITY DEFINER, SET search_path = public, pg_catalog)
Idempotency keyproblem_id + action + changed_at
PHI in payloadNone — IDs and ICD-10 code only
Cross-core FKNone (UUID-only reference; ADR-002 exception does not apply here)

Integration Points

DependencyPatternPurpose
PF-70 (Code Libraries)APIICD-10-CM canonical lookup (pf_icd10_codes) for icd10_display resolution
PF-30 (Permissions)APIcl.problems.read gate on usePatientActiveProblems
CL-08 (CDS)EventRe-evaluates active rules on cl_problem_list_updated
PM-07 (Encounter Charges)Event + APISubscribes to event for cache invalidation; calls read API on encounter create/check-in
FW-16 (Workflow Events)APIEvent registered in fw_workflow_events so workflow designers can trigger on problem-list changes

Event Contract: cl_problem_list_updated

Trigger

AFTER INSERT OR UPDATE OF status, icd10_code, resolved_date OR DELETE on cl_problems.

Payload (JSONB)

{
  "event_type": "cl_problem_list_updated",
  "event_version": "1.0.0",
  "occurred_at": "2026-05-12T18:42:11.123Z",
  "organization_id": "uuid",
  "payload": {
    "patient_id": "uuid",
    "problem_id": "uuid",
    "icd10_code": "F33.1",
    "action": "added | status_changed | resolved | reactivated | corrected | removed",
    "previous_status": "active | resolved | inactive | entered_in_error | null",
    "new_status": "active | resolved | inactive | entered_in_error | null",
    "changed_by": "uuid",
    "changed_at": "2026-05-12T18:42:11.000Z"
  }
}
No PHI in payload. Patient name, DOB, narrative description are deliberately excluded; subscribers fetch via the read API under their own RLS context.

Action mapping

DB changeaction
INSERTadded
UPDATE status active → resolvedresolved
UPDATE status resolved/inactive → activereactivated
UPDATE status * → entered_in_errorcorrected
UPDATE icd10_code (status unchanged)status_changed (code revision)
DELETE (hard delete; rare — soft via entered_in_error preferred)removed

Subscribers

SubscriberAction
CL-08Invalidate ['cds-alerts', patient_id]; re-run drug-disease and quality-measure rules
PM-07Invalidate ['encounter-diagnoses-suggestions', patient_id]; if an in-progress encounter exists, surface a “problem list updated” banner

Cross-Core Read API

PM-07 (and any other consumer) MUST use the platform integration layer rather than querying cl_problems directly.
// src/platform/clinical/index.ts (re-export)
export { usePatientActiveProblems } from '@/platform/clinical/hooks/usePatientActiveProblems';

// Consumer (PM-07 charge capture)
import { usePatientActiveProblems } from '@/platform/clinical';

const { data: problems, isLoading } = usePatientActiveProblems(patientId);
// problems: Array<{ problem_id, icd10_code, icd10_display, onset_date, priority }>
Server-side / edge functions call the SECURITY DEFINER helper:
SELECT * FROM cl_get_patient_active_problems(p_organization_id := $1, p_patient_id := $2);
The helper enforces pf_has_org_access(organization_id) and the cl.problems.read permission, returns only status = 'active' rows, and orders by priority ASC NULLS LAST, onset_date DESC.

Security and RLS

  • cl_problems has RLS enabled with FORCE ROW LEVEL SECURITY; all CRUD policies scope by organization_id via cl_user_has_problem_permission(action).
  • Cross-core reads from PM-07 execute under the calling user’s auth context — RLS still applies. The SECURITY DEFINER helper does not bypass tenant scoping; it only avoids the need for PM code to know CL table internals.
  • Event payload contains no PHI; consumers MUST re-fetch via the read API to obtain ICD-10 display text or clinician description.
  • Status state-machine enforcement (e.g., entered_in_error is terminal) is implemented in a BEFORE UPDATE trigger on cl_problems, not in the RLS WITH CHECK clause (which has no access to OLD).

Idempotency, Retry, and Ordering

  • Idempotency key: problem_id || ':' || action || ':' || changed_at (ISO-8601, millisecond precision). Subscribers MUST de-duplicate using this key for at least 24 h.
  • Ordering: Not strictly guaranteed across the domain_events channel. Subscribers MUST treat events as state notifications (re-fetch on receipt) rather than authoritative deltas.
  • Retry: PF event dispatcher retries with exponential backoff (per PF-70 event publishing standards). Failed deliveries land in the dead-letter queue after 5 attempts.
  • Backfill: On subscriber outage recovery, consumers may call the read API to reconcile state; no replay of historical events is provided.

Failure Modes

FailureBehavior
Event publish fails (pg_notify error)Logged via PF observability; the originating CL mutation still commits. Reconciliation via PM-07 calling the read API on next encounter open.
Subscriber RLS denial on read APIHook returns empty array; PM-07 falls back to manual diagnosis entry; no PHI leak.
ICD-10 code not in PF-70icd10_display returns the raw code; UI surfaces an “unmapped code” warning (non-blocking).
Race: encounter created milliseconds before problem addPM-07 banner refresh on event receipt; coder can re-pull suggested diagnoses.