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:
- CL-08 (Clinical Decision Support) — re-evaluates rules (drug-disease interactions, monitoring, quality-measure gaps) when active problems change.
- 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
| Category | Value |
|---|
| Publisher | CL-46 (cl_problems) |
| Subscribers | CL-08 (CDS re-evaluation), PM-07 (encounter diagnosis pre-population) |
| Event name | cl_problem_list_updated |
| Channel | domain_events (pg_notify) + fw_workflow_events registry (PF-70/FW-16) |
| Read API | usePatientActiveProblems(patientId) from @/platform/clinical |
| Server helper | cl_get_patient_active_problems(p_organization_id, p_patient_id) (SECURITY DEFINER, SET search_path = public, pg_catalog) |
| Idempotency key | problem_id + action + changed_at |
| PHI in payload | None — IDs and ICD-10 code only |
| Cross-core FK | None (UUID-only reference; ADR-002 exception does not apply here) |
Integration Points
| Dependency | Pattern | Purpose |
|---|
| PF-70 (Code Libraries) | API | ICD-10-CM canonical lookup (pf_icd10_codes) for icd10_display resolution |
| PF-30 (Permissions) | API | cl.problems.read gate on usePatientActiveProblems |
| CL-08 (CDS) | Event | Re-evaluates active rules on cl_problem_list_updated |
| PM-07 (Encounter Charges) | Event + API | Subscribes to event for cache invalidation; calls read API on encounter create/check-in |
| FW-16 (Workflow Events) | API | Event 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 change | action |
|---|
| INSERT | added |
UPDATE status active → resolved | resolved |
UPDATE status resolved/inactive → active | reactivated |
UPDATE status * → entered_in_error | corrected |
UPDATE icd10_code (status unchanged) | status_changed (code revision) |
DELETE (hard delete; rare — soft via entered_in_error preferred) | removed |
Subscribers
| Subscriber | Action |
|---|
| CL-08 | Invalidate ['cds-alerts', patient_id]; re-run drug-disease and quality-measure rules |
| PM-07 | Invalidate ['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
| Failure | Behavior |
|---|
| 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 API | Hook returns empty array; PM-07 falls back to manual diagnosis entry; no PHI leak. |
| ICD-10 code not in PF-70 | icd10_display returns the raw code; UI surfaces an “unmapped code” warning (non-blocking). |
| Race: encounter created milliseconds before problem add | PM-07 banner refresh on event receipt; coder can re-pull suggested diagnoses. |