> ## 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.

# Intake Screening & Triage Workflow — Integration Documentation

> Status: ✅ Complete Last Updated: 2026-03-28

**Spec:** [CE-28](../../../specs/ce/specs/CE-28-intake-screening-triage-workflow.md)
**Status:** ✅ Complete
**Last Updated:** 2026-03-28

***

## Overview

CE-28 formalizes the intake screening workflow between lead inquiry (CE-01) and patient admission. This integration document covers the event contracts, data flow, and cross-core dependencies for screening-driven automation.

***

## Event Contracts

### 1. `ce_screening_completed`

**Publisher:** CE-28 (Intake Screening)
**Subscribers:** FW-16 (workflow engine), PM-38 (appointment automation), PM-39 (waitlist), CE-29 (conversion pipeline)

**Trigger:** After `ce_screening_attempts` INSERT with a non-null disposition (consent-gated — `consent_obtained` must be `true`).

**Payload Schema:**

```typescript theme={null}
{
  event_id: uuid;
  source: 'ce-28';
  timestamp: string; // ISO 8601
  correlation_id: uuid;
  organization_id: uuid;
  data: {
    screening_id: uuid;
    lead_id: uuid;
    disposition: 'proceed' | 'waitlist' | 'refer_out' | 'decline';
    clinical_flags: string[]; // Predefined flag codes only; no free-text PHI
    asam_score: number | null;
    recommended_level_of_care: string | null;
    needs_clinical_escalation: boolean;
    screener_id: uuid;
    screening_date: string; // ISO 8601
    program_type: 'residential' | 'iop' | 'php' | 'outpatient';
    sla_status: 'on_time' | 'missed';
  };
}
```

**Downstream Behavior by Disposition:**

| Disposition               | Action                            | Subscriber            |
| ------------------------- | --------------------------------- | --------------------- |
| `proceed` (bed available) | Auto-create intake appointment    | PM-38                 |
| `proceed` (no bed)        | Route to waitlist                 | PM-39                 |
| `waitlist`                | Add to waitlist queue             | PM-39                 |
| `refer_out`               | Log referral, suggest alternative | CE-04 (activity)      |
| `decline`                 | Close lead with reason            | CE-01 (status update) |

### 2. `ce_lead_waitlisted`

**Publisher:** CE-28 (conditional — emitted when disposition = 'proceed' but bed unavailable)
**Subscribers:** PM-39 (waitlist management)

**Payload Schema:**

```typescript theme={null}
{
  event_id: uuid;
  source: 'ce-28';
  timestamp: string;
  correlation_id: uuid;
  organization_id: uuid;
  data: {
    lead_id: uuid;
    screening_id: uuid;
    program_type: string;
    reason: 'no_bed_available';
  };
}
```

***

## Data Flow

```text theme={null}
CE-01 (Lead inquiry)
  ↓
CE-28 (Screening)
  ├── ce_screening_attempts (disposition recorded)
  ├── ce_screening_results (questionnaire responses, ASAM score)
  └── Events published:
      ├── ce_screening_completed → FW-16, PM-38, PM-39, CE-29
      └── ce_lead_waitlisted → PM-39 (conditional)
          ↓
CE-29 (Lead-to-Patient Conversion)
  ├── ce_lead_converted_to_patient → PM-01
  └── ce_lead_converted_to_resident → RH-01
```

***

## Cross-Core Dependencies

| Dependency                | Direction  | Pattern                              | Notes                                  |
| ------------------------- | ---------- | ------------------------------------ | -------------------------------------- |
| CE-01 → CE-28             | Upstream   | Data (FK: `lead_id`)                 | Screening operates on CE-01 leads      |
| CE-28 → PM-38             | Downstream | Event (`ce_screening_completed`)     | Appointment auto-creation              |
| CE-28 → PM-39             | Downstream | Event (`ce_lead_waitlisted`)         | Waitlist routing                       |
| CE-28 → CE-29             | Downstream | Event (`ce_screening_completed`)     | Conversion pipeline trigger            |
| CE-28 → RH-01             | Query      | API/Query (bed availability)         | Real-time bed check before disposition |
| CE-28 → PM-42             | Read       | Data (query `ce_screening_attempts`) | Screening queue in workbench           |
| CE-28 → PM-41             | Read       | Data (query screening metrics)       | Funnel analytics                       |
| CE-28-ENH (EN-01) → PF-83 | Downstream | Event (`ce_crisis_alert_created`)    | Crisis SLA timer start                 |
| CE-28-ENH (EN-01) → PF-10 | Downstream | Event (`ce_crisis_alert_created`)    | On-call paging                         |
| CE-28-ENH (EN-01) → CE-29 | Downstream | Event (`ce_crisis_alert_created`)    | Conversion-pipeline crisis hand-off    |

***

## Platform Integration Layers Used

* **PF-10 (Notifications):** `@/platform/notifications` — SLA miss alerts
* **PF-30 (RBAC):** Permission keys `ce.screening.*`
* **FW-16 (Workflow):** Event publishing via `publishEvent()` platform layer

***

## Security Considerations

* All tables enforce RLS with `organization_id` tenant isolation
* PHI present in screening data (substance use, clinical flags) — encrypted at rest
* **42 CFR Part 2 consent gating (SUD-related screening):** Before publishing any workflow/event payload that includes SUD-related screening data, implementations MUST verify on `ce_screening_attempts` that **`consent_obtained` is true**, **`consent_method`** is populated (per org policy / valid enum), and **`consent_recorded_at`** is set. These fields are the authoritative implementation mechanism for consent capture at the point of screening.
* **Event metadata for audit:** Published events that include SUD-related screening content MUST include **`consent_recorded_at`** (ISO-8601 timestamp) in **event metadata** (alongside correlation/event IDs) so downstream subscribers (PM-38, CE-29, analytics) can prove consent timing for audit and Part 2 tracking.
* Consent capture (`consent_obtained`, `consent_method`, `consent_recorded_at`) on `ce_screening_attempts` — all three are required for gated publish paths above

***

## TODO

* [x] Finalize `ce_screening_completed` event contract with PM-38 team — implemented in `useCreateScreening.ts`; payload matches schema above; consent-gated per 42 CFR Part 2
* [x] Confirm RH-01 bed availability query mechanism (event vs API) — Phase 1: placeholder `bedAvailable` boolean in `CreateScreeningInput`; `ce_lead_waitlisted` published when `proceed` + no bed; RH-01 real-time query deferred to Phase 2
* [x] Coordinate CE-29 conversion trigger from screening disposition — `mapScreeningToPatient()` in `@/platform/ce/` maps screening fields to PM patient shape; CE-29 event-consumer already handles conversion

***

## CE-28-ENHANCEMENTS — Crisis Alert Event (EN-01)

**Status:** 📋 Specification (CE-28-ENHANCEMENTS EN-01).
**Event:** `ce_crisis_alert_created` (registered in `EVENT_CONTRACTS.md`).

### Trigger

Published by CE when a crisis is detected on inbound intake (SMS, web-form, or — Phase 2 — call transcript) and a `ce_crisis_alerts` row is inserted. Detection paths:

* **Phase 1 (no CE-37/CE-35):** Keyword-only matcher on inbound SMS (CE-08) and web-form (CE-10) bodies.
* **Phase 2:** Adds CE-37 intent-classification model and CE-35 transcription stream analysis.

### Payload (PHI-free)

| Field                  | Type         | Notes                                                        |
| ---------------------- | ------------ | ------------------------------------------------------------ |
| `alert_id`             | uuid         | `ce_crisis_alerts.id`                                        |
| `org_id`               | uuid         | Tenant scope                                                 |
| `source_kind`          | text         | `sms` \| `web_form` \| `call_transcript` \| `keyword_manual` |
| `confidence_tier`      | text         | `tier_1` (page) \| `tier_2` (queue only)                     |
| `contact_id`           | uuid         | `ce_contacts.id`                                             |
| `screening_attempt_id` | uuid \| null | Set when alert occurs during an active screening             |
| `created_at`           | timestamptz  | Detection time                                               |

**Excluded by design:** detected keywords, evidence excerpts, narrative content, member identifiers, model output text. PHI redaction is applied at insert time on `ce_crisis_alerts`; the event payload references IDs only.

### Subscribers

| Subscriber                      | Reason                        | Action                                                     |
| ------------------------------- | ----------------------------- | ---------------------------------------------------------- |
| **PF-83 (SLA platform)**        | Start tier-specific SLA timer | Tier-1: 60 s page deadline; Tier-2: 5-min triage-queue SLA |
| **PF-10 (Notifications)**       | On-call paging                | Tier-1 only; routes via on-call rotation (EN-02)           |
| **CE-29 (Conversion Pipeline)** | Crisis-aware hand-off         | Flags lead/contact for clinical hand-off; pipeline metrics |
| **CE-28 triage queue UI**       | Realtime queue update         | Inserts row into coordinator queue view                    |

### Consent / 42 CFR Part 2

`ce_crisis_alert_created` is published even when SUD-related screening consent (`consent_obtained`) has not been captured, in reliance on the **42 CFR Part 2 §2.51 medical-emergency exception**. The payload contains no SUD content (IDs only); any downstream subscriber that loads PHI from `ce_crisis_alerts` MUST log the §2.51 invocation per `ce_crisis_alerts.outcome` review trail.

### Ordering / Idempotency

* One event per `ce_crisis_alerts` insert. Re-classification updates do not re-publish; subscribers should treat `alert_id` as the idempotency key.
* Subscribers must tolerate at-least-once delivery.
