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.

Version: 2.2.2
Last Updated: 2026-05-18
Change Note: Added six BHRF (A.A.C. R9-10-701..722) lifecycle event contracts for CL-68 / GR-27 / PM-74 (rh_resident_admitted BHRF-filtered, cl_bhrf_loc_determined, cl_bhrf_clinical_assessment_completed, pm_bhrf_continued_stay_review_required, gr_bhrf_compliance_finding_raised, pm_residential_charge_held) with R7 retry alignment and coded (non-free-text) hold_reason. Prior: added explicit “no events” entry for CL-31; cl_referral_status_updated (CL-12-EN-67) on cl_events. Constitution Reference: Section 1.3 (Integration Patterns - Pattern 2)
Event-based integration enables loose coupling between cores via domain events. Events are published using PostgreSQL pg_notify and consumed via database triggers or edge functions.

Event Schema Standard

All events MUST follow this structure:
interface DomainEvent {
  event: string;              // Event name (e.g., 'rh_resident_admitted')
  publisher: string;           // Core that publishes (e.g., 'RH')
  subscriber: string[];        // Cores that subscribe (e.g., ['FA', 'HR'])
  payload: Record<string, any>; // Event-specific data
  metadata: {
    organization_id: uuid;
    site_id?: uuid;
    user_id: uuid;
    timestamp: timestamp;
    correlation_id?: uuid;
  };
}

RH lifecycle events: canonical names & persistence (FW-16)

Canonical names match KnownEventName in src/platform/events/types.ts and rows in fw_workflow_events / inserts into fw_domain_events:
Legacy / doc alias (deprecated)Canonical event_namefw_domain_events.event_source (trigger)Source table / condition
resident_admittedrh_resident_admittedtrigger_rh_episodes_domain_eventsrh_episodesstatus transitions to admitted
resident_dischargedrh_resident_dischargedtrigger_rh_episodes_domain_eventsrh_episodesstatus transitions to discharged
phase_progressed / rh_phase_changed (draft)rh_phase_advancedtrigger_rh_episode_phases_phase_advancedrh_episode_phases — row becomes current phase
bed_assigned (planned registry)rh_bed_assigned ✅ (now in KnownEventName)PlannedBed assignment mutation — add when HR consumer is scheduled
bed_released (planned registry)rh_bed_released ✅ (now in KnownEventName)PlannedBed release mutation
invoice_creation_requestedrh_invoice_creation_requested ✅ (now in KnownEventName)PlannedInvoice creation request — align with FA consumer story to avoid duplicate invoicing
Realtime: Consumers should read fw_domain_events (and FW-16 automation) as the source of truth. A dedicated pg_notify channel (e.g. rh_events) is optional and must not diverge from persisted domain events.

Status Legend

  • Implemented - Fully implemented and tested
  • 📝 Planned - Specified but not yet implemented
  • 🟡 In Progress - Partially implemented

Canonical Event Channels

Use these channels when documenting or implementing events. New events must use the channel for their owning core. Reference this table from specs/_templates/INTEGRATION_CONTRACT_TEMPLATE.md when defining event contracts.
ChannelOwning Core(s)Purpose
domain_eventsPF / generalGeneral lifecycle events, HR-style events when no dedicated channel
automation_triggerFWForm submission/update events (FW-03)
fw_eventsFWForms & workflow events (external form submitted, approval submitted/completed)
fa_eventsFAFinance events (journal posting, payments, budgets, consolidations)
hr_eventsHRHR lifecycle (credentials, onboarding, offboarding, performance)
it_eventsITIT asset, license, ticket, vendor, procurement events
lo_eventsLOLeadership (rocks, todos, meetings, issues)
cl_pm_eventsCL, PMCL/PM cross-core (break-glass, eligibility, check-in, lab orders)
cl_eventsCLCL clinical events (note finalized, assessment, group session)
pm_eventsPMPM practice management (eligibility, appointments, claims)
pm_rpa_eventsPMPM-51 RPA automation events (execution completed, consecutive failures)
rh_eventsRHRecovery housing events (resident admission, discharge, census, episodes)
gr_eventsGRGovernance (incidents, audits)
org_data_changesPFPF-18 org data sync events (department/site changes triggering cross-module propagation)
Event naming: For new events, use the canonical format {core}_{entity}_{action} (e.g. hr_employee_hired, cl_assessment_completed). Existing events may use the legacy dotted pattern (e.g. hr.benefit_enrollment.created). PM-51 RPA naming exception: The PM-51 RPA events (pm.rpa.execution_completed, pm.rpa.consecutive_failures) use dotted naming as approved for this feature. This is an explicit exception to the standard underscore convention for backward compatibility with the RPA automation system. New PM events outside of PM-51 should follow the standard pm_{entity}_{action} format. See INTEGRATION_CONTRACT_TEMPLATE.md § Event Naming Conventions.

Event Delivery Mechanism

Canonical guide: EVENT_DELIVERY.md — how to choose table-driven vs HTTP consumer vs realtime vs external webhooks. Current Implementation (✅ Complete):
  • Events published via PostgreSQL pg_notify to dedicated channels:
    • domain_events - HR lifecycle events (credentials, onboarding, offboarding)
    • automation_trigger - FW form submission/update events
    • fa_events - FA financial events (journal posting, payments, budgets, consolidations)
    • it_events - IT module events (ticket created, contract/license expiring, asset assigned, purchase request submitted/approved)
    • lo_events - LO leadership events (rocks, todos, meetings, issues)
    • cl_pm_events - Active channel for CL/PM cross-core events (CL-01 break-glass, PM eligibility, appointment check-in to CL-04, CL-09 lab orders/results) — ✅ Active for CL-01, PM, and CL-09 integration events
    • cl_events - CL clinical events (note finalized, assessment completed, group session completed) — 📝 Reserved for CL-02+ internal events; not yet in use
    • pm_events - PM practice management events (eligibility verified) — 📝 Planned; channel reserved for PM-02+
  • Subscribers consume via edge functions that listen to pg_notify
  • Events include full organization context for multi-tenant isolation
  • All events logged to pf_audit_logs for permanent audit trail
  • Event consumer edge function: supabase/functions/event-consumer/index.ts
  • Automation executor edge function: supabase/functions/automation-executor/index.ts
Event Flow:
Database Trigger → publish_domain_event() → pg_notify(channel, payload)
  → Edge Function Listener → Process Event → Log to Audit
  → Future: Trigger Notifications/Automations/Webhooks
Security:
  • All events include organization_id for tenant isolation
  • Edge functions run with service role (no JWT verification)
  • Event payloads logged for security audit
  • No sensitive data (passwords, SSNs) in event payloads
Idempotency and Retry (R7):
  • Idempotency keys: All event payloads MUST include a unique event_id (uuid); workflow executions MUST use execution_id as the idempotency key. Handlers in event-consumer and automation-executor MUST record processed keys and skip duplicates (e.g. check fw_workflow_executions or a processed-events table before performing side effects).
  • Retry/backoff: On transient failure (5xx, timeout), retry with exponential backoff (e.g. 1s, 2s, 4s, max 3 retries). Do not retry on 4xx (except 429).
  • Duplicate detection: When invoked more than once (retry, at-least-once delivery), handlers MUST detect already-processed event_id or execution_id and return success without re-executing; never create duplicate charges, notifications, or workflow steps.

PHI-Safe Payload Guidance

For PF-10/PF-11 workflows and PM-16-style billing communications, payloads must be identifier-only:
  • Allowed: system-generated UUIDs (organization_id, patient_id, statement_id, etc.)
  • Disallowed: patient names, MRNs, DOBs, account numbers, or narrative PHI fields
  • Resolve display details only through authorized API/UI lookups after permission/RLS validation
  • Use PM-16 integration guidance as the reference implementation pattern
Future Enhancements:
  • Event bus for higher throughput (Redis, RabbitMQ, Kafka)
  • Event replay for debugging and recovery
  • Event versioning for schema evolution
  • Circuit breaker for failing event handlers
  • Dead letter queue for failed events
  • Event aggregation and analytics

Supabase Realtime channel contracts

Channel contracts for Supabase Realtime (broadcast/presence) are documented here when they define cross-cutting semantics or multi-tenant rules. Implementations must enforce authorization at channel subscription time and align with RLS on application tables.

PF-73: Swim Lane Diagram collaborative realtime channel \

Owner: PF-73 (Workflow Builder with Swim Lane Visualization)
Status: ✅ Implemented (Phase 2.2)
Spec: PF-73-workflow-builder-swim-lane-visualization.md
Implemented: 2026-03-14
Hooks:
  • useDiagramPresence(orgId, diagramId) — wraps useRealtimePresence from @/platform/realtime
  • useDiagramBroadcast(orgId, diagramId) — wraps useRealtimeBroadcast; event diagram_updated
Broadcast payload:
interface DiagramBroadcastPayload {
  type: 'diagram_updated';
  version: number;
  userId: string;
  displayName: string;
  timestamp: string;
}
Channel schema: org:{orgId}:diagram:{diagramId} — composite key; never use diagram id alone (prevents cross-tenant leakage). Semantics: subscribe, broadcast, and presence (track) are allowed only after channel-level authorization. Authorization MUST be performed at channel subscription time (before allowing subscribe(), broadcast(), or track()/presence), not solely via RLS on application tables. Multi-tenant verification rules:
  • Org-scoped auth: Verify the requester belongs to orgId (e.g. via pf_has_org_access(organization_id, auth.uid())) before allowing join, broadcast, or presence on that channel.
  • RLS: Diagram and version tables remain org-scoped; require RLS policies on realtime.messages (where applicable) plus an explicit server/edge check that verifies the requester belongs to orgId.
  • Documentation: Channel-level checks and required RLS/auth checks are documented in CROSS_CORE_INTEGRATIONS.md and PF-73-workflow-builder-swim-lane-INTEGRATION.md.

Implemented Events

FW-03: Form Submission Events

Event: automation_trigger (form_submitted / form_updated)
Publisher: FW (Forms & Workflow)
Subscribers: FW-03 Automation Engine
Status: ✅ Complete
Implemented: 2025-11-25
Payload Schema:
{
  trigger_type: 'form_submitted' | 'form_updated';
  submission_id: uuid;
  form_id: uuid;
  organization_id: uuid;
  site_id?: uuid;
  submitted_by: uuid;
  submission_data: Record<string, any>;
  old_status?: submission_status;  // Only for updates
  new_status: submission_status;
}
Implementation:
CREATE TRIGGER trigger_automation_on_submission
AFTER INSERT OR UPDATE ON fw_form_submissions
FOR EACH ROW
EXECUTE FUNCTION trigger_automation_on_submission();
Consumer: supabase/functions/automation-executor/index.ts
  • Listens to automation_trigger channel via pg_notify
  • Fetches matching automation rules
  • Evaluates conditions
  • Executes actions (email, notification, webhook, record update)
  • Logs execution to fw_automation_logs
Testing: ✅ Complete - All test cases passed

HR-02: Credential Management Events

Event 1: hr_credential_expired (canonical)
Legacy alias (deprecated): credential_expired — maintained for backward compatibility but should migrate to canonical name
Publisher: HR (Workforce)
Subscribers: Event Consumer (audit logging), HR-04 (Scheduling)
Status: ✅ Complete
Implemented: 2025-11-25
Payload Schema:
{
  event_type: 'hr_credential_expired'; // Canonical name; legacy 'credential_expired' deprecated
  employee_id: uuid;
  credential_id: uuid;
  credential_type_id: uuid;
  expiration_date: date;
  organization_id: uuid;
  timestamp: timestamptz;
}
Implementation:
CREATE TRIGGER trigger_credential_expired
AFTER UPDATE ON hr_employee_credentials
FOR EACH ROW
WHEN (NEW.expiration_date < CURRENT_DATE AND 
      (OLD.expiration_date IS NULL OR OLD.expiration_date >= CURRENT_DATE))
EXECUTE FUNCTION publish_credential_expired();
-- Note: Function should publish as 'hr_credential_expired' (canonical), legacy name maintained for backward compatibility
Event 2: hr_credential_verified (canonical)
Legacy alias (deprecated): credential_verified — maintained for backward compatibility but should migrate to canonical name
Payload Schema:
{
  event_type: 'hr_credential_verified'; // Canonical name; legacy 'credential_verified' deprecated
  employee_id: uuid;
  credential_id: uuid;
  credential_type_id: uuid;
  verified_by: uuid;
  verified_at: timestamptz;
  organization_id: uuid;
  timestamp: timestamptz;
}
Implementation:
CREATE TRIGGER trigger_credential_verified
AFTER UPDATE ON hr_employee_credentials
FOR EACH ROW
WHEN (NEW.verification_status = 'verified' AND OLD.verification_status != 'verified')
EXECUTE FUNCTION publish_credential_verified();
-- Note: Function should publish as 'hr_credential_verified' (canonical), legacy name maintained for backward compatibility
Consumer: supabase/functions/event-consumer/index.ts
  • Logs all events to pf_audit_logs
  • Future handlers ready for notifications and alerts
HR-04 Integration (Credential Blocking):
  • HR-04 Scheduling subscribes to hr_credential_expired events (canonical; legacy credential_expired alias supported for backward compatibility)
  • When credential expires, employee is automatically blocked from shift assignment
  • Blocking prevents scheduling until credential is renewed and verified
  • Integration documented in HR-04 spec (Scheduling & Capacity)
Implementation in HR-04:
-- HR-04: Block employee from scheduling when credential expires
CREATE OR REPLACE FUNCTION hr_block_employee_on_credential_expiry()
RETURNS TRIGGER AS $$
BEGIN
  -- Update employee scheduling eligibility
  UPDATE hr_employees
  SET scheduling_blocked = true,
      scheduling_block_reason = 'credential_expired', // Uses legacy event name for backward compatibility
      scheduling_blocked_at = now()
  WHERE id = NEW.employee_id
    AND organization_id = NEW.organization_id;
  
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

-- Subscribe to credential_expired events via edge function
-- Location: supabase/functions/hr-scheduling-credential-listener/index.ts
Testing: ✅ Complete - Events fire correctly on status changes

HR-03: Onboarding & Offboarding Events

Status: ✅ Complete (base events), 📝 Planned (IT trigger events)
Implemented: 2025-11-25 (base), 2026-01-02 (IT triggers spec)

Completion Events (✅ Implemented)

Event 1: hr_onboarding_completed (canonical name; legacy alias onboarding_completed)
Publisher: HR (Workforce)
Subscribers: Event Consumer (audit logging)
Payload Schema:
{
  event_type: 'hr_onboarding_completed'; // legacy: 'onboarding_completed'
  employee_id: uuid;
  onboarding_instance_id: uuid;
  completed_at: timestamptz;
  organization_id: uuid;
  timestamp: timestamptz;
}
Event 2: offboarding_completed
Payload Schema:
{
  event_type: 'offboarding_completed';
  employee_id: uuid;
  offboarding_instance_id: uuid;
  completed_at: timestamptz;
  termination_type: termination_type;
  organization_id: uuid;
  timestamp: timestamptz;
}

IT Trigger Events (📝 Planned - IT-08 Integration)

These events trigger IT-08 IT Onboarding/Offboarding workflows. Event 3: hr_onboarding_started
Publisher: HR (Workforce)
Subscribers: IT-08 (IT Provisioning)
Trigger: INSERT on hr_onboarding_instances
Payload Schema:
{
  event_type: 'hr_onboarding_started';
  employee_id: uuid;
  onboarding_instance_id: uuid;
  template_id: uuid;
  start_date: date;
  is_clinical: boolean;
  organization_id: uuid;
  timestamp: timestamptz;
}
Event 4: hr_onboarding_task_created
Publisher: HR (Workforce)
Subscribers: IT-08 (IT Task Instance)
Trigger: INSERT on hr_onboarding_task_instances WHERE category = ‘it_setup’
Payload Schema:
{
  event_type: 'hr_onboarding_task_created';
  task_instance_id: uuid;
  onboarding_instance_id: uuid;
  employee_id: uuid;
  category: 'it_setup';
  title: string;
  due_date: date;
  organization_id: uuid;
  timestamp: timestamptz;
}
Event 5: hr_offboarding_started
Publisher: HR (Workforce)
Subscribers: IT-08 (IT Offboarding)
Trigger: INSERT on hr_offboarding_instances
Payload Schema:
{
  event_type: 'hr_offboarding_started';
  employee_id: uuid;
  offboarding_instance_id: uuid;
  termination_date: date;
  termination_type: 'voluntary' | 'involuntary' | 'retirement' | 'end_contract';
  organization_id: uuid;
  timestamp: timestamptz;
}
Event 6: hr_offboarding_task_created
Publisher: HR (Workforce)
Subscribers: IT-08 (IT Access Revocation)
Trigger: INSERT on hr_offboarding_checklist_items WHERE category = ‘access_revocation’
Payload Schema:
{
  event_type: 'hr_offboarding_task_created';
  checklist_item_id: uuid;
  offboarding_instance_id: uuid;
  employee_id: uuid;
  category: 'access_revocation';
  title: string;
  organization_id: uuid;
  timestamp: timestamptz;
}
Consumer: supabase/functions/event-consumer/index.ts
  • Logs all events to pf_audit_logs
  • IT-08 handlers create corresponding IT provisioning/offboarding instances
Testing: ✅ Complete (base events) - Events published on workflow completion

HR-31: Policy Acknowledgment Events — ⛔ ARCHIVED

⛔ DEPRECATED (2026-03-26): HR-31 has been consolidated into GR-01. The HR-31 tables (hr_policies, hr_policy_distributions, hr_policy_acknowledgments) were dropped in migration 20260326034722. These event contracts are retained for historical reference only.
Status: ⛔ Archived — consolidated into GR-01
Spec: HR-31 (deprecated)
Integration: HR-31 Integration (archived)

Event 1: hr_policy_acknowledgment_completed (archived)

Publisher: HR-31 (dropped)
Subscribers: None (historical only — no active subscribers)
Payload Schema (historical):
{
  event_type: 'hr_policy_acknowledgment_completed';
  acknowledgment_id: uuid;
  employee_id: uuid;
  policy_id: uuid;
  distribution_id: uuid;
  organization_id: uuid;
  acknowledged_at: timestamptz;
  timestamp: timestamptz;
}
Idempotency: (organization_id, acknowledgment_id)

Event 2: hr_policy_distribution_created (archived)

Publisher: HR-31 (dropped)
Subscribers: None (historical only — no active subscribers)
Payload Schema (historical):
{
  event_type: 'hr_policy_distribution_created';
  distribution_id: uuid;
  policy_id: uuid;
  policy_title: string;
  employee_ids: uuid[];
  deadline_date: date;
  organization_id: uuid;
  timestamp: timestamptz;
}
Idempotency: (organization_id, distribution_id)

Consumer: hr_onboarding_completed → HR-31 (archived)

Archived: HR-31 previously consumed hr_onboarding_completed (HR-03) to create new-hire policy packet distributions. This consumer was removed when HR-31 was consolidated into GR-01. GR-01 now handles policy acknowledgment workflows directly.

HR-05: Time & Attendance Exception Events

Status: ✅ Implemented
Implemented: 2026-03-09

Event 1: hr_timesheet_exception_created

Publisher: HR (DB trigger on hr_time_exceptions)
Subscribers: time-exception-notify edge function → PF-10 (in-app notification)
Channel: hr_events
Trigger: INSERT on hr_time_exceptions
Payload Schema:
interface HrTimesheetExceptionCreatedPayload {
  event_type: 'hr_timesheet_exception_created';
  exception_id: string;       // UUID
  employee_id: string;        // UUID
  exception_type: string;
  exception_date: string;     // ISO date
  organization_id: string;    // UUID — required for tenant isolation
  site_id?: string;           // UUID — optional site context
  timestamp: string;          // ISO 8601 timestamptz
  correlation_id?: string;    // UUID — optional for tracing
}
Consumer: supabase/functions/time-exception-notify/index.ts
  • Resolves manager via hr_employees.manager_id
  • Creates in-app notification via createNotificationIfNew() (dedup by reference)
  • Notification type: timesheet_exception
  • Auth gate: validates Authorization header before processing

HR-10: Performance Management Events

Status: ✅ Implemented
Implemented: 2026-01-13 (Event 1), 2026-01-12 (Event 3)

Event 1: performance_review_completed

Publisher: HR (Workforce)
Subscribers: LO-03 (Goals), HR-15 (Compensation), HR-16 (Succession Planning)
Status: ✅ Implemented (2026-01-13)
Payload Schema:
{
  event_type: 'performance_review_completed';
  review_id: uuid;
  employee_id: uuid;
  reviewer_id: uuid;
  overall_rating: 'exceeds_expectations' | 'meets_expectations' | 'below_expectations';
  review_period_start: date;
  review_period_end: date;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Notify other systems of completed reviews for goal alignment, compensation planning, succession planning Implementation:
CREATE TRIGGER trigger_performance_review_completed
  AFTER UPDATE ON public.hr_performance_reviews
  FOR EACH ROW
  EXECUTE FUNCTION public.hr_trigger_performance_review_completed();

Event 2: performance_goal_completed

Publisher: HR (Workforce)
Subscribers: LO-03 (Goals)
Status: 📝 Planned
Payload Schema:
{
  event_type: 'performance_goal_completed';
  goal_id: uuid;
  employee_id: uuid;
  organizational_goal_id: uuid | null;
  status: 'completed' | 'not_met';
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Update organizational goal progress when employee goals complete

Event 3: hr_pip_terminated

Publisher: HR (Workforce)
Subscribers: HR-03 (Offboarding), HR-14 (Employee Relations)
Status: ✅ Implemented (2026-01-12)
Payload Schema:
{
  event_type: 'hr_pip_terminated';
  pip_id: uuid;
  employee_id: uuid;
  organization_id: uuid;
  disciplinary_action_id: uuid;  // Created HR-14 record
  final_assessment: string;
  terminated_at: timestamptz;
}
Purpose: Trigger employee relations case and potential offboarding when PIP fails Implementation:
  • Hook: src/cores/hr/hooks/performance/usePIPTerminationIntegration.ts
  • Event registered in: fw_workflow_events table
  • Triggered by: usePIPMutation.completePIP() when outcome is ‘unsuccessful’
  • Creates: hr_disciplinary_actions record with action_type: 'termination'
  • UI Warning: PIPCompleteDialog.tsx shows warning for unsuccessful outcome
Consumer Actions:
  1. Creates disciplinary action record in HR-14
  2. Publishes hr_pip_terminated event for workflow automation
  3. Future: Triggers HR-03 offboarding workflow via automation rules

HR-11 / HR-PAY-02: Benefit Enrollment Events (Payroll Deductions)

Status: 📝 Planned (Event payloads documented; publisher and HR-PAY-02 subscriber to be implemented) Spec Reference: HR-PAY-02 (Payroll Deductions), HR-11 (Benefits Administration). When implemented, HR-PAY-02 will subscribe to auto-create deduction on enrollment and end-date deduction on termination. See src/cores/hr/lib/reconcileEnrollmentDeductions.ts for enrollment-deduction sync pattern.
⚠️ BREAKING CHANGE (v2.2.0): The payloads for hr.benefit_enrollment.created and hr.benefit_enrollment.terminated were restructured:
  • Removed: enrollment_id, benefit_plan_id, enrollment_date, coverage_tier
  • Added: benefit_enrollment_id, amount, pre_tax
  • Structure: Event-specific fields moved into payload object per Event Schema Standard Implementers consuming these events must update their handlers.

Event 1: hr.benefit_enrollment.created

Publisher: HR (Workforce) — HR-11 Benefits
Subscribers: HR-PAY-02 (Payroll Deductions)
Payload Schema:
{
  event: 'hr.benefit_enrollment.created';
  payload: {
    employee_id: uuid;
    benefit_enrollment_id: uuid;
    amount: number;           // employee contribution amount for deduction
    pre_tax: boolean;
  };
  metadata: {
    organization_id: uuid;
    user_id?: uuid;
    timestamp: timestamptz;
    correlation_id?: uuid;
  };
}
Purpose: Notify payroll deductions (HR-PAY-02) of new benefit enrollment so a deduction can be auto-created.

Event 2: hr.benefit_enrollment.terminated

Publisher: HR (Workforce) — HR-11 Benefits
Subscribers: HR-PAY-02 (Payroll Deductions)
Payload Schema:
{
  event: 'hr.benefit_enrollment.terminated';
  payload: {
    employee_id: uuid;
    benefit_enrollment_id: uuid;
    amount: number;           // last contribution amount (for reference)
    pre_tax: boolean;
  };
  metadata: {
    organization_id: uuid;
    user_id?: uuid;
    timestamp: timestamptz;
    correlation_id?: uuid;
  };
}
Purpose: Notify payroll deductions (HR-PAY-02) of benefit enrollment termination so the deduction can be end-dated.

HR-PAY-04: Employer Tax Liability Events (Tax Forms Compliance)

Status: 📝 Planned (Publisher implemented; FA consumer not yet implemented) Publisher: HR (Workforce) — HR-PAY-04 — ✅ Implemented in src/cores/hr/services/employer-taxes/publish-tax-event.ts (publishes to hr_events). Subscribers: FA (Finance) — for GL posting and liability tracking. Consumer: Not yet implemented; until FA consumes this event, GL posting may be manual. See FA_FINANCIAL_COMPLIANCE_TRACKING.md. Spec Reference: HR-PAY-04 (Tax Forms Compliance)

Event: hr.employer_tax_liability.calculated

Publisher: HR (Workforce) — HR-PAY-04
Subscribers: FA (Finance) — for GL posting and liability tracking
Payload Schema (Event Schema Standard):
{
  event: 'hr.employer_tax_liability.calculated';
  payload: {
    organization_id: uuid;
    tax_period_type: 'quarterly' | 'annual';
    tax_period_start: date;
    tax_period_end: date;
    federal_income_tax_withheld: number;
    social_security_tax_withheld: number;
    medicare_tax_withheld: number;
    employer_ss_tax: number;
    employer_medicare_tax: number;
    additional_medicare_tax_withheld?: number;
    total_liability: number;
    tax_form_run_id?: uuid;
  };
  metadata: {
    organization_id: uuid;
    user_id?: uuid;
    timestamp: timestamptz;
    correlation_id?: uuid;
  };
}
Purpose: Notify FA when employer-side tax liability has been calculated so FA can post to GL (or queue for manual posting until FA automation is ready). Contingency: Until FA is ready to consume this event, GL posting may be manual; document acceptance and link confirmation in HR-PAY-04 plan.

HR-34: Contractor & Contingent Workforce Events

Status: 📝 Planned (Event stubs defined; publishers to be implemented in Phase 4) Publisher: HR (Workforce) — HR-34 Subscribers: PF-10 (Notifications), FW-16 (Workflow automation — optional) Spec Reference: HR-34 Contractor & Contingent Workforce Management Channel: hr_events

Event 1: hr_contractor_created

Publisher: HR (Workforce) — HR-34 Subscribers: PF-10 (Notifications), FW-16 (optional automation triggers) Status: 📝 Planned Payload Schema:
{
  event: 'hr_contractor_created';
  payload: {
    organization_id: uuid;
    contractor_id: uuid;
    classification: string; // 'independent_contractor' | 'agency_contractor' | 'consultant' | 'temp_worker'
    agency_id?: uuid; // if agency_contractor
  };
  metadata: {
    organization_id: uuid;
    user_id: uuid;
    timestamp: timestamptz;
    correlation_id?: uuid;
  };
}
Purpose: Notify downstream systems when a new contractor is onboarded. No tax IDs in payload.

Event 2: hr_contractor_contract_renewal_due

Publisher: HR (Workforce) — HR-34 Subscribers: PF-10 (Notifications — renewal alerts to HR managers) Status: 📝 Planned Payload Schema:
{
  event: 'hr_contractor_contract_renewal_due';
  payload: {
    organization_id: uuid;
    contractor_id: uuid;
    contract_id: uuid;
    end_date: date;
    renewal_notice_days: number; // days until expiration
  };
  metadata: {
    organization_id: uuid;
    timestamp: timestamptz;
    correlation_id?: uuid;
  };
}
Purpose: Alert HR managers when a contractor contract is approaching its end date. Fired by batch cron or on contract create/update. No tax IDs in payload.

Event 3: hr_contractor_credential_expiring

Publisher: HR (Workforce) — HR-34 Subscribers: PF-10 (Notifications — expiration alerts) Status: 📝 Planned Payload Schema:
{
  event: 'hr_contractor_credential_expiring';
  payload: {
    organization_id: uuid;
    contractor_id: uuid;
    credential_id: uuid;
    expiration_date: date;
    days_until_expiration: number;
  };
  metadata: {
    organization_id: uuid;
    timestamp: timestamptz;
    correlation_id?: uuid;
  };
}
Purpose: Alert when a contractor credential is approaching expiration (30/60/90 day thresholds). Aligns with HR-02 credential expiration patterns. No tax IDs in payload.

FA-12: Expense Management Events

Status: ✅ Implemented (Events 1-4 published in code)
Spec Reference: specs/fa/specs/FA-12-expense-management-reimbursements.md

Event 1: fa_expense_report_submitted (canonical)

Publisher: FA (Finance)
Subscribers: FW-03 (Approval Workflow), PF-10 (Notifications)
Status: ✅ Implemented
Payload Schema:
interface ExpenseReportSubmittedEvent {
  event_version: '1.0';
  event_id: string;
  event_timestamp: string;
  organization_id: string;
  expense_report_id: string;
  employee_id: string;
  total_amount: number;
  submitted_at: string;
  submitted_by: string;
  line_count: number;
  has_policy_violations: boolean;
}
SLA: Delivery < 500ms p95, Processing < 2s p95, 3 retries with exponential backoff Purpose: Trigger approval workflow for expense report
Note: Canonical event name is fa_expense_report_submitted. This is the canonical schema for the event. Previous versions using event_type and simplified fields have been consolidated into this format. Consumers should migrate to use ExpenseReportSubmittedEvent interface fields.

Event 2: fa_expense_report_approved (canonical)

Publisher: FA (Finance)
Subscribers: FA-05 (Payment Processing), PF-10 (Notifications)
Status: ✅ Implemented
Payload Schema:
{
  event_type: 'fa_expense_report_approved'; // Canonical name
  event_id: uuid;
  event_version: '1.0';
  expense_report_id: uuid;
  report_number: string;
  employee_id: uuid;
  total_amount: number;
  approved_by: uuid;
  approved_at: timestamptz;
  approval_id: uuid;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Trigger reimbursement processing
Note: Consumers (FA-05, PF-10) MUST use event_id for deduplication and retry handling. The event_version field enables schema evolution tracking.

Event 3: fa_expense_report_rejected (canonical)

Publisher: FA (Finance)
Subscribers: PF-10 (Notifications)
Status: ✅ Implemented
Payload Schema:
{
  event_type: 'fa_expense_report_rejected'; // Canonical name
  event_id: uuid;
  event_version: '1.0';
  expense_report_id: uuid;
  report_number: string;
  employee_id: uuid;
  rejected_at: timestamptz;
  rejected_by: uuid;
  rejection_reason: string;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Notify employee of rejection
Note: Consumers (PF-10) MUST use event_id for deduplication and retry handling. The event_version field enables schema evolution tracking.

Event 4: fa_reimbursement_processed (canonical)

Publisher: FA (Finance)
Subscribers: FA-02 (GL), PF-10 (Notifications)
Status: ✅ Implemented
Payload Schema:
{
  event_type: 'fa_reimbursement_processed'; // Canonical name
  event_id: uuid;
  event_version: '1.0';
  reimbursement_payment_id: uuid;
  payment_number: string;
  employee_id: uuid;
  payment_amount: number;
  journal_entry_id: uuid;
  processed_by: uuid;
  processed_at: timestamptz;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Notify reimbursement completion and trigger GL posting
Note: Consumers (FA-02, PF-10) MUST use event_id for deduplication and retry handling. The event_version field enables schema evolution tracking.

HR-14: Employee Relations Events

Status: ✅ Complete
Implemented: 2026-01-09

Event 1: disciplinary_action_termination

Publisher: HR (Workforce)
Subscribers: HR-03 (Offboarding), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'disciplinary_action_termination';
  disciplinary_action_id: uuid;
  employee_id: uuid;
  action_type: 'termination';
  termination_reason: string;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Trigger HR-03 offboarding workflow when disciplinary action results in termination

Event 2: incident_reported

Publisher: HR (Workforce)
Subscribers: GR-06 (Incident Management), PF-10 (Notifications for critical/serious)
Payload Schema:
{
  event_type: 'incident_reported';
  incident_id: uuid;
  incident_type: 'accident' | 'injury' | 'safety_violation' | 'property_damage' | 'other';
  severity: 'minor' | 'moderate' | 'serious' | 'critical';
  incident_date: date;
  organization_id: uuid;
  site_id?: uuid;
  timestamp: timestamptz;
}
Purpose: Notify GR-06 incident management system of workplace incidents

Event 3: grievance_filed

Publisher: HR (Workforce)
Subscribers: GR-03 (Compliance)
Payload Schema:
{
  event_type: 'grievance_filed';
  grievance_id: uuid;
  employee_id: uuid;
  grievance_type: 'harassment' | 'discrimination' | 'wage_dispute' | 'working_conditions' | 'other';
  filed_date: date;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Notify compliance team of employee grievances for tracking and resolution

HR-26: E-Verify Integration Events

Status: ✅ Implemented
Publisher: HR-26 (E-Verify orchestrator edge function)
Subscribers: PF-10 (notifications), audit log
Event 1: hr_everify_case_created
Trigger: Successful USCIS case creation via hr-everify-orchestrator
Payload:
{
  case_id: uuid;
  employee_id: uuid;
  uscis_case_number: string;
  organization_id: uuid;
  timestamp: timestamptz;
}
Event 2: hr_everify_status_changed
Trigger: Status transition on poll or manual update
Payload:
{
  case_id: uuid;
  employee_id: uuid;
  old_status: string;
  new_status: string;
  organization_id: uuid;
  timestamp: timestamptz;
}
Event 3: hr_everify_tnc_opened
Trigger: Case enters TNC state
Payload:
{
  case_id: uuid;
  employee_id: uuid;
  tnc_type: string;
  organization_id: uuid;
  timestamp: timestamptz;
}

Status: ✅ Complete
Implemented: 2026-01-13

Event 1: merit_increase_approved

Publisher: HR (Workforce)
Subscribers: HR-07 (Payroll), FA (Budget tracking), PF-10 (Notifications)
Trigger: hr_merit_increases.status'approved'
Payload Schema:
{
  event_type: 'merit_increase_approved';
  merit_increase_id: uuid;
  employee_id: uuid;
  current_salary: number;
  new_salary: number;
  increase_percentage: number;
  effective_date: date;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Notify payroll and finance of approved salary changes

Event 2: compensation_analysis_completed

Publisher: HR (Workforce)
Subscribers: FA (Analytics), PF-10 (Notifications)
Trigger: hr_compensation_analyses.status'approved'
Payload Schema:
{
  event_type: 'compensation_analysis_completed';
  analysis_id: uuid;
  analysis_type: 'internal_equity' | 'market_comparison' | 'distribution';
  disparity_percent: number;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Notify finance of equity analysis results for budgeting decisions

Event 3: compensation_cost_allocated

Publisher: HR (Workforce)
Subscribers: FA (Budget adjustments), FA (Cost forecasting)
Trigger: hr_merit_increases.status'approved'
Payload Schema:
{
  event_type: 'compensation_cost_allocated';
  source: 'hr_merit_increases';
  merit_increase_id: uuid;
  employee_id: uuid;
  employee_name: string;
  department_id: uuid | null;
  department_name: string | null;
  position_title: string | null;
  previous_salary: number;
  new_salary: number;
  increase_amount: number;
  increase_percentage: number;
  annual_cost_impact: number;
  effective_date: date;
  currency: string;
  organization_id: uuid;
  approved_by: uuid;
  approved_at: timestamptz;
  timestamp: timestamptz;
}
Consumer Actions:
  1. FA creates budget alert for significant cost increases
  2. FA updates departmental expense forecasts
  3. FA may trigger budget amendment workflow if over threshold
Testing: Verify event fires on merit increase approval with correct payload

HR-16: Succession Planning Events

Status: 📝 Planned
Implemented: TBD

Event 1: successor_identified

Publisher: HR (Workforce)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'successor_identified';
  succession_plan_id: uuid;
  position_id: uuid;
  successor_id: uuid;
  readiness_level: 'ready_now' | 'ready_1_year' | 'ready_2_years' | 'ready_3_plus_years';
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Notify managers of successor readiness

Event 2: talent_promoted

Publisher: HR (Workforce)
Subscribers: HR-16 (Succession Planning)
Payload Schema:
{
  event_type: 'talent_promoted';
  employee_id: uuid;
  from_position_id: uuid;
  to_position_id: uuid;
  promotion_date: date;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Update succession plans when talent is promoted

HR-17: Employee Engagement Events

Status: 📝 Planned
Implemented: TBD

Event 1: survey_completed

Publisher: HR (Workforce)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'survey_completed';
  survey_id: uuid;
  response_id: uuid;
  employee_id: uuid | null; // null if anonymous
  completion_percentage: number;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Notify managers of survey completion for tracking participation

Event 2: exit_interview_completed

Publisher: HR (Workforce)
Subscribers: HR-03 (Offboarding)
Payload Schema:
{
  event_type: 'exit_interview_completed';
  exit_interview_id: uuid;
  employee_id: uuid;
  offboarding_instance_id: uuid;
  reason_for_leaving: string;
  would_recommend: boolean;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Update offboarding workflow when exit interview completed

FA-02: Vendor Bill Approved Events

Event: vendor_bill_approved
Publisher: FA (Finance & Accounting)
Subscribers: FW-03 (Workflow completion), PF-10 (Notifications), FA-03 (Payment queue)
Status: ✅ Complete
Implemented: 2025-11-26
Payload Schema:
{
  bill_id: uuid;
  bill_number: string;
  vendor_id: uuid;
  vendor_name: string;
  total_amount: number;
  due_date: date;
  approved_by: uuid;
  approved_at: timestamp;
  approval_workflow_id?: uuid;
  organization_id: uuid;
  site_id?: uuid;
}
Consumer:
  • supabase/functions/event-consumer/index.ts - Logs to audit trail
  • FW-03 Automation Engine - Completes approval workflow steps
  • PF-10 Notifications - Notifies vendors and accounting team
  • FA-03 Payment Processing - Queues bill for payment
Testing: ✅ Complete - Event fires on bill approval

FA-03: Payment Processed Events

Event: payment_processed
Publisher: FA (Finance & Accounting)
Subscribers: FA-02 (GL posting), PF-10 (Vendor notification), FA-06 (Bank reconciliation)
Status: ✅ Complete
Implemented: 2025-11-26
Payload Schema:
{
  payment_id: uuid;
  payment_number: string;
  vendor_id: uuid;
  payment_amount: number;
  payment_date: date;
  payment_method: 'check' | 'ach' | 'wire' | 'card';
  check_number?: string;
  bank_account_id: uuid;
  applied_bills: [{
    bill_id: uuid;
    amount_applied: number;
  }];
  organization_id: uuid;
  processed_by: uuid;
  processed_at: timestamp;
}
Consumer:
  • FA-02 Chart of Accounts - Creates GL journal entry for payment
  • PF-10 Notifications - Sends payment confirmation to vendor
  • FA-06 Bank Reconciliation - Marks expected transaction for reconciliation
Testing: ✅ Complete - Event fires on payment creation with bill applications

FA-03: Vendor Activated (domain event)

Registry ID: FA-E-06 (vendor_activated)
Event name: fa.vendor.activated
Version: 1.0.0
Publisher: FA (Finance & Accounting) — vendor master activation (e.g. FA-UX-11 Vendor onboarding wizard)
Status: 📝 Planned
Spec reference (single source of truth): FA-03 Accounts Payable — Event Contracts — FA-E-06 (naming, versioning, payload)
Publish call pattern:
publish_domain_event('fa.vendor.activated', { version: '1.0.0', payload });
Payload schema (payload object):
{
  vendor_id: uuid;
  organization_id: uuid;
  created_by_user_id: uuid;
  classification: '1099-MISC' | '1099-NEC' | null; // public 1099 categorization only; no TIN/bank data
  has_portal_invite: boolean;
  is_active: boolean;
  notes?: string; // optional; non-sensitive summary only — must NOT include vendor contact details (emails, phone numbers), TIN or partial TIN fragments, bank account/routing numbers or hints, insurance policy numbers, health/medical identifiers, or any other PII/PHI/secrets subject to compliance
}
Purpose: Notify async consumers (indexing, search, cross-core integrations) after a vendor is activated, without exposing sensitive vendor credentials in the event stream.

FA-22: Accounts Payable Automation Events

Spec Reference: specs/fa/specs/FA-22-accounts-payable-automation.md
Publisher: FA (Finance & Accounting)
Subscribers: FW-16 (Workflow Events – workflow triggers). Subscribers must subscribe to event_type values fa_bill_scan_completed and fa_bill_duplicate_flagged.
Status: 📝 Planned
Channel: fa_events (or equivalent)

fa_bill_scan_completed

Event type: fa_bill_scan_completed
When: After fa-scan-invoice edge function completes and inserts into fa_invoice_scans.
Payload Schema:
{
  event_type: 'fa_bill_scan_completed';
  organization_id: uuid;      // Required
  timestamp: timestamptz;     // Required
  user_id?: uuid;            // When user-initiated (e.g. scan from UI)
  correlation_id?: string;   // When chaining with other events
  scan_id: uuid;
  vendor_bill_id: uuid | null;  // Set when linked to bill
  confidence_score: number;
}

fa_bill_duplicate_flagged

Event type: fa_bill_duplicate_flagged
When: After fa-detect-duplicates creates a fa_duplicate_detection_log entry (on bill insert or cron).
Payload Schema:
{
  event_type: 'fa_bill_duplicate_flagged';
  organization_id: uuid;     // Required
  timestamp: timestamptz;     // Required
  user_id?: uuid;            // When user-initiated
  correlation_id?: string;   // When chaining (e.g. from same batch)
  vendor_bill_id: uuid;
  suspected_duplicate_of_id: uuid;
  match_score: number;
  match_reason: string;
  log_id: uuid;
}
Integration: FW-16 Event Registry – register event_type values fa_bill_scan_completed and fa_bill_duplicate_flagged so workflow designers can trigger automations (e.g., notify approver when duplicate flagged).

FA-04: Purchase Order Events

Status: ✅ Complete
Implemented: 2026-01-27
Spec Reference: specs/fa/specs/FA-04-purchase-orders.md

FA-E-04: purchase_order_approved

Event: purchase_order_approved
Publisher: FA (Finance & Accounting)
Subscribers: Event Consumer (audit logging), PF-10 (Notifications), FA-11 (Fixed Assets - asset creation from PO)
Status: ✅ Complete
Channel: fa_events
Payload Schema:
{
  event_type: 'purchase_order_approved';
  po_id: uuid;
  po_number: string;
  vendor_id: uuid;
  po_total: number;
  approved_by: uuid;
  approved_at: timestamp;
  user_id: uuid;  // Mirrors approved_by for user-initiated actions
  organization_id: uuid;
  site_id?: uuid;
  timestamp: timestamptz;
}
Consumer:
  • supabase/functions/event-consumer/index.ts - Logs to audit trail
  • PF-10 Notifications - Notifies purchaser and receiving staff
  • FA-11 Fixed Assets - Creates asset records from PO (when implemented)
Trigger: Database trigger fa_publish_po_approved() fires when PO status changes to ‘approved’ Testing: ✅ Complete - Event fires on PO approval

FA-E-05: goods_received

Event: goods_received
Publisher: FA (Finance & Accounting)
Subscribers: Event Consumer (audit logging), PF-10 (Notifications), FA-11 (Fixed Assets - asset receipt)
Status: ✅ Complete
Channel: fa_events
Payload Schema:
{
  event_type: 'goods_received';
  receipt_id: uuid;
  receipt_number: string;
  po_id: uuid;
  po_number: string;
  receipt_date: date;
  received_by: uuid;
  user_id: uuid;  // Mirrors received_by for user-initiated actions
  organization_id: uuid;
  site_id?: uuid;
  timestamp: timestamptz;
}
Consumer:
  • supabase/functions/event-consumer/index.ts - Logs to audit trail
  • PF-10 Notifications - Notifies AP staff for bill matching
  • FA-11 Fixed Assets - Updates asset status to “received” (when implemented)
Trigger: Database trigger fa_publish_goods_received() fires on receipt creation Testing: ✅ Complete - Event fires on receipt creation

FA-02: Journal Entry Posted Events

Event: journal_entry_posted
Publisher: FA (Finance & Accounting)
Subscribers: Event Consumer (audit logging), FA-07 (Balance refresh), PF-10 (Notifications)
Status: ✅ Complete
Implemented: 2025-11-26
Payload Schema:
{
  journal_entry_id: uuid;
  entry_number: string;
  entry_date: date;
  description: string;
  total_debit: number;
  total_credit: number;
  status: 'posted';
  source: 'manual' | 'accounts_payable' | 'payroll' | 'accounts_receivable' | 'bank_import';
  source_document_id?: uuid;
  fiscal_period_id: uuid;
  organization_id: uuid;
  posted_by: uuid;
  posted_at: timestamp;
  lines: [{
    account_id: uuid;
    fund_id?: uuid;
    department_id?: uuid;
    debit: number;
    credit: number;
  }];
}
Consumer:
  • Event Consumer - Logs all posted journal entries to audit trail
  • FA-07 Financial Reporting - Refreshes account balances and financial statements
  • PF-10 Notifications - Alerts accounting team of significant postings
Testing: ✅ Complete - Event fires on journal entry posting with all line details

FA-08: Budget Approved Events

Event: budget_approved
Publisher: FA (Finance & Accounting)
Subscribers: FW-03 (Workflow completion), PF-10 (Notifications), FA-07 (Reporting)
Status: ✅ Complete
Implemented: 2025-11-26
Payload Schema:
{
  budget_id: uuid;
  budget_name: string;
  fiscal_year: number;
  fund_id?: uuid;
  department_id?: uuid;
  total_amount: number;
  approved_by: uuid;
  approved_at: timestamp;
  approval_level: number;
  organization_id: uuid;
}
Consumer:
  • FW-03 Automation Engine - Completes approval workflow
  • PF-10 Notifications - Notifies budget owners and finance team
  • FA-07 Financial Reporting - Enables budget vs. actual reporting
Testing: ✅ Complete - Event fires on budget approval

FA-08: Budget Exceeded Events

Event: budget_exceeded
Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications to budget owners), FA-08 (Alert log)
Status: ✅ Complete
Implemented: 2025-11-26
Payload Schema:
{
  budget_id: uuid;
  budget_name: string;
  account_id: uuid;
  account_number: string;
  fund_id?: uuid;
  department_id?: uuid;
  budget_amount: number;
  actual_amount: number;
  variance_percent: number;
  threshold_type: 'warning' | 'critical';
  organization_id: uuid;
  triggered_by_entry_id: uuid;
  triggered_at: timestamp;
}
Consumer:
  • PF-10 Notifications - Sends alerts to budget owners and finance managers
  • FA-08 Budget Management - Logs alert and tracks budget compliance
Testing: ✅ Complete - Event fires when budget threshold exceeded

FA-09: Consolidation Completed Events

Event: consolidation_completed
Publisher: FA (Finance & Accounting)
Subscribers: FA-07 (Consolidated reports), PF-10 (Notifications), Event Consumer (audit)
Status: ✅ Complete
Implemented: 2025-11-26
Payload Schema:
{
  consolidation_id: uuid;
  consolidation_name: string;
  as_of_date: date;
  entities_included: uuid[];
  total_eliminations: number;
  elimination_amount: number;
  consolidated_assets: number;
  consolidated_liabilities: number;
  consolidated_net_assets: number;
  parent_organization_id: uuid;
  completed_by: uuid;
  completed_at: timestamp;
}
Consumer:
  • FA-07 Financial Reporting - Generates consolidated financial statements
  • PF-10 Notifications - Alerts management of completed consolidation
  • Event Consumer - Logs consolidation completion to audit trail
Testing: ✅ Complete - Event fires on consolidation run completion

PM-05: Provider Time-Off Events

Owning Core: PM (Practice Management)
Spec: PM-05 Provider Schedule & Availability
Integration: PM-05-provider-schedule-availability-INTEGRATION.md
Status: ✅ Implemented (2026-02-20) — declared in INTEGRATION doc; canonical schemas registered here on 2026-05-04 during PM-05 pre-verification.
All three events use canonical naming pm_{entity}_{action} and carry IDs only — no PHI. Subscribers must dereference IDs through PM RLS-protected reads.

pm_time_off_requested

Publisher: PM-05 (on insert into pm_provider_time_off with status = 'pending')
Subscribers: PF-10 Notifications (notify approver), FW (workflow triggers), Event Consumer (audit)
Schema version: 1
{
  "event_type": "pm_time_off_requested",
  "schema_version": 1,
  "payload": {
    "organization_id": "uuid",
    "provider_id": "uuid",
    "time_off_id": "uuid",
    "start_date": "YYYY-MM-DD",
    "end_date": "YYYY-MM-DD",
    "time_off_type": "vacation | sick | personal | continuing_education | conference | other"
  }
}

pm_time_off_approved

Publisher: PM-05 (on update to pm_provider_time_off.status = 'approved')
Subscribers: PM-03 (refresh availability), PM-04 (refresh facilitator availability), PF-10 (notify provider + coverage), HR-04 (display only — no shared tables), Event Consumer (audit)
Schema version: 1
{
  "event_type": "pm_time_off_approved",
  "schema_version": 1,
  "payload": {
    "organization_id": "uuid",
    "provider_id": "uuid",
    "time_off_id": "uuid",
    "approved_by": "uuid",
    "coverage_provider_id": "uuid | null"
  }
}

pm_time_off_denied

Publisher: PM-05 (on update to pm_provider_time_off.status = 'denied')
Subscribers: PF-10 (notify requester), Event Consumer (audit)
Schema version: 1
{
  "event_type": "pm_time_off_denied",
  "schema_version": 1,
  "payload": {
    "organization_id": "uuid",
    "provider_id": "uuid",
    "time_off_id": "uuid",
    "denied_by": "uuid"
  }
}
PHI safety: None of the three payloads contain patient data. time_off_type is workforce metadata, not clinical PHI.
Idempotency: Subscribers SHOULD treat time_off_id as the idempotency key.
Registration TODO: Verify these three events are seeded in fw_workflow_events (producer=pm). If absent, add a follow-up migration; if the shipped PM-05 hooks do not currently call publishEvent, this section documents the contract for the upcoming wiring.

CL-57: Clinical Content Marketplace Events

cl_marketplace_bundle_imported

Publisher: CL-57 (cl-marketplace-import Edge Function on successful import) Subscribers: Event Consumer (audit), future content-distribution analytics Status: ✅ Implemented Schema version: 1
{
  "event_type": "cl_marketplace_bundle_imported",
  "schema_version": 1,
  "payload": {
    "event_id": "uuid",
    "organization_id": "uuid",
    "import_id": "uuid",
    "bundle_id": "uuid",
    "bundle_key": "string",
    "bundle_version": "integer",
    "imported_item_count": "integer",
    "unsupported_item_count": "integer"
  }
}
PHI safety: Marketplace content is platform-curated reference data (no patient identifiers). All payload fields are tenant + bundle metadata only. Publishing semantics: Event publishes only after the import transaction has been materialized for the tenant (cl_marketplace_imports marked completed and import outputs persisted). Publisher authorization for curator actions is gated by cl_can_curate_marketplace() per CL-57. Idempotency: event_id is the canonical deduplication key for cross-retry processing (Event Schema Standard). import_id remains the domain-specific idempotency key for marketplace import workflows and subscriber reconciliation. Retry semantics: Fire-and-forget from the import flow. A publish failure does NOT roll back the import (the per-org rows are already materialized and survive event-bus outages). Versioning/consumers: Consumers should branch on schema_version; current consumers are audit/event-observability pipelines, with downstream analytics consumers planned. Spec reference: CL-57 Clinical Content Marketplace

CL-31: Co-Occurring Disorder Integrated Documentation — No Events Published

Status: ⚪ Not Applicable (intentional) Publisher: None (CL-31 is an intra-CL extension) Subscribers: None CL-31 (Co-Occurring Disorder Integrated Documentation) extends CL-02 (assessments), CL-03 (treatment plans), and CL-04 (progress notes) in-place and does not publish any domain events in Phase 1 or Phase 2. Rationale:
  • 42 CFR Part 2 SUD redaction is enforced at request time via cl_check_sud_consent() and redactSUDFields() in @/platform/clinical, not via async event consumers.
  • All COD integration with downstream cores (PM billing, CL-15 quality measures) flows through existing CL-02/CL-03/CL-04 events; no new event surface is introduced.
  • ASAM COD level is informational only; no PM service-authorization event coupling (Clarification #12).
If a future phase introduces a domain event (e.g., cl_cod_assessment_completed for CL-15 quality reporting), it MUST be added here with full schema, PHI-safety review, and a CONTEXT.md decision record. Spec reference: CL-31 Co-Occurring Disorder Integrated Documentation

Planned Events (LO-14/15 Action Dependencies & Status)

LO-14: Action Unblocked Event

Event: action_unblocked
Publisher: LO (Leadership Operating System)
Subscribers: PF-10 (Notifications), Event Consumer (audit logging)
Status: 📝 Planned
Spec Reference: LO-14 Action Dependencies
Purpose: Notify when a dependency action completes, enabling dependent actions to proceed. Payload Schema:
{
  event_type: 'action_unblocked';
  action_id: uuid;          // The action that was unblocked
  goal_id: uuid;            // The parent goal (rock_id)
  organization_id: uuid;
  site_id?: uuid;
  dependency_action_id: uuid; // The action that was completed
  unblocked_at: timestamptz;
  unblocked_by_user_id?: uuid; // User who completed the dependency
  timestamp: timestamptz;
}
Consumer Actions:
  • Event Consumer: Log to pf_audit_logs for audit trail
  • PF-10 Notifications (Future): Send notification to action assignee
Implementation (Planned):
-- Trigger when an action completes that has dependent actions
CREATE OR REPLACE FUNCTION lo_publish_action_unblocked()
RETURNS TRIGGER AS $$
DECLARE
  v_dependent_action RECORD;
BEGIN
  -- Only fire when action is completed
  IF NEW.status = 'complete' AND (OLD.status IS NULL OR OLD.status != 'complete') THEN
    -- Find actions that depend on this action
    FOR v_dependent_action IN
      SELECT id, rock_id, organization_id
      FROM lo_rock_milestones
      WHERE depends_on_action_id = NEW.id
    LOOP
      PERFORM pg_notify('lo_events', json_build_object(
        'event_type', 'action_unblocked',
        'action_id', v_dependent_action.id,
        'goal_id', v_dependent_action.rock_id,
        'organization_id', v_dependent_action.organization_id,
        'dependency_action_id', NEW.id,
        'unblocked_at', now(),
        'unblocked_by_user_id', auth.uid(),
        'timestamp', now()
      )::text);
    END LOOP;
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER SET search_path = public;

LO-15: Action Status Changed Event

Event: action_status_changed
Publisher: LO (Leadership Operating System)
Subscribers: PF-10 (Notifications), Event Consumer (audit logging)
Status: 📝 Planned
Spec Reference: LO-15 Enhanced Action Status
Purpose: Notify when an action’s status changes, enabling audit logging and status-based notifications. Payload Schema:
{
  event_type: 'action_status_changed';
  action_id: uuid;
  goal_id: uuid;            // The parent goal (rock_id)
  organization_id: uuid;
  site_id?: uuid;
  old_status: 'not_started' | 'in_progress' | 'blocked' | 'on_hold' | 'needs_review' | 'complete';
  new_status: 'not_started' | 'in_progress' | 'blocked' | 'on_hold' | 'needs_review' | 'complete';
  changed_by: uuid;
  changed_at: timestamptz;
  timestamp: timestamptz;
}
Consumer Actions:
  • Event Consumer: Log to pf_audit_logs for audit trail
  • PF-10 Notifications (Future): Send notifications based on status:
    • needs_review → Notify reviewer/goal owner
    • blocked → Notify assignee and goal owner
    • complete → Notify goal owner
Implementation (Planned):
CREATE OR REPLACE FUNCTION lo_publish_action_status_changed()
RETURNS TRIGGER AS $$
BEGIN
  IF OLD.status IS DISTINCT FROM NEW.status THEN
    PERFORM pg_notify('lo_events', json_build_object(
      'event_type', 'action_status_changed',
      'action_id', NEW.id,
      'goal_id', NEW.rock_id,
      'organization_id', NEW.organization_id,
      'old_status', COALESCE(OLD.status, 'not_started'),
      'new_status', NEW.status,
      'changed_by', auth.uid(),
      'changed_at', now(),
      'timestamp', now()
    )::text);
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER SET search_path = public;

CREATE TRIGGER trigger_action_status_changed
AFTER UPDATE ON lo_rock_milestones
FOR EACH ROW
WHEN (OLD.status IS DISTINCT FROM NEW.status)
EXECUTE FUNCTION lo_publish_action_status_changed();

Planned Events (FW-22 Execution Monitoring)

FW-22: Workflow Execution Failed Event

Event: execution_failed
Publisher: FW (Forms & Workflow)
Subscribers: PF-10 (Notifications), FW-22 (Monitoring Dashboard)
Status: 📝 Planned (FW-22 Implementation)
Spec Reference: FW-22 Workflow Execution Monitoring & Debugging
Purpose: Notify when a workflow execution fails, enabling alerts and monitoring dashboard updates. Payload Schema:
{
  event_type: 'execution_failed';
  organization_id: uuid;
  site_id?: uuid;
  execution_id: uuid;
  workflow_id: uuid;
  workflow_name: string;
  failed_node_id?: string;
  failed_node_name?: string;
  error_message: string;
  error_code?: string;
  started_at: timestamptz;
  failed_at: timestamptz;
  trigger_type: 'form_submitted' | 'form_updated' | 'scheduled' | 'manual' | 'event';
  triggered_by?: uuid;
  timestamp: timestamptz;
}
Consumer Actions:
  • PF-10 Notifications: Send alert to workflow owner and org admins
  • FW-22 Dashboard: Update failed execution count, trigger refresh
Implementation (Planned):
CREATE TRIGGER trigger_execution_failed
AFTER UPDATE ON fw_workflow_executions
FOR EACH ROW
WHEN (NEW.status = 'failed' AND OLD.status != 'failed')
EXECUTE FUNCTION publish_execution_failed();

Planned Events (FW-32 External Form Portal)

FW-16-P2: Event Schema Updated

Event: fw_event_schema_updated
Publisher: FW (Forms & Workflow)
Subscribers: FW (Event Registry UI), Monitoring
Status: ✅ Implemented (FW-16-P2)
Channel: fw_events
{
  event_type: 'fw_event_schema_updated';
  organization_id: uuid;
  payload: {
    event_name: string;
    old_schema_version: number;
    new_schema_version: number;
    changed_by: uuid;
  };
}

FW-16-P2: Event Deprecated

Event: fw_event_deprecated
Publisher: FW (Forms & Workflow)
Subscribers: FW (Event Registry UI), Monitoring
Status: ✅ Implemented (FW-16-P2)
Channel: fw_events
{
  event_type: 'fw_event_deprecated';
  organization_id: uuid;
  payload: {
    event_name: string;
    deprecated_at: string;
    replacement_event: string | null;
    deprecated_by: uuid;
  };
}

FW-32: External Form Submission Event

Event: fw_external_form_submitted
Publisher: FW (Forms & Workflow)
Subscribers: PF-10 (Notifications), FW-03 (Automation Engine)
Status: ✅ Implemented (FW-32 — published by portal-form-submit edge function via pg_notify)
Spec Reference: FW-32 External Form Portal
Purpose: Notify when a form is submitted via the external portal, trigger notifications and workflow automations. Payload Schema:
{
  event_type: 'fw_external_form_submitted';
  organization_id: uuid;
  site_id?: uuid;
  form_id: uuid;
  submission_id: uuid;
  portal_config_id: uuid;
  submitted_at: timestamptz;
  submitted_by_email: string;
  verified: boolean;
  spam_score?: number;
  timestamp: timestamptz;
}
Consumer Actions:
  • PF-10 Notifications: Send confirmation email to submitter
  • FW-03 Automation Engine: Trigger any workflow automations configured for external form submissions
Implementation (Planned):
CREATE OR REPLACE FUNCTION fw_publish_external_form_submitted()
RETURNS TRIGGER AS $$
DECLARE
  v_portal_config fw_form_portal_config;
BEGIN
  -- Get portal config
  SELECT * INTO v_portal_config
  FROM fw_form_portal_config
  WHERE form_id = NEW.form_id
    AND organization_id = NEW.organization_id
    AND is_active = true
  LIMIT 1;
  
  IF v_portal_config IS NOT NULL THEN
    PERFORM pg_notify('fw_events', json_build_object(
      'event_type', 'fw_external_form_submitted',
      'organization_id', NEW.organization_id,
      'site_id', NEW.site_id,
      'form_id', NEW.form_id,
      'submission_id', NEW.id,
      'portal_config_id', v_portal_config.id,
      'submitted_at', NEW.submitted_at,
      'submitted_by_email', NEW.submitted_by_email,
      'verified', NEW.email_verified,
      'spam_score', NEW.spam_score,
      'timestamp', now()
    )::text);
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER trigger_external_form_submitted
AFTER INSERT ON fw_form_submissions
FOR EACH ROW
WHEN (NEW.submitted_via = 'portal')
EXECUTE FUNCTION fw_publish_external_form_submitted();

Planned Events (FW-34 Approval Workflows)

FW-34: Approval Request Submitted Event

Event: fw_approval_submitted
Publisher: FW (Forms & Workflow)
Subscribers: PF-10 (Notifications), FW-03 (Automation Engine)
Status: 📝 Planned (FW-34 Implementation)
Spec Reference: FW-34 Approval Workflows
Purpose: Notify when a new approval request is submitted, trigger notifications to approvers. Payload Schema:
{
  event_type: 'fw_approval_submitted';
  organization_id: uuid;
  site_id?: uuid;
  request_id: uuid;
  chain_id: uuid;
  title: string;
  submitted_by: uuid;
  source_type: 'form_submission' | 'entity' | 'workflow';
  source_id: uuid;
  priority: 'low' | 'normal' | 'high' | 'urgent';
  timestamp: timestamptz;
}
Consumer Actions:
  • PF-10 Notifications: Send notification to assigned approvers
  • FW-03 Automation Engine: Trigger any related automations
Implementation (Planned):
CREATE OR REPLACE FUNCTION fw_publish_approval_submitted()
RETURNS TRIGGER AS $$
BEGIN
  PERFORM pg_notify('fw_events', json_build_object(
    'event_type', 'fw_approval_submitted',
    'organization_id', NEW.organization_id,
    'request_id', NEW.id,
    'chain_id', NEW.chain_id,
    'title', NEW.title,
    'submitted_by', NEW.submitted_by,
    'source_type', NEW.source_type,
    'source_id', NEW.source_id,
    'priority', NEW.priority,
    'timestamp', now()
  )::text);
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER trigger_approval_submitted
AFTER INSERT ON fw_approval_requests
FOR EACH ROW
EXECUTE FUNCTION fw_publish_approval_submitted();

FW-34: Approval Request Completed Event

Event: fw_approval_completed
Publisher: FW (Forms & Workflow)
Subscribers: FW-03 (Automation Engine), PF-10 (Notifications)
Status: 📝 Planned (FW-34 Implementation)
Spec Reference: FW-34 Approval Workflows
Purpose: Notify when an approval request is completed (approved or rejected). Payload Schema:
{
  event_type: 'fw_approval_completed';
  organization_id: uuid;
  site_id?: uuid;
  request_id: uuid;
  chain_id: uuid;
  title: string;
  decision: 'approved' | 'rejected';
  submitted_by: uuid;
  completed_by: uuid;
  source_type: 'form_submission' | 'entity' | 'workflow';
  source_id: uuid;
  completed_at: timestamptz;
  timestamp: timestamptz;
}
Consumer Actions:
  • FW-03 Automation Engine: Trigger post-approval automations (e.g., update entity status)
  • PF-10 Notifications: Notify submitter of decision
Implementation (Planned):
CREATE OR REPLACE FUNCTION fw_publish_approval_completed()
RETURNS TRIGGER AS $$
BEGIN
  IF NEW.status IN ('approved', 'rejected') AND 
     (OLD.status IS NULL OR OLD.status NOT IN ('approved', 'rejected')) THEN
    PERFORM pg_notify('fw_events', json_build_object(
      'event_type', 'fw_approval_completed',
      'organization_id', NEW.organization_id,
      'request_id', NEW.id,
      'chain_id', NEW.chain_id,
      'title', NEW.title,
      'decision', NEW.final_decision,
      'submitted_by', NEW.submitted_by,
      'completed_by', NEW.completed_by,
      'source_type', NEW.source_type,
      'source_id', NEW.source_id,
      'completed_at', NEW.completed_at,
      'timestamp', now()
    )::text);
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

CREATE TRIGGER trigger_approval_completed
AFTER UPDATE ON fw_approval_requests
FOR EACH ROW
EXECUTE FUNCTION fw_publish_approval_completed();

FW-34: Approval Escalated Event

Event: fw_approval_escalated
Publisher: FW (Forms & Workflow)
Subscribers: PF-10 (Notifications)
Status: 📝 Planned (FW-34 Implementation)
Spec Reference: FW-34 Approval Workflows
Purpose: Notify when an approval is escalated due to timeout. Payload Schema:
{
  event_type: 'fw_approval_escalated';
  organization_id: uuid;
  request_id: uuid;
  assignment_id: uuid;
  original_assignee_id: uuid;
  escalated_to_id?: uuid;
  reason: 'timeout' | 'manual';
  hours_overdue: number;
  timestamp: timestamptz;
}
Consumer Actions:
  • PF-10 Notifications: Notify escalation target and original approver

Planned Events (FW-33 Form Signature Capture)

FW-33: Form Signature Captured Event

Event: fw_form_signature_captured
Publisher: FW (Forms & Workflow)
Subscribers: FW-03 (Automation Engine), PF-10 (Notifications)
Status: 📝 Planned (FW-33 Implementation)
Spec Reference: FW-33 Form Signature Capture
Purpose: Notify when a signature is captured on a form field, trigger automations and notifications. Payload Schema:
{
  event_type: 'fw_form_signature_captured';
  organization_id: uuid;
  site_id?: uuid;
  form_id: uuid;
  submission_id: uuid;
  field_id: uuid;
  signature_id: uuid; // References pf_signatures (PF-33)
  signer_user_id?: uuid;
  signer_email: string;
  timestamp: timestamptz;
}
Consumer Actions:
  • FW-03 Automation Engine: Trigger signature-based workflow automations
  • PF-10 Notifications: Send confirmation to signer

FW-33: Signed Document Generated Event

Event: fw_signed_document_generated
Publisher: FW (Forms & Workflow)
Subscribers: PF-11 (Documents)
Status: 📝 Planned (FW-33 Implementation)
Spec Reference: FW-33 Form Signature Capture
Purpose: Notify when a signed PDF document is generated from a form submission. Payload Schema:
{
  event_type: 'fw_signed_document_generated';
  organization_id: uuid;
  submission_id: uuid;
  document_id: uuid; // References pf_documents (PF-11)
  signature_ids: uuid[]; // All signatures embedded in document
  generated_at: timestamptz;
  timestamp: timestamptz;
}
Consumer Actions:
  • PF-11 Documents: Link document to submission, update document metadata

Planned Events (FW-16 Event Registry)

The following events are planned for registration in fw_workflow_events as part of FW-16 (Event-Based Workflow Triggers):

HR Core Events (Planned)

Event NameDisplay NameCategoryEntity Type
hr_employee_createdEmployee Created (canonical)lifecyclehr_employees
hr_employee_assigned_to_siteEmployee Assigned to Sitelifecyclehr_employees
hr_employee_hiredEmployee Hiredlifecyclehr_employees
hr_employee_terminatedEmployee Terminatedlifecyclehr_employees
hr_credential_expiredCredential Expiredcompliancehr_employee_credentials
hr_credential_verifiedCredential Verifiedcompliancehr_employee_credentials
hr_onboarding_completedOnboarding Completedlifecyclehr_onboarding_instances
hr_leave_approvedLeave Approvedoperationalhr_leave_requests
hr_interview_scorecard_assignedScorecard Assignedoperationalhr_interview_scorecards
hr_interview_scorecard_submittedScorecard Submittedoperationalhr_interview_scorecards
hr_final_paycheck_status_changedFinal Paycheck Status Changedcompliancehr_final_paycheck_requests
hr_fingerprint_clearance_status_changedClearance Status Changedcompliancehr_fingerprint_clearances
hr_fingerprint_clearance_expiration_warningClearance Expiration Warningcompliancehr_fingerprint_clearances
hr_flsa_classification_changedFLSA Classification Changedcompliancehr_flsa_classifications
hr_flsa_reclassification_approvedFLSA Reclassification Approvedcompliancehr_flsa_reclassifications
HR-01 canonical events (confirmed 2026-04-28): hr_employee_created, hr_employee_assigned_to_site, and hr_employee_terminated are published by HR-01 — see HR-01 Integration §Events for full payload schemas. hr_employee_hired is treated as a synonym/legacy alias of hr_employee_created for downstream consumers (FW-16 registry retains both names during transition; new subscribers SHOULD prefer hr_employee_created). Subscribers include PF-101 (Google Workspace provisioning/offboarding), HR-30 (final paycheck on termination), and FW-16 workflow triggers.

PF-101: Google Workspace Integration (planned detail)

Spec: PF-101 Integration: PF-101 Integration Consumes:
  • hr_employee_created (HR-01) — provision or link a Google Workspace user when tenant policy enables provisioning. Payload: organization_id, employee_id, profile_id, department_id, position_id, hire_date, correlation_id, timestamp.
  • hr_employee_assigned_to_site (HR-01) — reconcile site-based group, OU, Drive, Calendar resource, or Chat mappings. Payload: organization_id, employee_id, site_id, assignment_date, role, correlation_id, timestamp.
  • hr_employee_terminated (HR-01) — suspend/offboard linked Workspace user, revoke licenses, remove groups, queue Drive transfer review. Payload: organization_id, employee_id, termination_date, termination_reason, correlation_id, timestamp.
Publishes:
  • pf_google_workspace_user_provisioned — subscribers PF-10, HR status consumers; payload: organization_id, employee_id, profile_id, google_user_id, correlation_id, timestamp. Signals successful Workspace user provisioning without exposing secrets or PHI. Subscribers requiring email must perform scoped lookups using google_user_id or profile_id.
  • pf_google_workspace_connector_degraded — subscribers PF-10, PF-36; payload: organization_id, connection_id, capability (directory|gmail|calendar|drive|chat|licensing|reports), reason_code (sanitized machine code), correlation_id, timestamp. Alerts admins when credential, scope, quota, BAA gate, or sync health degrades.
Event NameDisplay NameCategoryEntity Type
pf_google_workspace_user_provisionedGoogle Workspace User Provisionedlifecyclepf_google_workspace_user_links
pf_google_workspace_connector_degradedGoogle Workspace Connector Degradedhealthpf_google_workspace_connections
See PF-101 Integration §Event Contracts for full payload schemas, BAA/PHI-gating rules, and idempotency semantics (events keyed by event_id as the canonical deduplication key; correlation_id is used only for trace/linkage).

HR-28: Fingerprint Clearance Card Management (planned detail)

Spec: HR-28
Publishes:
  • hr_fingerprint_clearance_status_changed — notify HR-02, HR-03 gates when clearance moves between blocking/non-blocking states; payload: organization_id, employee_id, clearance_id, previous_status, new_status, effective_at.
  • hr_fingerprint_clearance_expiration_warning — scheduled worker fires at 90/60/30-day thresholds; subscriber PF-10; payload: organization_id, employee_id, clearance_id, days_until_expiration, expiration_date.
See HR-28 Integration for full payload schemas.

HR-29: FLSA Classification & Compliance Engine (planned detail)

Spec: HR-29 Publishes:
  • hr_flsa_classification_changed — subscribers HR-07 (Payroll), HR-01 (Employee Directory); payload: classification_id, position_id, employee_id, previous_classification, new_classification, effective_date, retroactive_start_date, retroactive_pay_request_id, organization_id.
  • hr_flsa_reclassification_approved — subscribers HR-07 (Payroll); payload: reclassification_id, employee_id, new_classification, effective_date, retroactive_start_date, retroactive_pay_request_id, organization_id.
See HR-29 Integration for full payload schemas and data flow.

HR-30: Final paycheck (planned detail)

Spec: HR-30
Consumes: hr_employee_terminated (HR-03) — create hr_final_paycheck_requests.
May publish: hr_final_paycheck_status_changed — subscribers PF-10, HR-07 (Phase 2); payload stub in HR-30 Integration.

RH Core Events (Planned)

Event NameDisplay NameCategoryEntity Type
rh_resident_admittedResident Admittedlifecyclerh_episodes
rh_resident_dischargedResident Dischargedlifecyclerh_episodes
rh_phase_advancedEpisode phase advancedoperationalrh_episode_phases
rh_bed_assignedBed Assignedoperationalrh_beds

FA Core Events (Planned)

Event NameDisplay NameCategoryEntity Type
fa_invoice_paidInvoice Paidfinancialfa_invoices
fa_budget_approvedBudget Approvedfinancialfa_budgets
fa_budget_exceededBudget Exceededalertfa_budget_alerts
fa_payment_processedPayment Processedfinancialfa_customer_payments
Implementation: See FW-16 Event-Based Workflow Triggers for full specification.

FA-10: Tax Reporting Events

Status: 📝 Planned
Spec Reference: FA-10 (Tax Reporting & Compliance)

Event 1: tax_1099_generated

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'tax_1099_generated';
  organization_id: uuid;
  tax_year_id: uuid;
  vendor_id: uuid;
  form_type: '1099-MISC' | '1099-NEC';
  generated_at: timestamp;
}

Event 2: tax_w2_generated

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications), HR-07
Payload Schema:
{
  event_type: 'tax_w2_generated';
  organization_id: uuid;
  tax_year_id: uuid;
  employee_id: uuid;
  generated_at: timestamp;
}

Event 3: tax_year_closed

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications), FA-07
Payload Schema:
{
  event_type: 'tax_year_closed';
  organization_id: uuid;
  tax_year_id: uuid;
  tax_year: number;
  closed_at: timestamp;
  closed_by: uuid;
}

FA-11: Fixed Assets Events

Status: 📝 Planned
Spec Reference: FA-11 (Fixed Assets & Depreciation)

Event 1: asset_created

Publisher: FA (Finance & Accounting)
Subscribers: FM-05 (Facilities), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'asset_created';
  organization_id: uuid;
  asset_id: uuid;
  asset_tag: string;
  asset_name: string;
  purchase_cost: number;
  created_at: timestamp;
}

Event 2: asset_disposed

Publisher: FA (Finance & Accounting)
Subscribers: FM-05 (Facilities), PF-10 (Notifications), FA-02 (GL)
Payload Schema:
{
  event_type: 'asset_disposed';
  organization_id: uuid;
  asset_id: uuid;
  disposal_date: date;
  disposal_method: string;
  gain_loss: number;
}

Event 3: depreciation_posted

Publisher: FA (Finance & Accounting)
Subscribers: FA-02 (GL), FA-07 (Financial Reporting)
Payload Schema:
{
  event_type: 'depreciation_posted';
  organization_id: uuid;
  asset_id: uuid;
  depreciation_month: date;
  depreciation_amount: number;
  journal_entry_id: uuid;
}

FA-12: Expense Management Events

Status: 📝 Planned
Spec Reference: FA-12 (Expense Management & Reimbursements)
Note: The canonical schema for FA-12 events is defined in the FA-12 section above (lines 484-582). This duplicate section has been removed. Please refer to the ExpenseReportSubmittedEvent interface and other event definitions in that section for the authoritative payload formats.

FA-13: Project Accounting Events

Status: 📝 Planned
Spec Reference: FA-13 (Project Accounting & Grant Tracking)

Event 1: project_created

Publisher: FA (Finance & Accounting)
Subscribers: FA-08 (Budgeting), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'project_created';
  organization_id: uuid;
  project_id: uuid;
  project_number: string;
  project_name: string;
  created_at: timestamp;
}

Event 2: project_budget_exceeded

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications), FA-08 (Budgeting)
Payload Schema:
{
  event_type: 'project_budget_exceeded';
  organization_id: uuid;
  project_id: uuid;
  budget_variance: number;
  exceeded_percentage: number;
}

Event 3: grant_drawdown_received

Publisher: FA (Finance & Accounting)
Subscribers: FA-02 (GL), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'grant_drawdown_received';
  organization_id: uuid;
  project_id: uuid;
  drawdown_id: uuid;
  drawdown_amount: number;
  received_at: timestamp;
}

FA-14: Cash Management Events

Status: 📝 Planned
Spec Reference: FA-14 (Cash Management & Treasury)

Event 1: cash_position_updated

Publisher: FA (Finance & Accounting)
Subscribers: FA-07 (Financial Reporting), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'cash_position_updated';
  organization_id: uuid;
  position_date: date;
  total_cash: number;
  updated_at: timestamp;
}

Event 2: investment_maturity_approaching

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'investment_maturity_approaching';
  organization_id: uuid;
  investment_id: uuid;
  maturity_date: date;
  days_until_maturity: number;
}

Event 3: credit_limit_approaching

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'credit_limit_approaching';
  organization_id: uuid;
  credit_line_id: uuid;
  utilization_percentage: number;
  available_credit: number;
}

FA-15: Cost Allocation Events

Status: 📝 Planned
Spec Reference: FA-15 (Cost Allocation & Indirect Cost Rates)

Event 1: idc_rate_calculated

Publisher: FA (Finance & Accounting)
Subscribers: FA-13 (Project Accounting), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'idc_rate_calculated';
  organization_id: uuid;
  rate_id: uuid;
  pool_id: uuid;
  fiscal_year: number;
  idc_rate: number;
  calculated_at: timestamp;
}

Event 2: idc_allocated

Publisher: FA (Finance & Accounting)
Subscribers: FA-13 (Project Accounting), FA-02 (GL)
Payload Schema:
{
  event_type: 'idc_allocated';
  organization_id: uuid;
  allocation_id: uuid;
  project_id: uuid;
  allocated_idc: number;
  journal_entry_id: uuid;
}

FA-16: Financial Analytics Events

Status: 📝 Planned
Spec Reference: FA-16 (Financial Analytics & Dashboards)

Event 1: kpi_threshold_exceeded

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'kpi_threshold_exceeded';
  organization_id: uuid;
  kpi_id: uuid;
  kpi_name: string;
  kpi_value: number;
  threshold_type: 'warning' | 'critical';
  exceeded_at: timestamp;
}

FA-17: Intercompany Events

Status: 📝 Planned
Spec Reference: FA-17 (Intercompany Transactions)

Event 1: intercompany_transaction_created

Publisher: FA (Finance & Accounting)
Subscribers: FA-02 (GL), FA-09 (Consolidation)
Payload Schema:
{
  event_type: 'intercompany_transaction_created';
  organization_id: uuid;
  transaction_id: uuid;
  from_entity_id: uuid;
  to_entity_id: uuid;
  transaction_amount: number;
  created_at: timestamp;
}

Event 2: intercompany_elimination_generated

Publisher: FA (Finance & Accounting)
Subscribers: FA-09 (Consolidation), FA-02 (GL)
Payload Schema:
{
  event_type: 'intercompany_elimination_generated';
  organization_id: uuid;
  elimination_id: uuid;
  consolidation_id: uuid;
  elimination_amount: number;
  generated_at: timestamp;
}

FA-19: Financial Close Events

Status: 📝 Planned
Spec Reference: FA-19 (Financial Close Management)

Event 1: close_period_started

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications), FA-02 (GL)
Payload Schema:
{
  event_type: 'close_period_started';
  organization_id: uuid;
  close_period_id: uuid;
  period_name: string;
  started_at: timestamp;
}

Event 2: close_period_completed

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications), FA-07 (Financial Reporting)
Payload Schema:
{
  event_type: 'close_period_completed';
  organization_id: uuid;
  close_period_id: uuid;
  period_name: string;
  completed_at: timestamp;
}

Event 3: close_task_assigned

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'close_task_assigned';
  organization_id: uuid;
  close_task_id: uuid;
  assigned_to: uuid;
  assigned_at: timestamp;
}

FA-10: Tax Reporting Events

Status: 📝 Planned
Spec Reference: FA-10 (Tax Reporting & Compliance)

Event 1: tax_1099_generated

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'tax_1099_generated';
  organization_id: uuid;
  tax_year_id: uuid;
  vendor_id: uuid;
  form_type: '1099-MISC' | '1099-NEC';
  generated_at: timestamp;
}

Event 2: tax_w2_generated

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications), HR-07
Payload Schema:
{
  event_type: 'tax_w2_generated';
  organization_id: uuid;
  tax_year_id: uuid;
  employee_id: uuid;
  generated_at: timestamp;
}

Event 3: tax_year_closed

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications), FA-07
Payload Schema:
{
  event_type: 'tax_year_closed';
  organization_id: uuid;
  tax_year_id: uuid;
  tax_year: number;
  closed_at: timestamp;
  closed_by: uuid;
}

FA-11: Fixed Assets Events

Status: 📝 Planned
Spec Reference: FA-11 (Fixed Assets & Depreciation)

Event 1: asset_created

Publisher: FA (Finance & Accounting)
Subscribers: FM-05 (Facilities), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'asset_created';
  organization_id: uuid;
  asset_id: uuid;
  asset_tag: string;
  asset_name: string;
  purchase_cost: number;
  created_at: timestamp;
}

Event 2: asset_disposed

Publisher: FA (Finance & Accounting)
Subscribers: FM-05 (Facilities), PF-10 (Notifications), FA-02 (GL)
Payload Schema:
{
  event_type: 'asset_disposed';
  organization_id: uuid;
  asset_id: uuid;
  disposal_date: date;
  disposal_method: string;
  gain_loss: number;
}

Event 3: depreciation_posted

Publisher: FA (Finance & Accounting)
Subscribers: FA-02 (GL), FA-07 (Financial Reporting)
Payload Schema:
{
  event_type: 'depreciation_posted';
  organization_id: uuid;
  asset_id: uuid;
  depreciation_month: date;
  depreciation_amount: number;
  journal_entry_id: uuid;
}

FA-12: Expense Management Events

Status: 📝 Planned
Spec Reference: FA-12 (Expense Management & Reimbursements)
Note: The canonical schema for FA-12 events is defined in the FA-12 section above (lines 484-582). This duplicate section has been removed. Please refer to the ExpenseReportSubmittedEvent interface and other event definitions in that section for the authoritative payload formats.

FA-13: Project Accounting Events

Status: 📝 Planned
Spec Reference: FA-13 (Project Accounting & Grant Tracking)

Event 1: project_created

Publisher: FA (Finance & Accounting)
Subscribers: FA-08 (Budgeting), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'project_created';
  organization_id: uuid;
  project_id: uuid;
  project_number: string;
  project_name: string;
  created_at: timestamp;
}

Event 2: project_budget_exceeded

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications), FA-08 (Budgeting)
Payload Schema:
{
  event_type: 'project_budget_exceeded';
  organization_id: uuid;
  project_id: uuid;
  budget_variance: number;
  exceeded_percentage: number;
}

Event 3: grant_drawdown_received

Publisher: FA (Finance & Accounting)
Subscribers: FA-02 (GL), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'grant_drawdown_received';
  organization_id: uuid;
  project_id: uuid;
  drawdown_id: uuid;
  drawdown_amount: number;
  received_at: timestamp;
}

FA-14: Cash Management Events

Status: 📝 Planned
Spec Reference: FA-14 (Cash Management & Treasury)

Event 1: cash_position_updated

Publisher: FA (Finance & Accounting)
Subscribers: FA-07 (Financial Reporting), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'cash_position_updated';
  organization_id: uuid;
  position_date: date;
  total_cash: number;
  updated_at: timestamp;
}

Event 2: investment_maturity_approaching

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'investment_maturity_approaching';
  organization_id: uuid;
  investment_id: uuid;
  maturity_date: date;
  days_until_maturity: number;
}

Event 3: credit_limit_approaching

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'credit_limit_approaching';
  organization_id: uuid;
  credit_line_id: uuid;
  utilization_percentage: number;
  available_credit: number;
}

FA-15: Cost Allocation Events

Status: 📝 Planned
Spec Reference: FA-15 (Cost Allocation & Indirect Cost Rates)

Event 1: idc_rate_calculated

Publisher: FA (Finance & Accounting)
Subscribers: FA-13 (Project Accounting), PF-10 (Notifications)
Payload Schema:
{
  event_type: 'idc_rate_calculated';
  organization_id: uuid;
  rate_id: uuid;
  pool_id: uuid;
  fiscal_year: number;
  idc_rate: number;
  calculated_at: timestamp;
}

Event 2: idc_allocated

Publisher: FA (Finance & Accounting)
Subscribers: FA-13 (Project Accounting), FA-02 (GL)
Payload Schema:
{
  event_type: 'idc_allocated';
  organization_id: uuid;
  allocation_id: uuid;
  project_id: uuid;
  allocated_idc: number;
  journal_entry_id: uuid;
}

FA-16: Financial Analytics Events

Status: 📝 Planned
Spec Reference: FA-16 (Financial Analytics & Dashboards)

Event 1: kpi_threshold_exceeded

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'kpi_threshold_exceeded';
  organization_id: uuid;
  kpi_id: uuid;
  kpi_name: string;
  kpi_value: number;
  threshold_type: 'warning' | 'critical';
  exceeded_at: timestamp;
}

FA-17: Intercompany Events

Status: 📝 Planned
Spec Reference: FA-17 (Intercompany Transactions)

Event 1: intercompany_transaction_created

Publisher: FA (Finance & Accounting)
Subscribers: FA-02 (GL), FA-09 (Consolidation)
Payload Schema:
{
  event_type: 'intercompany_transaction_created';
  organization_id: uuid;
  transaction_id: uuid;
  from_entity_id: uuid;
  to_entity_id: uuid;
  transaction_amount: number;
  created_at: timestamp;
}

Event 2: intercompany_elimination_generated

Publisher: FA (Finance & Accounting)
Subscribers: FA-09 (Consolidation), FA-02 (GL)
Payload Schema:
{
  event_type: 'intercompany_elimination_generated';
  organization_id: uuid;
  elimination_id: uuid;
  consolidation_id: uuid;
  elimination_amount: number;
  generated_at: timestamp;
}

FA-18: Revenue Recognition Events

Status: ✅ Implemented (FA-18 Phase 2 WS3, 2026-04-25)
Spec Reference: FA-18 (Revenue Recognition Advanced)

Event 1: fa_revenue_recognized

Publisher: FA (Finance & Accounting)
Subscribers: FA-02 (GL), FA-05 (AR), FA-13 (Projects)
Payload Schema:
{
  event_name: 'fa_revenue_recognized';
  organization_id: uuid;
  recognition_id: uuid;
  revenue_schedule_id: uuid;
  revenue_contract_id: uuid;
  fiscal_period_id: uuid;
  recognition_date: date;     // processing date
  recognition_amount: number;
  journal_entry_id: uuid | null;
  journal_entry_line_id: uuid | null;
  auto_posted: boolean;
  user_id: uuid | null;
  timestamp: string;          // ISO-8601
}
Notes: Published atomically with the fa_revenue_recognitions insert by fa_process_revenue_recognition (writes to fw_domain_events). journal_entry_* populated only when both revenue & deferred accounts resolve (schedule → contract → module defaults). auto_posted reflects fa_module_settings.auto_post_revenue_recognition. Canonical narrative: FA-18-revenue-recognition-advanced-INTEGRATION.md.

Event 2: fa_revenue_schedule_completed

Publisher: FA (Finance & Accounting)
Subscribers: FA-05 (AR), FA-13 (Projects), LO (Leadership OS metrics)
Payload Schema:
{
  event_name: 'fa_revenue_schedule_completed';
  organization_id: uuid;
  revenue_schedule_id: uuid;
  revenue_contract_id: uuid;
  total_revenue_amount: number;
  total_recognized: number;
  completed_at: string;       // ISO-8601
  user_id: uuid | null;
  timestamp: string;
}
Notes: Emitted in the same transaction as the recognition that drives the schedule’s running total to within tolerance of total_revenue_amount. Tolerance comes from fa_module_settings.revenue_recognition_sum_tolerance (default 0.01).

FA-19: Financial Close Events

Status: 📝 Planned
Spec Reference: FA-19 (Financial Close Management)

Event 1: close_period_started

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications), FA-02 (GL)
Payload Schema:
{
  event_type: 'close_period_started';
  organization_id: uuid;
  close_period_id: uuid;
  period_name: string;
  started_at: timestamp;
}

Event 2: close_period_completed

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications), FA-07 (Financial Reporting)
Payload Schema:
{
  event_type: 'close_period_completed';
  organization_id: uuid;
  close_period_id: uuid;
  period_name: string;
  completed_at: timestamp;
}

Event 3: close_task_assigned

Publisher: FA (Finance & Accounting)
Subscribers: PF-10 (Notifications)
Payload Schema:
{
  event_type: 'close_task_assigned';
  organization_id: uuid;
  close_task_id: uuid;
  assigned_to: uuid;
  assigned_at: timestamp;
}

LO Core: Leadership Operating System Events

LO-01: Vision & Strategic Planning Events

Event: rock_completed Publisher: LO (Leadership Operating System) Subscribers: FA (Finance - financial goals), PF-10 (Notifications), PF-04 (Audit) Status: ✅ Complete
Implemented: 2025-12-03
Payload Schema:
{
  event_type: 'rock_completed';
  organization_id: uuid;
  rock_id: uuid;
  completed_date: date;
  owner_id: uuid;
  strategic_goal_id?: uuid;
  timestamp: timestamptz;
}
Purpose: Notify when Rock is completed (may trigger financial goals)

LO-04: To-Dos & Task Management Events

Event 1: todo_created
Publisher: LO (Leadership Operating System)
Subscribers: PF-10 (Notifications)
Status: ✅ Complete
Implemented: 2025-12-03
Payload Schema:
{
  event_type: 'todo_created';
  organization_id: uuid;
  todo_id: uuid;
  title: string;
  assigned_to: uuid;
  assigned_by: uuid;
  due_date?: date;
  rock_id?: uuid;
  issue_id?: uuid;
  meeting_id?: uuid;
  timestamp: timestamptz;
}
Event 2: todo_completed
Status: ✅ Complete
Implemented: 2025-12-03
Payload Schema:
{
  event_type: 'todo_completed';
  organization_id: uuid;
  todo_id: uuid;
  completed_date: date;
  assigned_to: uuid;
  rock_id?: uuid;
  timestamp: timestamptz;
}
Event 3: todo_overdue
Status: ✅ Complete
Implemented: 2025-12-03
Payload Schema:
{
  event_type: 'todo_overdue';
  organization_id: uuid;
  todo_id: uuid;
  title: string;
  assigned_to: uuid;
  due_date: date;
  days_overdue: number;
  timestamp: timestamptz;
}

LO-05: Scorecards & KPI Tracking Events

Event 1: scorecard_updated
Status: ✅ Complete
Implemented: 2025-12-03
Event 2: metric_threshold_breached
Status: ✅ Complete
Implemented: 2025-12-03

LO-06: Structured Meetings Events

Event 1: meeting_scheduled
Status: ✅ Complete
Implemented: 2025-12-03
Event 2: meeting_completed
Status: ✅ Complete
Implemented: 2025-12-03
Event 3: action_item_created
Status: ✅ Complete
Implemented: 2025-12-03

LO-07: Issues & Problem Solving Events

Event 1: issue_identified
Status: ✅ Complete
Event 2: issue_resolved
Status: ✅ Complete

LO-09: Assessments & Surveys Events

Event 1: assessment_distributed
Status: ✅ Complete
Implemented: 2025-12-03
Event 2: assessment_completed
Status: ✅ Complete
Implemented: 2025-12-03

Planned Events

RH-01: Resident Admission Events

Event (canonical): rh_resident_admitted
Deprecated alias: resident_admitted (do not use in new code) Publisher: RH (Recovery Housing) Subscribers: FA (Finance & Revenue), PM (POS derivation for charge capture) Persistence: fw_domain_events (SECURITY DEFINER trigger on rh_episodes) Status: 🟡 Implemented (DB persistence); FA/PM batch consumers 📋 Planned Spec Reference: RH-01 Census, Beds & Episodes · RH-01.1 Bed Board & Facility Types Integration Doc: RH-01-bed-board-census-INTEGRATION.md
Payload Schema:
{
  event_name: 'rh_resident_admitted';
  timestamp: string;             // ISO 8601 / timestamptz
  organization_id: string;       // UUID
  site_id?: string;              // UUID — site-scoped when applicable
  correlation_id?: string;       // UUID — when event chaining
  episode_id: string;            // UUID — episode-based model
  resident_profile_id: string;   // UUID
  residence_id: string;          // UUID
  bed_id: string;                // UUID
  admission_date: string;        // ISO date
  user_id: string;               // UUID — staff member who performed the admission (audit/accountability)
  // facility_type is used by PM to derive Place of Service:
  //   recovery_housing       → POS 55 (Residential SUD)
  //   psychiatric_residential → POS 56 (Psychiatric residential / RTC / BHRF)
  //   inpatient_unit          → POS 51 (Inpatient psychiatric)
  facility_type: 'recovery_housing' | 'psychiatric_residential' | 'inpatient_unit';
  agreement_id?: string;         // UUID — if agreement already created at admission
  resident_agreement?: {
    agreement_id: string;
    payment_terms: {
      amount: number;
      frequency: 'weekly' | 'bi_weekly' | 'monthly';
      start_date: string;
      due_day_of_month?: number;
      payment_methods: ('check' | 'ach' | 'card' | 'cash')[];
      late_fee_amount?: number;
      grace_period_days?: number;
    };
  };
}
Purpose: FA Core creates billing account and sets up recurring invoice schedule. PM uses facility_type to derive POS for charge capture (PM-07). user_id captures the staff member who performed the admission for audit and accountability. Consumer implementation note: FA should follow the fa-consume-pm-payment-events batch pattern (read fw_domain_events, idempotency log per event id) — dedicated fa-consume-rh-episode-events function 📋 Planned until FA episode AR schema is finalized.

RH-01: Resident Discharge Events

Event (canonical): rh_resident_discharged
Deprecated alias: resident_discharged Publisher: RH (Recovery Housing) Subscribers: FA (Finance & Revenue), PM (census/bed-day billing finalization) Persistence: fw_domain_events (trigger on rh_episodes) Status: 🟡 Implemented (DB persistence); FA/PM batch consumers 📋 Planned Spec Reference: RH-01 Census, Beds & Episodes · RH-01.1 Bed Board & Facility Types Integration Doc: RH-01-bed-board-census-INTEGRATION.md
Payload Schema:
{
  event_name: 'rh_resident_discharged';
  timestamp: string;             // ISO 8601 / timestamptz
  organization_id: string;
  site_id?: string;
  correlation_id?: string;
  episode_id: string;
  resident_profile_id: string;
  residence_id: string;
  discharge_date: string;
  user_id: string;               // UUID — staff member who performed the discharge (audit/accountability)
  discharge_type: 'planned' | 'ama' | 'non_compliance' | 'completion' | 'extension';
  facility_type: 'recovery_housing' | 'psychiatric_residential' | 'inpatient_unit';
  actual_length_of_stay_days: number;
  exit_destination?: string;
  final_balance?: {
    outstanding_balance: number;
    last_payment_date?: string;
    last_payment_amount?: number;
  };
}
Purpose: FA Core finalizes billing and closes billing account. PM uses facility_type and actual_length_of_stay_days for bed-day billing reconciliation. user_id captures the staff member who performed the discharge for audit and accountability.

RH-01: Bed Assignment Events

Event (target canonical): rh_bed_assigned
Deprecated alias: bed_assigned
Publisher: RH (Recovery Housing) Subscribers: HR (workload/census update) Persistence: ✅ Now in KnownEventName — trigger when HR consumer is scheduled Status: 📝 Planned (RH-01.1 Implementation) Spec Reference: RH-01.1 Bed Board & Facility Types Integration Doc: RH-01-bed-board-census-INTEGRATION.md
Payload Schema:
{
  event_name: 'rh_bed_assigned';
  timestamp: string;             // ISO 8601 / timestamptz
  organization_id: string;
  site_id?: string;
  correlation_id?: string;
  episode_id: string;
  bed_id: string;
  residence_id: string;
  user_id: string;               // UUID — staff member who assigned the bed (audit/accountability)
  facility_type: 'recovery_housing' | 'psychiatric_residential' | 'inpatient_unit';
  unit_label?: string;   // Non-null for inpatient_unit
  assigned_at: string;
}
Purpose: HR updates workload/staffing census when a bed is assigned. user_id captures the staff member who performed the assignment for audit and accountability.

RH-01: Bed Released Events

Event (target canonical): rh_bed_released
Deprecated alias: bed_released Publisher: RH (Recovery Housing) Subscribers: HR (workload/census update) Persistence: ✅ Now in KnownEventName Status: 📝 Planned (RH-01.1 Implementation) Spec Reference: RH-01.1 Bed Board & Facility Types Integration Doc: RH-01-bed-board-census-INTEGRATION.md
Payload Schema:
{
  event_name: 'rh_bed_released';
  timestamp: string;             // ISO 8601 / timestamptz
  organization_id: string;
  site_id?: string;
  correlation_id?: string;
  episode_id: string;
  bed_id: string;
  residence_id: string;
  user_id: string;               // UUID — staff member who released the bed (audit/accountability)
  facility_type: 'recovery_housing' | 'psychiatric_residential' | 'inpatient_unit';
  released_at: string;
}
Purpose: HR updates workload/staffing census when a bed is released after discharge. user_id captures the staff member who performed the release for audit and accountability.

RH-01: Invoice Creation Requested Events

Event (canonical): rh_invoice_creation_requested
Legacy alias (deprecated): invoice_creation_requested — maintained for backward compatibility but should migrate to canonical name
Publisher: RH (Recovery Housing) Subscribers: FA (Finance & Revenue) Channel: rh_events Status: 📝 Planned (RH-01 Implementation) Spec Reference: RH-01 Census, Beds & Episodes Integration Doc: RH-01-bed-board-census-INTEGRATION.md
Payload Schema:
{
  event_type: 'rh_invoice_creation_requested'; // Canonical name; legacy 'invoice_creation_requested' deprecated
  timestamp: string;             // ISO 8601 / timestamptz
  organization_id: string;
  site_id?: string;
  correlation_id?: string;
  episode_id: string;
  resident_profile_id: string;
  residence_id: string;
  agreement_id: string;
  user_id?: string;              // UUID — present when a staff member manually triggers invoice creation; omitted when auto-generated by the billing schedule
  payment_amount: number;
  payment_frequency: 'weekly' | 'bi_weekly' | 'monthly';
  payment_start_date: string;
  due_day_of_month?: number;
  payment_methods: string[];
  late_fee_amount: number;
  grace_period_days: number;
  admission_date: string;
  facility_type: 'recovery_housing' | 'psychiatric_residential' | 'inpatient_unit';
}
Purpose: FA creates the first invoice based on the resident agreement payment terms. facility_type helps FA tag invoices by service line for financial reporting. user_id is present when a staff member manually triggers invoice creation; omitted when auto-generated by the billing schedule.

RH-03: Critical Incident Events

Event 1 (canonical): rh_critical_significant_event_reported
Legacy alias (deprecated): critical_significant_event_reported
Publisher: RH (RH-03 Safety Events & Compliance)
Subscribers: PF-10 (notifications)
Channel: rh_events
Status: 📝 Planned
Spec Reference: RH-03 Safety Events & Compliance
Integration Doc: RH-03-safety-events-compliance-INTEGRATION.md
Payload Schema:
{
  event_type: 'rh_critical_significant_event_reported';
  significant_event_id: uuid;
  organization_id: uuid;
  episode_id: uuid;
  severity: 'critical';
  occurred_at: timestamptz;
  correlation_id?: uuid;
}
Event 2 (canonical): rh_significant_event_investigation_completed
Legacy alias (deprecated): significant_event_investigation_completed
Publisher: RH (RH-03 Safety Events & Compliance)
Subscribers: PF-10, RH compliance/reporting consumers
Channel: rh_events
Status: 📝 Planned
Spec Reference: RH-03 Safety Events & Compliance
Integration Doc: RH-03-safety-events-compliance-INTEGRATION.md
Payload Schema:
{
  event_type: 'rh_significant_event_investigation_completed';
  significant_event_id: uuid;
  investigation_id: uuid;
  organization_id: uuid;
  completed_at: timestamptz;
  correlation_id?: uuid;
}
Event 3 (canonical): rh_uds_test_positive
Legacy alias (deprecated): uds_test_positive
Publisher: RH (RH-03 Safety Events & Compliance)
Subscribers: RH-03 relapse/event workflows, PF-10 notifications
Channel: rh_events
Status: 📝 Planned
Spec Reference: RH-03 Safety Events & Compliance
Integration Doc: RH-03-safety-events-compliance-INTEGRATION.md
Payload Schema (consent-safe identifier-only):
{
  event_type: 'rh_uds_test_positive';
  uds_test_id: uuid;
  organization_id: uuid;
  episode_id: uuid;
  tested_at: timestamptz;
  correlation_id?: uuid;
}
Part 2 / consent handling: Subscribers MUST NOT expect substances or narrative test detail in this payload. Consumers must perform an RH-controlled, consent-gated read (RH-04 EN-4) before retrieving UDS result details.

RH-04: Resident Billing Events

Event: resident_charge_created
Publisher: RH (Recovery Housing)
Subscribers: FA-05 (Accounts Receivable)
Status: 📝 Planned (RH-04 Implementation)
Spec Reference: FA-05: Accounts Receivable & Revenue Recognition
Payload Schema:
{
  event_type: 'resident_charge_created';
  resident_id: uuid;
  charge_id: uuid;
  charge_date: date;
  amount: number;
  description: string;
  account_id: uuid;  // Revenue account
  organization_id: uuid;
  site_id: uuid;
  user_id: uuid;  // ID of the user who created the charge (for audit trail)
  timestamp: timestamptz;
}
Purpose: FA-05 auto-generates invoices from resident charges. When RH-04 publishes this event, FA-05 creates an invoice for the resident’s linked customer record, posts it to GL, and links the invoice to the source charge for traceability. Consumer Actions:
  1. FA-05 looks up resident → customer mapping
  2. Creates invoice with charge as line item
  3. Sets invoice status to “sent” and auto-posts to GL (DR AR, CR Revenue)
  4. Links invoice to source charge via fa_invoices.source_charge_id
  5. Sends notification to billing coordinator (PF-10)
Implementation Notes:
  • Event contract defined in FA-05 spec (Section 9: Integration Points)
  • Database schema ready: fa_invoices.source_charge_id column exists
  • Event consumer implementation pending RH-04 completion
  • Batch processing support for 100+ charges/day
  • CRITICAL: The database trigger that emits this event MUST capture the creating user’s ID from the session/context (e.g., using auth.uid() or current_setting('request.jwt.claims', true)::json->>'sub') and populate the user_id field in the emitted event payload. This ensures the audit trail is preserved and traceable to the specific user who created the charge.

RH-06: Compliance Events

Event 1: compliance_deadline_approaching
Publisher: RH (Recovery Housing)
Subscribers: PF-10 (Notifications)
Status: 📝 Planned
Spec Reference: RH-06 (Compliance Tracking & Staff Operations)
Payload Schema:
{
  compliance_requirement_id: uuid;
  organization_id: uuid;
  due_date: date;
  days_until_due: number;
}
Purpose: Send compliance deadline reminders 7 days before due date Event 2: non_compliance_detected
Publisher: RH (Recovery Housing)
Subscribers: PF-10 (Notifications)
Status: 📝 Planned
Payload Schema:
{
  compliance_requirement_id: uuid;
  organization_id: uuid;
  residence_id?: uuid;
  non_compliance_reason: string;
}
Purpose: Alert management to non-compliance issues

FA-01: Payment Received Events

Event: payment_received
Publisher: FA (Finance & Revenue)
Subscribers: RH (Recovery Housing)
Status: 📝 Planned (FA-01 Implementation)
Payload Schema:
{
  event_type: 'payment_received';
  event_timestamp: timestamp;
  organization_id: uuid;
  episode_id: uuid;
  payment_id: uuid;
  payment_amount: number;
  payment_method: 'cash' | 'check' | 'card' | 'ach' | 'other';
  payment_date: date;
  new_balance: number;
  payment_status: 'current' | 'past_due' | 'paid_in_full';
}
Purpose: RH Core updates cached payment status based on received payments

HR-01: Employee Assignment Events

Event: employee_assigned_to_site Publisher: HR (Workforce) Subscribers: RH (Recovery Housing) Channel: hr_events Status: 📝 Planned (RH-06 Implementation, Q2 2026) Payload Schema:
{
  employee_id: uuid;
  site_id: uuid;
  organization_id: uuid;
  assignment_date: timestamp;
  role: 'staff' | 'manager' | 'admin';
  department_id?: uuid;
}
Purpose: RH Core receives notifications when staff are assigned to recovery housing sites

HR-01: Employee Created Events

Event: employee_created Publisher: HR (Workforce) Subscribers: GR (Governance & Risk) Channel: hr_events Status: 📝 Planned (Q2 2026) Payload Schema:
{
  employee_id: uuid;
  organization_id: uuid;
  department_id?: uuid;
  position_id?: uuid;
  hire_date: timestamp;
  is_clinical: boolean;
}
Purpose: GR Core assigns default policies and training requirements to new employees

LO-01: Vision & Strategic Planning Events (Planned)

Event: vision_updated
Status: 📝 Planned (LO-01 Implementation)
Event: strategic_goal_created
Status: 📝 Planned (LO-01 Implementation)
Event: rock_created
Status: 📝 Planned (LO-01 Implementation)

LO-02: Accountability Chart Events (Planned)

Event: role_assigned
Status: 📝 Planned (LO-02 Implementation)
Event: accountability_chart_updated
Status: 📝 Planned (LO-02 Implementation)

LO-08: Feedback & 1-on-1s Events (Planned)

Event: one_on_one_scheduled
Status: 📝 Planned (LO-08 Implementation)
Event: feedback_submitted
Status: 📝 Planned (LO-08 Implementation)

LO-10: Knowledge Portal Events (Planned)

Event: knowledge_article_created
Status: 📝 Planned (LO-10 Implementation)
Event: process_updated
Status: 📝 Planned (LO-10 Implementation)

LO-16: Goals & Actions Event Integration (Planned)

Event: goal_created
Publisher: LO (Leadership Operating System)
Subscribers: FA (budget planning), GR (compliance), FW (workflow linking)
Status: 📝 Planned (LO-16 Implementation)
Payload Schema:
{
  event_type: 'goal_created';
  payload: {
    goal_id: uuid;
    goal_title: string;
    goal_quarter: string;
    goal_fiscal_year: number;
    organization_id: uuid;
    site_id?: uuid;
    created_by: uuid;
    executive_sponsor_id?: uuid;
    strategic_goal_id?: uuid;
    created_at: timestamptz;
  };
  timestamp: timestamptz;
}
Event: goal_completed
Publisher: LO
Subscribers: RH (program metrics), FA (financial tracking), GR (compliance tracking)
Status: 📝 Planned (LO-16 Implementation)
Payload Schema:
{
  event_type: 'goal_completed';
  payload: {
    goal_id: uuid;
    goal_title: string;
    goal_quarter: string;
    organization_id: uuid;
    completed_by: uuid;
    completed_at: timestamptz;
    progress_percentage: number;
    smart_score?: number;
  };
  timestamp: timestamptz;
}
Event: action_assigned
Publisher: LO
Subscribers: HR (employee development), PF-10 (notifications)
Status: 📝 Planned (LO-16 Implementation)
Payload Schema:
{
  event_type: 'action_assigned';
  payload: {
    action_id: uuid;
    goal_id: uuid;
    action_title: string;
    organization_id: uuid;
    assigned_to: uuid;
    assigned_by: uuid;
    assigned_at: timestamptz;
  };
  timestamp: timestamptz;
}
Event: action_completed
Publisher: LO
Subscribers: LO-14 (unblock dependencies), PF-10 (notifications)
Status: 📝 Planned (LO-16 Implementation)
Payload Schema:
{
  event_type: 'action_completed';
  payload: {
    action_id: uuid;
    goal_id: uuid;
    action_title: string;
    organization_id: uuid;
    completed_by: uuid;
    completed_at: timestamptz;
    actual_hours?: number;
  };
  timestamp: timestamptz;
}
Implementation:
  • Events published via lo_events channel (pg_notify)
  • Database triggers on lo_quarterly_rocks and lo_rock_milestones
  • Events logged to pf_audit_logs for audit trail
  • Consumer examples provided for RH, FA, GR, FW modules
Related Spec: specs/lo/LO-16-goals-event-integration.md

Planned Events (GR Core)

GR-01: Policy Management Events

Event 1: policy_created
Publisher: GR (Governance & Compliance)
Subscribers: GR-02 (Training assignments), GR-03 (Compliance evidence)
Status: 📝 Planned (GR-01 Implementation)
Spec Reference: GR-01 Policy Management
Payload Schema:
{
  event_type: 'policy_created';
  policy_id: uuid;
  organization_id: uuid;
  site_id?: uuid;
  title: string;
  category: string;
  status: 'draft' | 'review' | 'approved';
  effective_date: date;
  created_by: uuid;
  timestamp: timestamptz;
}
Event 2: policy_acknowledged
Publisher: GR (Governance & Compliance)
Subscribers: GR-02 (Training compliance), GR-03 (Compliance tracking)
Status: 📝 Planned (GR-01 Implementation)
Payload Schema:
{
  event_type: 'policy_acknowledged';
  acknowledgment_id: uuid;
  policy_id: uuid;
  employee_id: uuid;
  organization_id: uuid;
  acknowledged_at: timestamptz;
  policy_version: string;
  timestamp: timestamptz;
}

GR-02: Training & CEU Tracking Events

Event: training_completed Publisher: GR (Governance & Compliance) Subscribers: GR-03 (Compliance evidence), HR-02 (Credentialing) Status: ✅ Implemented (GR-02-EN-01, 2026-05-01) Spec Reference: GR-02 Training & CEU Tracking Channel / Transport: gr_events (pg_notify) + direct HTTP fan-out via pg_net (see “Delivery bridge” below) Trigger: gr_on_training_completed (AFTER INSERT on gr_training_completions) → public.gr_publish_training_completed() (SECURITY DEFINER) Consumers (HTTP):
  • hr-training-credential-refresh — recomputes ce_hours_completed on employee credentials
  • gr-evidence-from-training — inserts deduplicated gr_compliance_evidence rows for linked requirements
Delivery bridge (2026-05-01): After publishing to pg_notify('gr_events', ...) the trigger calls public.gr_dispatch_training_event('training_completed', payload) (SECURITY DEFINER, service_role-only EXECUTE). The dispatcher reads project_url and service_role_key from vault.decrypted_secrets and issues two net.http_post calls — one to /functions/v1/gr-evidence-from-training and one to /functions/v1/hr-training-credential-refresh — with X-Correlation-Id propagated from the publisher’s correlation ID. Each HTTP call is wrapped in its own BEGIN…EXCEPTION block and any failure is logged with RAISE WARNING so dispatcher errors never block the originating INSERT. The pg_notify channel is preserved for back-compat and unit-test contracts. Migration: supabase/migrations/20260501114741_*.sql. Idempotency: Consumers rely on partial unique index gr_compliance_evidence_org_req_src_uq on (organization_id, requirement_id, source_reference) so retried deliveries are safe. PHI/PII: Payload contains identifiers and aggregate CEU credit only — no patient data, no employee names, no certificate content. Payload Schema:
{
  event_type: 'training_completed';
  enrollment_id: uuid;
  course_id: uuid;
  employee_profile_id: uuid;
  organization_id: uuid;
  completion_date: date;
  ceu_credits: number;
  certificate_issued: boolean;
  // Linkage resolved by the publisher trigger from gr_training_requirement_links
  // and gr_training_policy_links (arrays may be empty, never null)
  requirement_ids: uuid[];
  policy_ids: uuid[];
  timestamp: timestamptz;
}

Event: enrollment_overdue Publisher: GR (Governance & Compliance) Subscribers: GR-03 (Compliance evidence / status), HR-02 (Credentialing risk), PF notifications Status: ✅ Implemented (GR-02-EN-01, 2026-05-01) Spec Reference: GR-02-EN-01 Training Events Channel / Transport: gr_events (pg_notify) + HTTP dispatcher placeholder via pg_net Trigger: gr_on_enrollment_overdue (BEFORE UPDATE on gr_training_enrollments) → public.gr_publish_enrollment_overdue() (SECURITY DEFINER) Delivery bridge (2026-05-01): Trigger also calls public.gr_dispatch_training_event('enrollment_overdue', payload). No HTTP consumer is wired yet — the dispatcher currently emits a RAISE NOTICE placeholder. Follow-up work will fan out to a notification / supervisor-escalation edge function. Idempotency: The trigger fires only on transitions where NEW.status = 'overdue' AND OLD.status IS DISTINCT FROM 'overdue' AND overdue_event_published_at IS NULL. The trigger sets overdue_event_published_at = now() in the same row update, guaranteeing at most one publication per enrollment per overdue cycle. PHI/PII: Identifiers and due-date metadata only — no employee name or course content. Payload Schema:
{
  event_type: 'enrollment_overdue';
  enrollment_id: uuid;
  course_id: uuid;
  employee_profile_id: uuid;
  organization_id: uuid;
  due_date: date;
  days_overdue: number;        // computed at publish time (>= 0)
  previous_status: string;     // OLD.status, e.g. 'in_progress' | 'not_started'
  timestamp: timestamptz;
}
Audit: Both publishers best-effort insert into pf_audit_logs with a generated correlation ID (failures swallowed so trigger does not block the originating write).

GR-02-EN-04 (PF-96 → CE requirement library)

Event Name: Consumes pf_jurisdiction_profile_changed from PF-96; no new emitted event Publisher: PF-96 (Jurisdiction Profiles) Subscribers: GR-02 training requirement catalog service Status: 📝 Planned Spec Reference: GR-02-EN-04 Purpose: GR-02 training requirement catalogs consume PF-96 jurisdiction profile metadata to align with CE-facing requirement libraries. No new cross-core event is emitted; GR-02 subscribes to the existing pf_jurisdiction_profile_changed event. Payload Schema (consumed from PF-96):
{
  event_type: 'pf_jurisdiction_profile_changed';
  jurisdiction_id: uuid;
  jurisdiction_code: string;
  organization_id: uuid;
  profile_data: {
    training_requirements?: {
      required_hours?: number;
      renewal_period?: string;
      specialty_requirements?: Record<string, unknown>;
    };
    // Additional jurisdiction-specific profile fields
  };
  changed_at: timestamptz;
  timestamp: timestamptz;
}
Implementation Location: GR-02 training requirement catalog service (event subscriber logic)

GR-03: Compliance Tracking Events

Event 1: requirement_created
Publisher: GR (Governance & Compliance)
Subscribers: GR-04 (Audit checklists), GR-06 (AI assistance)
Status: 📝 Planned (GR-03 Implementation)
Spec Reference: GR-03 Compliance Tracking
Event 2: compliance_status_changed
Publisher: GR (Governance & Compliance)
Subscribers: GR-04 (Audit readiness), GR-05 (Risk assessment), GR-06 (AI monitoring)
Status: 📝 Planned (GR-03 Implementation)
Payload Schema:
{
  event_type: 'compliance_status_changed';
  check_id: uuid;
  requirement_id: uuid;
  organization_id: uuid;
  old_status: 'compliant' | 'non_compliant' | 'pending';
  new_status: 'compliant' | 'non_compliant' | 'pending';
  changed_at: timestamptz;
  timestamp: timestamptz;
}

GR-04: Audit Management Events

Event 1: audit_created
Publisher: GR (Governance & Compliance)
Subscribers: GR-06 (AI assistance)
Status: 📝 Planned (GR-04 Implementation)
Spec Reference: GR-04 Audit Management
Event 2: audit_finding_created
Publisher: GR (Governance & Compliance)
Subscribers: GR-05 (Risk assessment), GR-06 (AI monitoring)
Status: 📝 Planned (GR-04 Implementation)
Payload Schema:
{
  event_type: 'audit_finding_created';
  finding_id: uuid;
  audit_id: uuid;
  organization_id: uuid;
  severity: 'low' | 'medium' | 'high' | 'critical';
  finding_type: string;
  created_at: timestamptz;
  timestamp: timestamptz;
}

GR-05: Risk Assessment Events

Event 1: risk_created
Publisher: GR (Governance & Compliance)
Subscribers: GR-06 (AI assistance)
Status: 📝 Planned (GR-05 Implementation)
Spec Reference: GR-05 Risk Assessment
Event 2: risk_assessed
Publisher: GR (Governance & Compliance)
Subscribers: GR-06 (AI monitoring)
Status: 📝 Planned (GR-05 Implementation)
Payload Schema:
{
  event_type: 'risk_assessed';
  risk_id: uuid;
  organization_id: uuid;
  risk_score: number;
  risk_level: 'low' | 'medium' | 'high' | 'critical';
  assessed_at: timestamptz;
  timestamp: timestamptz;
}

GR-11: Procedures Management Events

Event 1: procedure_approved
Publisher: GR (Governance & Compliance)
Subscribers: GR-02 (Training), GR-03 (Compliance)
Status: ✅ Complete (GR-11 Implementation)
Spec Reference: GR-11 Procedures Management
Payload Schema:
{
  event_type: 'procedure_approved';
  procedure_id: uuid;
  organization_id: uuid;
  site_id?: uuid;          // Site scope if applicable
  user_id: uuid;           // User who approved
  title: string;
  category: string;
  implements_policy_id: uuid | null;
  approved_by: uuid;
  approved_at: timestamptz;
  correlation_id: string | null;
  timestamp: timestamptz;
}
Purpose: Notify when procedure is approved for use, enabling training assignments and compliance tracking Consumer Actions:
ConsumerActionStatus
GR-02 (Training)Create training assignment for new procedure📝 Planned
GR-03 (Compliance)Update compliance tracking for policy coverage📝 Planned
PF-10 (Notifications)Notify procedure owner and stakeholders📝 Planned
Testing Requirements:
  • Event fires when procedure status changes to ‘approved’
  • Payload includes all required fields including site_id
  • Event logged to pf_audit_logs
  • Tenant isolation verified (org_id matches)

Event 2: procedure_execution_completed
Publisher: GR (Governance & Compliance)
Subscribers: GR-03 (Compliance evidence)
Status: ✅ Complete (GR-11 Implementation)
Payload Schema:
{
  event_type: 'procedure_execution_completed';
  execution_id: uuid;
  procedure_id: uuid;
  organization_id: uuid;
  site_id?: uuid;          // Site scope if applicable
  user_id: uuid;           // Mirrors executed_by for consistency
  executed_by: uuid;
  completed_at: timestamptz;
  context_type: string | null;
  context_id: uuid | null;
  correlation_id: string | null;
  timestamp: timestamptz;
}
Purpose: Provide compliance evidence of procedure execution Consumer Actions:
ConsumerActionStatus
GR-03 (Compliance)Record execution as compliance evidence📝 Planned
PF-10 (Notifications)Notify procedure owner of completion📝 Planned
Testing Requirements:
  • Event fires when execution status changes to ‘completed’
  • Payload includes procedure and execution context
  • Event logged to pf_audit_logs
  • Related entity (context_type/context_id) included when available

Implementation:
  • Events published via gr_events channel (pg_notify)
  • Database triggers on gr_procedures (status change to ‘approved’) and gr_procedure_executions (status change to ‘completed’)
  • Events logged to pf_audit_logs for audit trail with user_id and correlation_id fields populated
  • Consumer examples provided for GR-02, GR-03 modules
Trigger Function Requirements:
  • All trigger functions that publish events to the gr_events channel MUST be created WITH SECURITY DEFINER
  • Coding Guideline: SQL trigger code for events must include SECURITY DEFINER clause
  • The trigger function owner and privileges must be set appropriately so the function can emit notifications even when invoked by less-privileged roles to remain compliant
  • Trigger functions must populate user_id from the current session context (e.g., auth.uid()) in addition to any role-specific fields like approved_by or executed_by
  • When events may chain (e.g., procedure approval triggers training assignment), trigger functions should generate and propagate correlation_id to enable event traceability

GR-06-EN-01: AI-Powered State Compliance Checking Events

Event: gr_state_gap_analysis_completed
Publisher: GR-06-EN-01 (Governance & Compliance)
Subscribers: PF-91 (compliance dashboard), PF-10 (notifications — critical gap alerts)
Channel / Transport: gr_events (pg_notify) — planned (align with other GR event publications); Kafka topic TBD if/when event bus externalizes
Status: 📝 Planned (Phase 4 — emit when state gap analysis completes)
Contract version: 1.0 (draft)
Spec / integration: GR-06-EN-01 · Integration
Payload schema (JSON fields):
FieldTypeRequiredDescription
event_typestringyesLiteral gr_state_gap_analysis_completed
event_iduuidyesUnique event ID for deduplication
organization_iduuidyesTenant scope
state_codestringyesJurisdiction state code (e.g. AZ)
domainstringyesOne of clinical, billing, compliance, training, comprehensive
compliance_scorenumberyes0–100
gap_countintegeryesCount of identified gaps
timestampstring (ISO 8601)yesEvent time (timestamptz)
correlation_idstring | nullnoTrace / workflow correlation
interface GrStateGapAnalysisCompletedPayload {
  event_type: 'gr_state_gap_analysis_completed';
  event_id: string; // UUID — canonical deduplication key
  organization_id: string; // UUID
  state_code: string;
  domain: 'clinical' | 'billing' | 'compliance' | 'training' | 'comprehensive';
  compliance_score: number; // 0–100
  gap_count: number;
  timestamp: string; // ISO 8601 timestamptz
  correlation_id?: string | null;
}
Consumer actions:
ConsumerActionStatus
PF-91Refresh compliance dashboard widgets / gap summaries📝 Planned
PF-10Notify compliance roles when gaps are critical📝 Planned

GR-12: Procedure Templates Library Events

Event 1: gr_template_instantiated
Publisher: GR (Governance & Compliance)
Subscribers: GR-03 (Compliance tracking), PF-10 (optional notification)
Status: 📝 Planned (GR-12 Implementation)
Spec Reference: GR-12 Procedure Templates Library
Payload Schema:
{
  event_type: 'gr_template_instantiated';
  template_id: uuid;
  procedure_id: uuid;          // newly created procedure
  organization_id: uuid;
  user_id: uuid;
  timestamp: timestamptz;
  correlation_id: string | null;
}
Purpose: Notify when a template is instantiated as a new procedure, enabling compliance tracking updates. Consumer Actions:
ConsumerActionStatus
GR-03 (Compliance)Update compliance coverage tracking📝 Planned
PF-10 (Notifications)Notify compliance officer of new procedure from template📝 Planned

Event 2: gr_template_contributed
Publisher: GR (Governance & Compliance)
Subscribers: GR-03 (Compliance tracking)
Status: 📝 Planned (GR-12 Implementation)
Payload Schema:
{
  event_type: 'gr_template_contributed';
  template_id: uuid;
  source_procedure_id: uuid;
  organization_id: uuid;
  user_id: uuid;
  timestamp: timestamptz;
  correlation_id: string | null;
}
Purpose: Notify when an approved procedure is contributed as an org-private template.

GR-07: Quality Improvement Events

Event: qi_project_created
Publisher: GR (Governance & Compliance)
Subscribers: GR-03 (Compliance tracking), GR-04 (Audit management)
Status: 📝 Planned (GR-07 Implementation)
Spec Reference: GR-07 Quality Improvement

GR-08: Accreditation Management Events

Event: accreditation_created
Publisher: GR (Governance & Compliance)
Subscribers: GR-03 (Compliance tracking), GR-04 (Audit management)
Status: 📝 Planned (GR-08 Implementation)
Spec Reference: GR-08 Accreditation Management

GR-15: Nonprofit Governance Controls Events

Status: ✅ Implemented
Implemented: 2026-03-12 (PR #1002 remediation)
Spec Reference: GR-15 Nonprofit Governance Controls

Event 1: gr_coi_cycle_launched

Publisher: GR (Governance & Compliance)
Subscribers: PF-10 (Notifications — reminder emails to attestation participants), GR-03 (Compliance tracking — annual COI completion)
Channel: gr_events
Status: ✅ Implemented
Payload Schema:
interface GrCoiCycleLaunchedPayload {
  event_type: 'gr_coi_cycle_launched';
  organization_id: string;    // UUID
  cycle_id: string;           // UUID — gr_coi_cycles record
  cycle_year: number;         // e.g. 2026
  due_date: string;           // ISO date — attestation deadline
  participant_count: number;  // Number of employees included
  launched_by: string;        // UUID — user who initiated
  timestamp: string;          // ISO 8601 timestamptz
  correlation_id?: string;    // UUID
}

Event 2: gr_whistleblower_report_submitted

Publisher: GR (Edge function: gr-whistleblower-submit)
Subscribers: PF-10 (Notifications — alert compliance officers), GR-03 (Compliance tracking)
Channel: gr_events
Status: ✅ Implemented
Payload Schema:
interface GrWhistleblowerReportSubmittedPayload {
  event_type: 'gr_whistleblower_report_submitted';
  organization_id: string;    // UUID
  report_id: string;          // UUID — gr_whistleblower_reports record
  category: string;           // e.g. 'financial', 'safety', 'compliance', 'other'
  is_anonymous: boolean;      // Whether submitter opted for anonymity
  timestamp: string;          // ISO 8601 timestamptz
  // NOTE: No PII fields — reporter identity is never included in event payload
}

CL-07-EN-01: Zero Suicide Framework Events

Event 1: cl_safety_plan_shared
Channel: cl_events
Publisher: CL (CL-07-EN-01 Zero Suicide Framework)
Subscribers: PF-10 (Notifications — notify shared contacts), workflow listeners
Status: 📝 Planned
PHI Restrictions: UUIDs only (safety_plan_id, patient_id). No patient names, DOB, SSN, or clinical detail.
Payload Schema:
{
  event_type: 'cl_safety_plan_shared';
  organization_id: uuid;
  timestamp: timestamptz;
  patient_id: uuid;
  safety_plan_id: uuid;
  shared_by: uuid;
  shared_at: timestamptz;
  correlation_id?: uuid;
}
ConsumerActionStatus
PF-10 NotificationsSend notification to clinician/support network with signed URL in action_url📝 Planned

Event 2: cl_zero_suicide_followup_scheduled
Channel: cl_events
Publisher: CL (CL-07-EN-01 Zero Suicide Framework)
Subscribers: PM scheduling views, PF-10 (reminders)
Status: 📝 Planned
PHI Restrictions: UUIDs only (patient_id, encounter_id). No patient names, DOB, SSN, or clinical detail.
Payload Schema:
{
  event_type: 'cl_zero_suicide_followup_scheduled';
  organization_id: uuid;
  timestamp: timestamptz;
  patient_id: uuid;
  followup_type: string;       // '24h' | '48h' | '72h'
  scheduled_for: timestamptz;
  encounter_id?: uuid;
  correlation_id?: uuid;
}
ConsumerActionStatus
PM SchedulingDisplay follow-up in scheduling views📝 Planned
PF-10 NotificationsSend reminder to assigned clinician📝 Planned

CL–GR Bridge Events (Incident Bridge)

Contract Source: Full event contract, payload schema, security requirements, and testing requirements are in CL-GR-CLINICAL-INCIDENT-INTEGRATION.md.
Regulatory driver: AHCCCS AMPM 1620-O; ARS 46-454; 42 CFR 482.13; CARF; Joint Commission EC.04.01.01.
Event 1: cl_safety_plan_activated
Channel: cl_events
Publisher: CL (CL-07 Suicide Risk Screening & Safety Planning)
Subscribers: GR (GR-08/GR-09 Incident Reporting — creates draft incident)
Status: 📝 Planned
PHI Restrictions: UUIDs only (chart_id, safety_plan_id, encounter_id). No patient names, DOB, SSN, or clinical detail.
Payload Schema:
{
  event_type: 'cl_safety_plan_activated';
  organization_id: uuid;
  timestamp: timestamptz;
  site_id?: uuid;
  user_id?: uuid;
  chart_id: uuid;
  safety_plan_id?: uuid;
  encounter_id?: uuid;
  correlation_id?: uuid;
}
ConsumerActionStatus
GR-08/GR-09Create draft incident report; type = safety_plan_activation; link chart/safety_plan📝 Planned

Event 2: cl_restraint_event_documented
Channel: cl_events
Publisher: CL (CL-13 Crisis Intervention Documentation, when implemented)
Subscribers: GR (GR-08/GR-09 — creates draft incident per 42 CFR 482.13)
Status: 📝 Planned
PHI Restrictions: UUIDs only. No patient names, DOB, SSN, or clinical detail.
Payload Schema:
{
  event_type: 'cl_restraint_event_documented';
  organization_id: uuid;
  timestamp: timestamptz;
  site_id?: uuid;
  user_id?: uuid;
  chart_id: uuid;
  encounter_id?: uuid;
  restraint_type: 'restraint' | 'seclusion';
  correlation_id?: uuid;
}
ConsumerActionStatus
GR-08/GR-09Create draft incident report; type = restraint_seclusion; link chart/encounter📝 Planned

Event 3: gr_incident_created
Channel: gr_events
Publisher: GR (GR-08/GR-09 Incident Reporting)
Subscribers: CL (chart flag — open documentation requirement indicator)
Status: ✅ Implemented
PHI Restrictions: UUIDs only (chart_id when patient-related). No patient names, DOB, SSN, or clinical detail.
Payload Schema:
{
  event_type: 'gr_incident_created';
  organization_id: uuid;
  timestamp: timestamptz;
  site_id?: uuid;
  incident_id: uuid;
  chart_id?: uuid;          // when incident is patient-related
  incident_type?: string;
  correlation_id?: uuid;
}
ConsumerActionStatus
CLSet chart-level flag “open documentation required” / “related incident”; link to incident_id📝 Planned
Security and Resilience (all three bridge events): Tenant Validation Requirements:
  1. User-initiated flows: Must validate organization_id against JWT claims (current_setting('jwt.claims.organization_id')) before any writes. Client-side checks are insufficient; server-side validation is mandatory.
  2. Service-initiated/pg_notify flows: Use a trusted organization context and MUST call a server-side SECURITY DEFINER stored procedure that:
    • Enforces strict organization_id checks against the trusted context
    • Includes auditable assertions (log mismatches to pf_audit_logs)
    • Rejects mismatches with explicit errors
    • Service-role callers must be limited to least-privilege roles
    • Includes audit logging for all event consumptions
    • Uses exponential backoff retries with dead-letter queue handling for max-retry failures
  • All emissions and consumptions MUST be logged to pf_audit_logs with user_id, organization_id, timestamp, correlation_id.

GR-09: Incident Reporting Events

Event 1: incident_created
Publisher: GR (Governance & Compliance)
Subscribers: GR-05 (Risk assessment), GR-06 (AI monitoring)
Status: 📝 Planned (GR-09 Implementation)
Spec Reference: GR-09 Incident Reporting
Event 2: incident_resolved
Publisher: GR (Governance & Compliance)
Subscribers: GR-05 (Risk update), GR-06 (AI monitoring)
Status: 📝 Planned (GR-09 Implementation)
Payload Schema:
{
  event_type: 'incident_resolved';
  incident_id: uuid;
  organization_id: uuid;
  resolution_date: date;
  resolved_by: uuid;
  timestamp: timestamptz;
}

GR-10 / GR-UX-10: Contract management & contract creation wizard

See GR-10-contract-creation-INTEGRATION.md for contract management and contract creation wizard integration details. Event Contract Template (GR-10):
Event Name: None in v1
Publisher: None in v1
Subscribers: None in v1
Payload Schema: None in v1
Implementation Location: None in v1
Status: No events published in v1. Contract creation wizard (GR-UX-10) is local to GR core. Future integration candidates include FA (billing setup triggers) and workflow notifications. Spec Reference: GR-10 Contract Management, GR-UX-10 Contract Creation Wizard

GR-13: Procedure Analytics Events

Event 1: procedure_gap_identified
Channel: gr_events
Publisher: GR (GR-13 Procedure Analytics)
Subscribers: GR-07 (QI project candidate creation)
Status: 📝 Planned
Spec Reference: GR-13 Procedure Analytics
Payload Schema:
{
  event_type: 'procedure_gap_identified';
  organization_id: uuid;
  procedure_id: uuid;
  procedure_title: string;
  category: string;
  completion_rate_pct: number;   // 0–100
  overdue_count: number;
  exported_by: uuid;             // user UUID
  exported_at: timestamptz;      // ISO 8601
  correlation_id?: uuid;
  timestamp: timestamptz;
}
ConsumerActionStatus
GR-07Create draft gr_qi_projects row with status='draft', source_event_id={fw_domain_events.id}, custom_fields.source_procedure_id={procedure_id}; prefilled title / problem statement / suggested owner. Idempotent on (organization_id, source_event_id) + secondary guard on (organization_id, source_procedure_id, status='draft').✅ Complete (consumer shipped in GR-13-EN-01, 2026-04-19)
Purpose: Notifies GR-07 that a procedure compliance gap was identified via analytics and a QI project should be considered. Implementation note (2026-04-19): Publisher writes to fw_domain_events via publishEvent() (src/platform/events/publishEvent.ts). fw_workflow_events is the registry of event definitions, not the event log — the consumer subscribes to fw_domain_events rows where event_name = 'procedure_gap_identified'. The current payload does not include gap_kind / metric / threshold_breached (these were proposed in earlier drafts but never shipped); the consumer composes its initial problem statement from procedure_title, completion_rate_pct, and overdue_count.

Event Infrastructure

Generic Event Publisher:
CREATE FUNCTION publish_domain_event(_event_type TEXT, _payload JSONB)
RETURNS VOID AS $$
BEGIN
  PERFORM pg_notify('domain_events', json_build_object(
    'event_type', _event_type,
    'payload', _payload,
    'timestamp', now()
  )::text);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
Event Consumer Edge Function:
  • Location: supabase/functions/event-consumer/index.ts
  • Listens to domain_events channel
  • Logs all events to pf_audit_logs with:
    • module = ‘hr’ (or relevant core)
    • action = ‘domain_event’
    • table_name = source table
    • new_values = event payload
  • Future-ready for event handlers (commented code included)
Testing: ✅ Complete - All events logged correctly

Planned Events (IT Module)

The IT (Information Technology) module defines 18 planned events for asset management, support ticketing, vendor management, software licensing, security compliance, and procurement. Full IT event documentation: IT Integration Contracts

IT-01: Asset Management Events

Event 1: it_asset_purchased
Publisher: IT (IT-01 Asset Management)
Subscribers: FA (Finance - asset capitalization)
Status: ✅ Implemented
Last Verified: 2026-02-15
Spec Reference: IT-01 IT Asset Management
Payload Schema:
{
  event_type: 'it_asset_purchased';
  asset_id: uuid;
  asset_tag: string;
  asset_type: string;
  asset_name: string;
  purchase_cost: number;
  purchase_date: date;
  vendor_id: uuid;
  organization_id: uuid;
  site_id?: uuid;
  timestamp: timestamptz;
}
Implementation:
-- SECURITY DEFINER function definitions for IT asset triggers
CREATE OR REPLACE FUNCTION it_notify_asset_purchased()
RETURNS TRIGGER
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
BEGIN
  PERFORM pg_notify('it_asset_purchased', json_build_object(
    'event_type', 'it_asset_purchased',
    'asset_id', NEW.id,
    'asset_tag', NEW.asset_tag,
    'asset_type', NEW.asset_type,
    'asset_name', NEW.name,
    'purchase_cost', NEW.purchase_cost,
    'purchase_date', NEW.purchase_date,
    'vendor_id', NEW.vendor_id,
    'organization_id', NEW.organization_id,
    'site_id', NEW.site_id,
    'timestamp', now()
  )::text);
  RETURN NEW;
END;
$$;

CREATE OR REPLACE FUNCTION it_notify_asset_disposed()
RETURNS TRIGGER
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
BEGIN
  IF NEW.status = 'disposed' AND (OLD.status IS DISTINCT FROM 'disposed') THEN
    PERFORM pg_notify('it_asset_disposed', json_build_object(
      'event_type', 'it_asset_disposed',
      'asset_id', NEW.id,
      'asset_tag', NEW.asset_tag,
      'organization_id', NEW.organization_id,
      'timestamp', now()
    )::text);
  END IF;
  RETURN NEW;
END;
$$;

CREATE OR REPLACE FUNCTION it_notify_ticket_status_changed()
RETURNS TRIGGER
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public
AS $$
BEGIN
  IF NEW.status IS DISTINCT FROM OLD.status THEN
    PERFORM pg_notify('it_ticket_status_changed', json_build_object(
      'event_type', 'it_ticket_status_changed',
      'ticket_id', NEW.id,
      'old_status', OLD.status,
      'new_status', NEW.status,
      'organization_id', NEW.organization_id,
      'timestamp', now()
    )::text);
  END IF;
  RETURN NEW;
END;
$$;

CREATE TRIGGER it_asset_purchased_trigger
  AFTER INSERT OR UPDATE ON it_assets
  FOR EACH ROW
  EXECUTE FUNCTION it_notify_asset_purchased();
Event 2: it_asset_assigned
Publisher: IT (IT-01 Asset Management)
Subscribers: PF-10 (Notifications), HR
Status: ✅ Implemented
Event 3: it_asset_maintenance_required
Publisher: IT (IT-01 Asset Management)
Subscribers: FM (Facilities), PF-10 (Notifications)
Status: 📝 Planned
Event 4: it_asset_disposed
Publisher: IT (IT-01 Asset Management)
Subscribers: FA (Finance), GR (Governance)
Status: ✅ Implemented
Last Verified: 2026-02-15
Implementation:
CREATE TRIGGER it_asset_disposed_trigger
  AFTER UPDATE ON it_assets
  FOR EACH ROW
  EXECUTE FUNCTION it_notify_asset_disposed();
-- Fires when status changes to 'disposed'

IT-02: Support Ticketing Events

Event 1: it_ticket_created
Publisher: IT (IT-02 Support Ticketing)
Subscribers: PF-10 (Notifications)
Status: ✅ Implemented
Spec Reference: IT-02 IT Support & Ticketing
Payload Schema:
{
  event_type: 'it_ticket_created';
  ticket_id: uuid;
  ticket_number: string;
  category: 'hardware' | 'software' | 'network' | 'access' | 'email' | 'other';
  priority: 'low' | 'medium' | 'high' | 'critical';
  subject: string;
  requester_id: uuid;
  organization_id: uuid;
  timestamp: timestamptz;
}
Event 2: it_ticket_status_changed
Publisher: IT (IT-02)
Subscribers: PF-10 (Notifications)
Status: ✅ Implemented
Last Verified: 2026-02-15
Implementation:
CREATE TRIGGER it_ticket_status_changed_trigger
  AFTER UPDATE ON it_tickets
  FOR EACH ROW
  EXECUTE FUNCTION it_notify_ticket_status_changed();
Event 3: it_ticket_sla_breached
Publisher: IT (IT-02)
Subscribers: PF-10 (Notifications), IT-02 Dashboard
Status: ✅ Implemented
Implemented: 2026-01-05
Payload Schema:
{
  event_type: 'it_ticket_sla_breached';
  ticket_id: uuid;
  ticket_number: string;
  subject: string;
  organization_id: uuid;
  priority: string;
  status: string;
  assigned_to_profile_id: uuid | null;
  sla_response_target: timestamptz | null;
  sla_resolution_target: timestamptz | null;
  timestamp: timestamptz;
}
Implementation:
CREATE TRIGGER it_ticket_sla_breached_trigger
  AFTER UPDATE ON it_tickets
  FOR EACH ROW
  WHEN (NEW.sla_breached = true AND (OLD.sla_breached IS NULL OR OLD.sla_breached = false))
  EXECUTE FUNCTION it_notify_ticket_sla_breached();

IT-03: Vendor Management Events

Event: it_contract_expiring
Publisher: IT (IT-03 Vendor Management)
Subscribers: PF-10 (Notifications)
Status: 📝 Planned
Spec Reference: IT-03 IT Vendor Management
Payload Schema:
{
  event_type: 'it_contract_expiring';
  contract_id: uuid;
  vendor_id: uuid;
  vendor_name: string;
  expiration_date: date;
  days_remaining: number;
  organization_id: uuid;
  timestamp: timestamptz;
}

IT-04: Software License Events

Event 1: it_license_created
Publisher: IT (IT-04 Software License Management)
Subscribers: FA (Finance)
Status: 📝 Planned
Spec Reference: IT-04 Software License Management
Event 2: it_license_expiring
Publisher: IT (IT-04)
Subscribers: PF-10 (Notifications)
Status: 📝 Planned
Event 3: it_license_renewed
Publisher: IT (IT-04)
Subscribers: FA (Finance)
Status: ✅ Implemented
Last Verified: 2026-02-15
Implementation:
CREATE TRIGGER it_license_renewed_trigger
  AFTER UPDATE ON it_licenses
  FOR EACH ROW
  EXECUTE FUNCTION it_notify_license_renewed();
-- Fires when expiry_date is extended
Event 4: it_license_compliance_alert
Publisher: IT (IT-04)
Subscribers: PF-10 (Notifications), FA (cost tracking)
Status: ✅ Implemented
Implemented: 2026-01-05
Payload Schema:
{
  event_type: 'it_license_compliance_alert';
  license_id: uuid;
  organization_id: uuid;
  name: string;
  software_name: string;
  compliance_status: 'non_compliant';
  total_seats: number;
  assigned_seats: number;
  timestamp: timestamptz;
}
Implementation:
CREATE TRIGGER it_license_compliance_alert_trigger
  AFTER UPDATE ON it_licenses
  FOR EACH ROW
  WHEN (NEW.compliance_status = 'non_compliant' AND (OLD.compliance_status IS NULL OR OLD.compliance_status != 'non_compliant'))
  EXECUTE FUNCTION it_notify_license_compliance_alert();

IT-05: Security & Compliance Events

Event 1: it_security_incident_created
Publisher: IT (IT-05 Security & Compliance)
Subscribers: GR (Governance & Risk), PF-10 (Notifications)
Status: ✅ Implemented
Implemented: 2026-01-05
Spec Reference: IT-05 IT Security & Compliance
Payload Schema:
{
  event_type: 'it_security_incident_created';
  incident_id: uuid;
  organization_id: uuid;
  severity: 'low' | 'medium' | 'high' | 'critical';
  incident_type: string;
  description: string;
  response_status: string;
  timestamp: timestamptz;
}
Implementation:
CREATE TRIGGER it_security_incident_created_trigger
  AFTER INSERT ON it_security_incidents
  FOR EACH ROW
  EXECUTE FUNCTION it_notify_security_incident_created();
Event 2: it_vulnerability_detected
Publisher: IT (IT-05)
Subscribers: GR (Governance), PF-10 (Notifications)
Status: ✅ Implemented
Implemented: 2026-01-05
Payload Schema:
{
  event_type: 'it_vulnerability_detected';
  vulnerability_id: uuid;
  organization_id: uuid;
  vulnerability_name: string;
  cve_id: string | null;
  severity: 'critical' | 'high';
  affected_asset_ids: uuid[];
  timestamp: timestamptz;
}
Implementation:
CREATE TRIGGER it_vulnerability_detected_trigger
  AFTER INSERT ON it_vulnerabilities
  FOR EACH ROW
  WHEN (NEW.severity IN ('critical', 'high'))
  EXECUTE FUNCTION it_notify_vulnerability_detected();
Event 3: it_patch_deployed
Publisher: IT (IT-05)
Subscribers: Event Consumer (audit logging), Asset tracking
Status: ✅ Implemented
Implemented: 2026-01-05
Payload Schema:
{
  event_type: 'it_patch_deployed';
  deployment_id: uuid;
  patch_id: uuid;
  asset_id: uuid;
  organization_id: uuid;
  deployed_at: timestamptz;
  deployed_by: uuid;
  timestamp: timestamptz;
}
Implementation:
CREATE TRIGGER it_patch_deployed_trigger
  AFTER UPDATE ON it_patch_deployments
  FOR EACH ROW
  WHEN (NEW.status = 'deployed' AND (OLD.status IS NULL OR OLD.status != 'deployed'))
  EXECUTE FUNCTION it_notify_patch_deployed();
Event 4: it_patch_deployment_overdue
Publisher: IT (IT-05)
Subscribers: PF-10 (Notifications)
Status: 📝 Planned

IT-06: Procurement Events

Event 1: it_purchase_request_submitted
Publisher: IT (IT-06 Procurement)
Subscribers: FW-34 (Approval Workflows), PF-10 (Notifications)
Status: ✅ Implemented
Spec Reference: IT-06 IT Procurement
Event 2: it_purchase_request_approved
Publisher: IT (IT-06)
Subscribers: FA-04 (Purchase Orders), PF-10 (Notifications)
Status: ✅ Implemented
Payload Schema:
{
  event_type: 'it_purchase_request_approved';
  request_id: uuid;
  request_number: string;
  estimated_cost: number;
  vendor_id?: uuid;
  approved_by: uuid;
  organization_id: uuid;
  timestamp: timestamptz;
}
Event 3: it_purchase_request_received
Publisher: IT (IT-06)
Subscribers: IT-01 (Asset creation), PF-10 (Notifications)
Status: 📝 Planned

Implemented Events (FA Core)

FA-19: Financial Close Management Events

Status: ✅ Complete
Implemented: 2026-01-19
Financial Close Management events are published to the fa_events channel for close period lifecycle tracking and task management integration.

Event 1: close_period_started

Publisher: FA (Finance)
Subscribers: PF-10 (Notifications), Audit Log
Trigger: UPDATE on fa_close_periods when status changes from ‘not_started’ to ‘in_progress’
Payload Schema:
{
  event_type: 'close_period_started';
  close_period_id: uuid;
  period_name: string;
  period_type: 'month' | 'quarter' | 'year';
  started_by: uuid;
  organization_id: uuid;
  timestamp: timestamptz;
}
Implementation:
CREATE TRIGGER trigger_close_period_started
AFTER UPDATE ON fa_close_periods
FOR EACH ROW
EXECUTE FUNCTION fa_publish_close_period_started();

Event 2: close_period_completed

Publisher: FA (Finance)
Subscribers: FA-02 (Fiscal Periods), PF-10 (Notifications)
Trigger: UPDATE on fa_close_periods when status changes to ‘completed’
Payload Schema:
{
  event_type: 'close_period_completed';
  close_period_id: uuid;
  period_name: string;
  period_type: 'month' | 'quarter' | 'year';
  fiscal_period_id: uuid | null;
  completed_by: uuid;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Notify FA-02 General Ledger to update fiscal period status, trigger period-end reporting

Event 3: close_period_approved

Publisher: FA (Finance)
Subscribers: FA-07 (Financial Reporting), PF-10 (Notifications)
Trigger: UPDATE on fa_close_periods when status changes to ‘approved’
Payload Schema:
{
  event_type: 'close_period_approved';
  close_period_id: uuid;
  period_name: string;
  period_type: 'month' | 'quarter' | 'year';
  fiscal_period_id: uuid | null;
  approved_by: uuid;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Enable final report generation for approved close periods

Event 4: close_task_assigned

Publisher: FA (Finance)
Subscribers: PF-10 (Notifications)
Trigger: UPDATE on fa_close_tasks when assigned_to changes
Payload Schema:
{
  event_type: 'close_task_assigned';
  task_id: uuid;
  task_name: string;
  checklist_id: uuid;
  close_period_id: uuid;
  assigned_to: uuid;
  assigned_by: uuid;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Notify assigned user of new close task assignment

Event 5: close_task_completed

Publisher: FA (Finance)
Subscribers: PF-10 (Notifications), FA-19 (Progress tracking)
Trigger: UPDATE on fa_close_tasks when status changes to ‘completed’
Payload Schema:
{
  event_type: 'close_task_completed';
  task_id: uuid;
  task_name: string;
  checklist_id: uuid;
  close_period_id: uuid;
  completed_by: uuid;
  organization_id: uuid;
  timestamp: timestamptz;
}
Purpose: Track close progress, update dashboard metrics, notify stakeholders Consumer: supabase/functions/event-consumer/index.ts
  • Logs all events to pf_audit_logs
  • Handlers for notification delivery pending PF-10 integration
Testing: ✅ Events fire correctly on status changes

PF-11 / PF-60: Document Lifecycle Events (RAG)

Status: ✅ Implemented (triggers and migration)
Implemented: Migration 20260226140000_pf_rag_document_knowledge_events.sql
Spec Reference: specs/pf/specs/PF-11-document-management.md, docs/architecture/integrations/PF-60-rag-infrastructure-INTEGRATION.md
For PF-11 and PF-60, events use the DomainEvent envelope (see Event Schema Standard above): on the wire, the message has top-level event_type, payload, and metadata. The interfaces below describe the payload only (the inner object inside payload). Handlers receive the full envelope and use payload (and optionally metadata); they must not expect event_type inside the payload.

Events: document_published, document_updated, document_deleted

Channel: domain_events
Publisher: PF (PF-11)
Subscribers: PF-60 (RAG Infrastructure), Event Consumer
Trigger: INSERT / UPDATE / DELETE on pf_documents (see migration for trigger definitions)
Payload-only schemas (inside envelope.payload)
/** Payload only — event_type is at envelope level. */
interface DocumentPublishedPayload {
  organization_id: uuid;
  document_id: uuid;
  timestamp: timestamptz;
  user_id: uuid;
}

interface DocumentUpdatedPayload {
  organization_id: uuid;
  document_id: uuid;
  timestamp: timestamptz;
  user_id: uuid;
}

interface DocumentDeletedPayload {
  organization_id: uuid;
  document_id: uuid;
  timestamp: timestamptz;
  user_id: uuid;
}
Note: Event payload contains only IDs and non-PHI metadata. RAG consumers (PF-60) must fetch document content (e.g. extracted_content, title) from pf_documents using document_id under RLS.
Consumer actions
ConsumerActionStatus
PF-60 (RAG Infrastructure)Generate/update/delete embeddings🟡 In Progress (generate-embeddings invoked when event-consumer handler added)
Event ConsumerLog to pf_audit_logs✅ Implemented

PF-61: Knowledge Base System Events

Status: 📝 Planned
Implemented: TBD
Spec Reference: specs/pf/specs/PF-61-knowledge-base-system.md

Event: knowledge_article_published

Event: knowledge_article_published
Channel: domain_events
Publisher: PF (PF-61)
Subscribers: PF-60 (RAG Infrastructure)
Status: 📝 Planned
Purpose
Notifies RAG infrastructure that a knowledge article has been published and is ready for embedding generation.
Trigger Conditions
  • Article status changes from draft or in_review to published via UPDATE
  • Note: Event only fires on UPDATE operations when status changes to published. Consumers must fetch article details (title, tags, category) under RLS using article_id.
Payload Schema
interface KnowledgeArticlePublishedPayload {
  event_type: 'knowledge_article_published';
  organization_id: uuid;
  article_id: uuid;
  timestamp: timestamptz;
  user_id: uuid;
}
Note: Event payload contains only IDs and non-PII metadata. Consumers must fetch article details (title, tags, category) from pf_knowledge_base table using article_id under RLS policies.
Implementation
CREATE OR REPLACE FUNCTION pf_publish_knowledge_article_published()
RETURNS TRIGGER AS $$
BEGIN
  IF NEW.status = 'published' AND (OLD.status IS NULL OR OLD.status != 'published') THEN
    PERFORM pg_notify('domain_events', json_build_object(
      'event_type', 'knowledge_article_published',
      'organization_id', NEW.organization_id,
      'article_id', NEW.id,
      'timestamp', now(),
      'user_id', NEW.published_by
    )::text);
  END IF;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER SET search_path = public;

CREATE TRIGGER trigger_knowledge_article_published
AFTER UPDATE ON pf_knowledge_base
FOR EACH ROW
WHEN (OLD.status IS DISTINCT FROM NEW.status AND NEW.status = 'published')
EXECUTE FUNCTION pf_publish_knowledge_article_published();
Consumer Actions
ConsumerActionStatus
PF-60 (RAG Infrastructure)Generate embeddings for published article📝 Planned
Event ConsumerLog to pf_audit_logs✅ Implemented
Testing Requirements
  • Event payload structure validation
  • Event fires on publish
  • Correct organization_id included
  • PF-60 handles event correctly

Event: knowledge_article_unpublished

Event: knowledge_article_unpublished
Channel: domain_events
Publisher: PF (PF-61)
Subscribers: PF-60 (RAG Infrastructure)
Status: 📝 Planned
Purpose
Notifies RAG infrastructure to remove embeddings for an unpublished article.
Trigger Conditions
  • Article status changes from published to draft, in_review, or archived
  • Article is deleted
Payload Schema
interface KnowledgeArticleUnpublishedPayload {
  event_type: 'knowledge_article_unpublished';
  organization_id: uuid;
  article_id: uuid;
  timestamp: timestamptz;
  user_id: uuid;
}
Implementation
CREATE OR REPLACE FUNCTION pf_publish_knowledge_article_unpublished()
RETURNS TRIGGER AS $$
BEGIN
  -- Handle UPDATE case: status changes from published to non-published
  IF TG_OP = 'UPDATE' AND NEW.status != 'published' AND OLD.status = 'published' THEN
    PERFORM pg_notify('domain_events', json_build_object(
      'event_type', 'knowledge_article_unpublished',
      'organization_id', NEW.organization_id,
      'article_id', NEW.id,
      'timestamp', now(),
      'user_id', auth.uid()
    )::text);
  END IF;
  
  -- Handle DELETE case: article is deleted while published
  IF TG_OP = 'DELETE' AND OLD.status = 'published' THEN
    PERFORM pg_notify('domain_events', json_build_object(
      'event_type', 'knowledge_article_unpublished',
      'organization_id', OLD.organization_id,
      'article_id', OLD.id,
      'timestamp', now(),
      'user_id', auth.uid()
    )::text);
  END IF;
  
  RETURN COALESCE(NEW, OLD);
END;
$$ LANGUAGE plpgsql SECURITY DEFINER SET search_path = public;

-- Trigger for UPDATE operations
CREATE TRIGGER trigger_knowledge_article_unpublished
AFTER UPDATE ON pf_knowledge_base
FOR EACH ROW
WHEN (OLD.status = 'published' AND NEW.status != 'published')
EXECUTE FUNCTION pf_publish_knowledge_article_unpublished();

-- Trigger for DELETE operations
CREATE TRIGGER trigger_knowledge_article_unpublished_delete
AFTER DELETE ON pf_knowledge_base
FOR EACH ROW
WHEN (OLD.status = 'published')
EXECUTE FUNCTION pf_publish_knowledge_article_unpublished();
Consumer Actions
ConsumerActionStatus
PF-60 (RAG Infrastructure)Delete embeddings for unpublished article📝 Planned
Event ConsumerLog to pf_audit_logs✅ Implemented
Testing Requirements
  • Event payload structure validation
  • Event fires on unpublish
  • Correct organization_id included
  • PF-60 handles event correctly

Planned Events (CL/PM EHR & Practice Management)

Source: EHR_PM_PLANNING_BUNDLE.md
Status: 📝 Planned (stubs); payload schemas to be defined in respective CL/PM specs.

CL/PM Event Summary

Event NameChannelPublisherSubscribersSpec ReferenceDefinition TimelineOwner
assessment_completedcl_pm_eventsCLPM (optional), FW, PF-10CL-02Q2 2026; payload schema by sprint per CL-02CL team; tracking: CL-02 spec
treatment_plan_signedcl_pm_eventsCLFW, PF-10CL-03Q2 2026CL team
treatment_plan_review_scheduledcl_pm_eventsCLPF-10CL-03Q2 2026CL team
treatment_plan_event_triggeredcl_pm_eventsCLPF-10CL-03Q2 2026CL team
progress_note_signedcl_pm_eventsCLPM (charge capture), PF-10CL-04Q2 2026CL team
medication_recon_completedcl_pm_eventsCLPF-10CL-05Q2 2026CL team
prescription_sentcl_pm_eventsCLPM, PF-10CL-06Q2 2026CL team
pdmp_query_completedcl_pm_eventsCL / externalCL (audit)CL-17Q2 2026; Dec 31, 2026 CSPMP deadlineCL team
cds_alert_triggeredcl_eventsCL (CL-08)PF-10, CL (audit)CL-08Q2 2026CL team
cds_rule_overriddencl_eventsCL (CL-08)PF-10, PF-04 (audit)CL-08Q2 2026CL team
cl_group_encounters_approvedcl_eventsCL (CL-14-EN-01)PM-07CL-14-EN-01Q2 2026CL team
cl_cohort_membership_recomputedcl_eventsCL (CL-54)CE-09/10 (outreach audience refresh), FA (VBP attribution), CL-35 (panel/dashboard refresh)CL-54Q2 2026CL team
cl_quality_measure_period_calculatedcl_eventsCL (CL-35)FA (VBP payment adjustment)CL-35 · CL-FA-VBP-QUALITY-DATA-PIPELINEPhase 3 (shipped 2026-04-01)CL team
cl_care_gap_closedcl_eventsCL (CL-35)FW (event automation)CL-35 · CL-FW-EVENT-AUTOMATION-INTEGRATIONPhase 2 (shipped 2026-04-01)CL team
cl_virtual_group_startedcl_pm_eventsCL (CL-55)PM-07, PF-10/FW-16 (optional)CL-55Q2 2026; PHI-free payloadCL team
cl_virtual_group_concludedcl_pm_eventsCL (CL-55)PM-07 (charge capture w/ jurisdiction-resolved modifier suggestions)CL-55Q2 2026; PHI-free payloadCL team
cl_lab_order_createdcl_pm_eventsCL (CL-09)PF-10, FWCL-09Q2 2026CL team
cl_lab_result_receivedcl_pm_eventsCL (CL-09) / ExternalCL-08 (abnormal alert), PF-10CL-09Q2 2026CL team
cl_lab_result_reviewedcl_pm_eventsCL (CL-09)PF-10, PF-04 (audit)CL-09Q2 2026CL team
cl_cda_document_generatedcl_eventsCL (CL-48)CL-25 (Audit Dashboard), PF-04 (audit)CL-48 · INTEGRATIONQ3 2026; PHI-free payload (IDs only)CL team
cl_cda_transmission_status_changedcl_eventsCL (CL-48 edge function)PF-10 Notifications, CL-25 (Audit Dashboard)CL-48 · INTEGRATIONQ3 2026; PHI-free payload (IDs + status only)CL team
cl_problem_list_updatedcl_eventsCL (CL-46)CL-08 (CDS re-evaluation), PM-07 (advisory — diagnosis pre-pop via @/platform/clinical#usePatientActiveProblems)CL-46Q2 2026; PHI-free payload &#123; patient_id, problem_id, icd10_code, action: 'added'|'resolved'|'reactivated' &#125;; idempotency key problem_id+action+changed_atCL team
claim_submittedcl_pm_eventsPMFA (optional), PF-10, FW-03PM-08Q2 2026PM team
claim_status_changedcl_pm_eventsPMPM-09, PF-10, FW-03PM-08, PM-19Q2 2026PM team
claim_createdcl_pm_eventsPMFW-03 (optional)PM-08, PM-19Q2 2026PM team
claim_adjudicatedcl_pm_eventsPMPM-09, PF-10PM-08, PM-09Q2 2026PM team
denial_receivedcl_pm_eventsPMFW-03, PF-10PM-08, PM-19Q2 2026PM team
charge_approvedcl_pm_eventsPMFW-03, PF-10PM-07, PM-19Q2 2026PM team
charge_status_changedcl_pm_eventsPMFW-03, PF-10PM-07, PM-19Q2 2026PM team
prior_auth_requiredcl_pm_eventsPMCL, PF-10PM-10Q2 2026PM team
prior_auth_receivedcl_pm_eventsPMCL, PM-07/08, PF-10PM-10Q2 2026PM team
eligibility_verifiedcl_pm_eventsPMCL, PM-07, PF-10PM-02Q2 2026PM team
patient_registeredcl_pm_eventsPMCL, RH (optional), PF-10PM-01Q2 2026PM team
appointment_scheduledcl_pm_eventsPMCL, PF-10PM-03Q2 2026PM team
encounter_completedcl_pm_eventsCL/PMPM (charge capture), PF-10CL-04, PM-07Q2 2026CL/PM
payment_postedcl_pm_eventsPM (PM-09)FA, FW-03PM-09, PM-19Q2 2026PM team
write_off_approvedcl_pm_eventsPM (PM-09) / PF-10FA, FW-03PM-09, PM-19Q2 2026PM team
pm.rpa.execution_completedpm_rpa_eventsPM (PM-51 RPA)PM-08, PM-09PM-51Q3 2026PM team
pm.rpa.consecutive_failurespm_rpa_eventsPM (PM-51 RPA)PF-10PM-51Q3 2026PM team
PM events as automation triggers: When the cl_pm_events channel is implemented, FW-03 Automation Engine can subscribe and use PM events as automation triggers (trigger type pm_event or event with source PM). Billing admins can create rules that run when specific events occur (e.g. claim status = denied, charge approved, payment posted), with optional payload filters (event_type, new_status, payer_id). See PM-19: PM-Triggered Business Rule Automation and PM-19 Integration. CL-23 In-Basket event consumption: CL-23 (Clinical In-Basket) consumes the following planned events to create or update cl_inbasket_items (item types: cosign_request, lab_review, refill_request, chart_message, referral_response, cds_alert). Event names and payload schemas are defined in the rows above; when implemented, CL-23 subscribes and maps to in-basket item_type and payload. Key events: progress_note_signed (cosign), cds_alert_triggered (cds_alert), cl_lab_result_received / cl_lab_result_reviewed (lab_review). Planned stubs for referral and chart_message below. See CL-23 Clinical In-Basket Integration. CL-23 planned event stubs (referral_response, chart_message):
⚠️ Naming compliance note: When these events are implemented, names MUST follow the established {domain}_{entity}_{action} convention (e.g., cl_referral_response_received, cl_chart_message_sent). The placeholder names below are for planning only.
Event NameChannelPublisherSubscribersPayload SchemaStatus
referral_response (placeholder — rename to cl_referral_response_received)cl_events (or TBD)TBD (PM/CL when spec defines)CL-23To be defined in spec📝 Planned
chart_message (placeholder — rename to cl_chart_message_sent)cl_events (or TBD)TBD (PM/CL when spec defines)CL-23To be defined in spec📝 Planned
Consumers can align on channel, publisher, subscriber, and payload placeholders early; payload schemas will be defined in respective PM/CL specs. PM-19 automation trigger payload schemas (canonical): All PM events consumed by FW-03 for automation MUST include organization_id in payload or metadata for tenant isolation. Filterable fields used by PM-19 rules:
Event TypeRequired Payload FieldsOptional Filter Fields (for rule matching)
claim_submittedorganization_id, claim_id, payer_idpayer_id
claim_status_changedorganization_id, claim_id, new_status, payer_idnew_status, payer_id
claim_createdorganization_id, claim_id, payer_idpayer_id
denial_receivedorganization_id, claim_id, payer_idpayer_id
charge_approvedorganization_id, charge_id
charge_status_changedorganization_id, charge_id, new_statusnew_status
payment_postedorganization_id, payment_id, claim_id
write_off_approvedorganization_id, approval_id, payment_id, write_off_amount
IDs-only rule for PM automation payloads: All example payloads in this subsection use UUIDs/IDs only (no PII/PHI). Human-readable identifiers (e.g. claim numbers, account numbers) must not be included in event payloads; use system-generated UUIDs only, or if needed store only irreversible hashes. Consumers resolve display data via authorized APIs. Example payload (claim_status_changed):
{
  event_id: uuid;
  event: 'claim_status_changed';
  payload: {
    organization_id: uuid;
    claim_id: uuid;
    patient_id: uuid;
    payer_id: uuid;
    previous_status: string;
    new_status: string;   // Used by PM-19 filter (e.g. 'denied', 'paid')
    denial_codes?: Array<{ code: string; source: string }>;
    paid_amount?: number; // cents, when new_status = 'paid'
    changed_by?: uuid;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}
Example payload (charge_approved / charge_status_changed):
{
  event_id: uuid;
  event: 'charge_approved' | 'charge_status_changed';
  payload: {
    organization_id: uuid;
    charge_id: uuid;
    new_status?: string;   // For charge_status_changed: e.g. 'approved', 'pending'
    patient_id?: uuid;
    encounter_id?: uuid;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}
Example payload (payment_posted):
{
  event_id: uuid;
  event: 'payment_posted';
  payload: {
    organization_id: uuid;
    payment_id: uuid;
    claim_id?: uuid;
    amount_cents: number;
    payer_id?: uuid;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}
All example payloads above use IDs only (no PII/PHI). Automation actions resolve display data via authorized APIs. Acceptance criteria for transition to full specs: (1) Payload schema documented with required/optional fields and types; (2) Channel cl_pm_events created and wired; (3) Publisher/subscriber contracts and error handling agreed; (4) Owner and target date (sprint/quarter) assigned per row above.

CL/PM Full Payload Schemas (Canonical)

Payloads use IDs only (no PII/PHI). All events include event_id (uuid) as the primary idempotency key and metadata: { organization_id, user_id?, timestamp, correlation_id? }. Idempotency note: event_id is the canonical deduplication key per the Event Schema Standard. Some older event contracts reference correlation_id for idempotency — these should be treated as supplementary domain-specific keys; event_id takes precedence.

clinical_note_finalized (CL-04 → PM-07)

Event: clinical_note_finalized (alias: progress_note_signed)
Publisher: CL
Subscribers: PM-07 (charge capture), PF-10
Contract: CL-PM-ENCOUNTER-TO-BILLING
{
  event_id: uuid;
  event: 'clinical_note_finalized';
  payload: {
    encounter_id: uuid;
    patient_id: uuid;
    provider_id: uuid;
    note_id: uuid;
    service_date: string; // ISO date
    begin_time: string;   // ISO time or HH:mm
    end_time: string;
    duration_minutes: number;
    cpt_code: string;
    diagnosis_codes: string[];
    place_of_service: string;
    is_telehealth: boolean;
    is_group: boolean;
    group_participant_count?: number;
    modifiers: string[];
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}
Idempotency: Consumer (PM-07) MUST use event_id to avoid duplicate charges. Error handling: Retry with exponential backoff; dead-letter queue after N failures. No PII/PHI in payload.

peer_encounter_finalized (CL-19 → PM-07)

Event: peer_encounter_finalized
Publisher: CL
Subscribers: PM-07 (charge capture)
Contract: CL-19 Peer Recovery Support
{
  event_id: uuid;
  event: 'peer_encounter_finalized';
  payload: {
    event_type: 'peer_encounter_finalized';
    timestamp: string;   // ISO timestamp
    user_id?: uuid;      // present only when the event is user-initiated; otherwise omit
    peer_encounter_id: uuid;
    organization_id: uuid;
    chart_id: uuid;
    encounter_id?: uuid;  // optional link to pm_encounters
    peer_provider_id: uuid;
    service_date: string;   // ISO date
    hcpcs_code: string;
    duration_minutes: number;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}
Idempotency: Consumer (PM-07) MUST use event_id to avoid duplicate charges. No PII/PHI in payload. payload.user_id is set only when the event is user-initiated; otherwise omit.

assessment_completed (CL-02)

{
  event_id: uuid;
  event: 'assessment_completed';
  payload: {
    assessment_id: uuid;
    patient_id: uuid;
    assessment_type: string;
    level_of_care_recommendation?: string;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

treatment_plan_signed (CL-03)

{
  event_id: uuid;
  event: 'treatment_plan_signed';
  payload: {
    plan_id: uuid;
    patient_id: uuid;
    signed_by: uuid;
    signature_type: 'member' | 'hcdm' | 'clinician';
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}
{
  event_id: uuid;
  event: 'consent_granted' | 'consent_revoked';
  payload: {
    consent_id: uuid;
    patient_id: uuid;
    consent_type: string;
    scope: string;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

cl_sdoh_screening_completed (CL-18)

Consumers MUST resolve patient identity from chart_id (e.g. cl_sdoh_screenings.chart_idcl_patient_charts). patient_id is not in the payload to avoid denormalization and sync/merge issues.
{
  event_id: uuid;
  event: 'cl_sdoh_screening_completed';
  payload: {
    screening_id: uuid;
    chart_id: uuid;   // primary reference; resolve patient via cl_patient_charts
    needs_identified: string[];
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

patient_registered (PM-01)

{
  event_id: uuid;
  event: 'patient_registered';
  payload: {
    patient_id: uuid;
    patient_identity_id?: uuid;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

appointment_scheduled (PM-03)

{
  event_id: uuid;
  event: 'appointment_scheduled';
  payload: {
    appointment_id: uuid;
    patient_id: uuid;
    provider_id: uuid;
    start_datetime: string;
    end_datetime: string;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

encounter_completed (PM-03 / CL-04)

{
  event_id: uuid;
  event: 'encounter_completed';
  payload: {
    encounter_id: uuid;
    patient_id: uuid;
    appointment_id?: uuid;
    status: string;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

cl_assessment_completed (CL-02-EN-59)

Event: cl_assessment_completed
Channel: cl_events
Publisher: CL-02
Subscribers: PM-07 (charge capture for assessment billing)
Status: ✅ Active (2026-04-04)
Payload includes instrument_code to allow subscribers to differentiate cognitive screening instruments (moca, slums, mmse) from other assessments. No PHI in payload — consumers must fetch clinical data server-side.
{
  event_id: uuid;
  event: 'cl_assessment_completed';
  payload: {
    assessment_id: uuid;
    chart_id: uuid;
    instrument_code: string;       // e.g. 'moca', 'slums', 'mmse'
    instrument_name: string;       // Human-readable name
    score: number | null;          // Adjusted score (null if draft)
    below_threshold: boolean;      // true if score below population threshold
    completed_by: uuid;            // User ID of clinician
    completed_at: timestamptz;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

claim_submitted / claim_status_changed (PM-08)

{
  event_id: uuid;
  event: 'claim_submitted' | 'claim_status_changed';
  payload: {
    claim_id: uuid;
    claim_number: string;
    patient_id: uuid;
    payer_id: uuid;
    claim_type: 'professional_837p' | 'institutional_837i';
    total_charge: number;
    line_count: number;        // Number of claim lines
    submitted_by?: uuid;       // User who submitted (claim_submitted only)
    new_status?: string;       // New status (claim_status_changed only)
    changed_by?: uuid;         // User who changed status (claim_status_changed only)
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

prior_auth_required / prior_auth_received (PM-10)

{
  event_id: uuid;
  event: 'prior_auth_required' | 'prior_auth_received';
  payload: {
    prior_authorization_id: uuid;
    patient_id: uuid;
    status: string;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

eligibility_verified (PM-02)

{
  event_id: uuid;
  event: 'eligibility_verified';
  payload: {
    eligibility_check_id: uuid;
    patient_id: uuid;
    policy_id?: uuid;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

charge_approved / charge_status_changed (PM-07 → FW-03)

Event: charge_approved or charge_status_changed
Publisher: PM (PM-07)
Subscribers: FW-03 (automation triggers), PF-10
Spec Reference: PM-19 PM-Triggered Business Rule Automation
{
  event_id: uuid;
  event: 'charge_approved' | 'charge_status_changed';
  payload: {
    charge_id: uuid;
    patient_id: uuid;
    organization_id: uuid;
    new_status: string;        // e.g. 'approved', 'billed', 'void'
    old_status?: string;       // charge_status_changed only
    changed_by?: uuid;
    payer_id?: uuid;           // from fee schedule when applicable
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

claim_created (PM-08)

Event: claim_created
Publisher: PM (PM-08)
Subscribers: FW-03 (optional)
Spec Reference: PM-19
{
  event_id: uuid;
  event: 'claim_created';
  payload: {
    claim_id: uuid;
    claim_number: string;
    patient_id: uuid;
    payer_id: uuid;
    status: string;            // 'draft'
    created_by?: uuid;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

denial_received (PM-08 / PM-09)

Event: denial_received
Publisher: PM (PM-08/PM-09 when denial_codes updated, e.g. from ERA)
Subscribers: FW-03, PF-10
Spec Reference: PM-19
{
  event_id: uuid;
  event: 'denial_received';
  payload: {
    claim_id: uuid;
    claim_number: string;
    payer_id: uuid;
    new_status: string;        // e.g. 'denied'
    denial_codes?: Array<{ carc: string; rarc?: string; group_code: string }>;
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}

payment_posted (PM-09 → FA)

Event: payment_posted
Channel: cl_pm_events
Publisher: PM (PM-09)
Subscribers: FA (revenue/AR posting to GL)
Status: Implemented (FA consumer: fa-consume-pm-payment-events)
Spec Reference: PM-09 Payment Posting & ERA Processing
Integration Doc: PM-09 Integration
Purpose: Notify FA when an insurance or patient payment has been posted so FA can post revenue/AR to the general ledger. Loose coupling: PM publishes after posting; FA consumes asynchronously. Trigger: After pm_payments row is created/updated with status ‘posted’ or ‘partially_posted’ and at least one pm_payment_applications exists (or after ERA batch posting completes). Payload Schema:
{
  event_id: uuid;
  event: 'payment_posted';
  payload: {
    payment_id: uuid;
    organization_id: uuid;
    payment_type: 'insurance' | 'patient' | 'adjustment' | 'refund';
    total_amount: number;
    posted_amount: number;
    payment_date: string;   // ISO date
    payer_id: uuid | null;  // pm_payers.id if insurance
    patient_id: uuid | null;
    era_file_id: uuid | null;
    claim_ids: uuid[];      // claims affected (for FA to link GL lines)
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}
Idempotency: FA MUST use event_id to avoid duplicate GL entries. No PII/PHI in payload (IDs only).

write_off_approved (PM-09 / PF-10 → FA)

Event: write_off_approved
Channel: cl_pm_events
Publisher: PM (PM-09) or PF-10 (approval workflow completion)
Subscribers: FA (write-off/bad debt GL entry)
Status: Implemented (FA consumer: fa-consume-pm-payment-events)
Spec Reference: PM-09 Payment Posting & ERA Processing
Integration Doc: PM-09 Integration
Purpose: Notify FA when a write-off or bad debt has been approved (PF-10/FW-34) so FA can post the write-off to the general ledger. Trigger: When platform approval (PF-10/FW-34) completes for a write-off request tied to PM-09 (e.g. payment or application write-off). Payload Schema:
{
  event_id: uuid;
  event: 'write_off_approved';
  payload: {
    approval_id: uuid;      // PF-10 approval record
    organization_id: uuid;
    payment_id: uuid;       // pm_payments.id (write_off type)
    write_off_amount: number;
    claim_id: uuid | null;
    reason_code?: string;   // optional adjustment/reason code
  };
  metadata: { organization_id: uuid; user_id?: uuid; timestamp: timestamptz; correlation_id?: uuid; };
}
Idempotency: FA MUST use event_id to avoid duplicate write-off GL entries. No PII/PHI in payload (IDs only).

Planned Events (FA Cross-Core — when CE/GR/CL ready)

EventPublisherConsumerSpecStatus
donation_receivedCEFA-05, FA-02CE-18, FA-31📝 Planned
fundraising_campaign_completedCEFA-07CE-18, FA-31📝 Planned
compliance_cost_incurredGRFA-13, FA-15FA-34📝 Planned
clinical_program_cost_allocatedCLFA-35 (→ FA-15 allocation bases)FA-35📝 Planned
encounter_cost_calculatedPM-35FA-35 (Phase 2)PM-35, FA-35📝 Planned — schema pending FA-35 + PM-35 joint session (see PENDING_CONTRACTS.md)

clinical_program_cost_allocated — Payload Schema

Channel: cl_events Publisher: CL (Clinical core) Publisher Artifact: TBD — CL edge function or trigger (pending CL module maturity) Subscriber: FA-35 (fa-consume-cl-program-cost edge function) Subscriber Artifact: supabase/functions/fa-consume-cl-program-cost/index.ts (FA-35) Idempotency Key: event_id (UUID); consumer deduplicates on fa_cl_allocation_activity.source_event_id.
{
  event_id: uuid;                   // Required; unique per event
  event: 'clinical_program_cost_allocated';
  version: '1.0';
  payload: {
    organization_id: uuid;          // Tenant isolation — required
    program_id: uuid;               // CL clinical program UUID (opaque to FA)
    activity_count: number;         // Encounter/session count for the period
    period_start: string;           // ISO date (YYYY-MM-DD)
    period_end: string;             // ISO date (YYYY-MM-DD)
  };
  metadata: {
    organization_id: uuid;
    user_id?: uuid;
    timestamp: string;              // ISO timestamp
    correlation_id?: uuid;
  };
}
Implementation Location:
  • Publisher: TBD — CL edge function or database trigger (pending CL module implementation)
  • Subscriber: supabase/functions/fa-consume-cl-program-cost/index.ts (FA-35 Phase 1)
Contract References: No PHI/PII: Only program UUIDs and integer counts. No patient names, diagnoses, or clinical details.

encounter_cost_calculated — Payload Schema

Channel: fa_events (or cl_pm_events — to be confirmed) Publisher: PM-35 (Practice Management / Encounter Cost Accounting) Subscriber: FA-35 (fa-consume-encounter-cost edge function) Idempotency Key: event_id (UUID); consumer deduplicates on event_id (or source_event_id if included in payload). Status: 📝 Planned — schema pending FA-35 + PM-35 joint session (see PENDING_CONTRACTS.md) Payload Schema (draft):
{
  event_id: uuid;                   // Required; unique per event
  event: 'encounter_cost_calculated';
  version: '1.0';
  payload: {
    organization_id: uuid;          // Tenant isolation — required
    encounter_id: uuid;             // PM encounter UUID (opaque to FA)
    cl_program_id?: uuid;           // CL program identifier (pending PM-35 confirmation)
    cost_breakdown: {
      total_cost: number;           // Total encounter cost
      // Additional fields TBD in PM-35/FA-35 joint session
    };
    period_start: string;           // ISO date (YYYY-MM-DD)
    period_end: string;             // ISO date (YYYY-MM-DD)
  };
  metadata: {
    organization_id: uuid;
    user_id?: uuid;
    timestamp: string;              // ISO timestamp
    correlation_id?: uuid;
  };
}
Implementation Location:
  • Publisher: TBD — PM-35 edge function or trigger (pending PM-35 Phase 2)
  • Subscriber: supabase/functions/fa-consume-encounter-cost/index.ts (FA-35 Phase 2)
Contract References: No PHI/PII: Only UUIDs and cost amounts. No patient names, clinical details, or diagnoses.

CL/PM Event Error Handling and Idempotency

  • Idempotency: Every event MUST include a unique event_id. Consumers MUST record processed event_ids and MUST NOT create duplicate side effects (e.g. duplicate charges) when the same event is delivered more than once.
  • Retry policy: Consumers SHOULD retry transient failures with exponential backoff (e.g. 1s, 2s, 4s, max 3 retries).
  • Dead-letter queue (DLQ): After max retries, event SHOULD be written to a DLQ or logged for manual resolution; alert operators.
  • No PII/PHI in payload: Only UUIDs and non-identifying codes. See constitution and EVENT_CONTRACTS security guidance.

Example Stub: assessment_completed

Event: assessment_completed
Channel: cl_pm_events
Publisher: CL (Clinical & EHR)
Subscribers: PM (optional billing), FW, PF-10
Status: 📝 Planned
Spec Reference: CL-02 – Comprehensive Assessments
Definition Timeline: Q2 2026; payload schema finalized in CL-02 spec.
Owner: CL team; tracking: CL-02 spec.
Purpose: Notify when a comprehensive assessment is completed so downstream workflows (billing, automation, notifications) can react. Trigger Conditions: Assessment record finalized/signed (e.g. INSERT/UPDATE on assessment table with status = completed). Payload Schema (mandatory fields per EVENT_CONTRACTS guidelines):
FieldTypeRequiredDescription
event_typestringYesMust equal "assessment_completed".
organization_iduuidYesTenant isolation; required.
timestamptimestamptz (ISO 8601)YesEvent occurrence time.
site_iduuidOptionalIf site-scoped.
user_iduuidOptionalIf user-initiated (e.g. completing clinician).
correlation_idstring (uuid)OptionalFor event chaining and audit trail.
assessment_iduuidYesAssessment record ID. Event payload must not contain PII/PHI; use IDs only.
patient_iduuidYesPatient record ID. Event payload must not contain PII/PHI; use IDs only.
GUIDANCE: Event payload must not contain PII/PHI; use IDs only (e.g. assessment_id, patient_id). No names, emails, or other sensitive data. See EVENT_CONTRACTS payload guidelines. Implementation: Not yet implemented. Channel cl_pm_events to be created when CL/PM event pipeline is implemented.

CL-03: treatment_plan_review_scheduled

Event: treatment_plan_review_scheduled
Channel: cl_pm_events
Publisher: CL (Clinical & EHR)
Subscribers: PF-10 (Notifications)
Status: 📝 Planned
Spec Reference: CL-03 – Treatment Planning
Integration Doc: CL-03-treatment-planning-INTEGRATION.md
Owner: CL team.
Purpose: Notify when a treatment plan is due for review (e.g. 30 days before annual review_due_date) so PF-10 can send alerts to the assigned clinician/care coordinator. Trigger Conditions: Scheduled or cron evaluation: plans where review_due_date is within the notification window (e.g. 30 days); or on plan create/update when review_due_date is set. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "treatment_plan_review_scheduled".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
site_iduuidOptionalIf site-scoped.
user_iduuidOptionalIf user-initiated.
correlation_idstring (uuid)OptionalFor audit/chain.
treatment_plan_iduuidYesPlan record ID.
chart_iduuidYesPatient chart ID.
review_due_datestring (date)YesDate plan review is due.
Implementation: Not yet implemented.

CL-03: treatment_plan_event_triggered

Event: treatment_plan_event_triggered
Channel: cl_pm_events
Publisher: CL (Clinical & EHR)
Subscribers: PF-10 (Notifications)
Status: 📝 Planned
Spec Reference: CL-03 – Treatment Planning
Integration Doc: CL-03-treatment-planning-INTEGRATION.md
Owner: CL team.
Purpose: Notify when a life event is recorded that triggers a treatment plan update (hospitalization, move, LOC change, incarceration). Success metric: alert/queue within 48 hours of event recorded. Phase 1: manual event entry only. For auditability, user_id must be present when the trigger is user-initiated. Trigger Conditions: User records a qualifying life event for a chart (e.g. “Life event” form or chart event); optional future ADT integration. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "treatment_plan_event_triggered".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
site_iduuidOptionalIf site-scoped.
user_iduuidYesUser who recorded the event; required for user-initiated life-event triggers (omit only for explicit system-initiated events).
correlation_idstring (uuid)OptionalFor audit/chain.
chart_iduuidYesPatient chart ID.
life_event_typestringOptionale.g. hospitalization, move, loc_change, incarceration.
event_recorded_atstring (ISO 8601)YesWhen the event was recorded in the system.
treatment_plan_iduuidOptionalCurrent active plan ID if known.
Implementation: Not yet implemented.

PM-02: Insurance & Eligibility Verification Events

Status: 📝 Planned
Spec Reference: PM-02-insurance-eligibility-verification.md

Event: pm_eligibility_verified

Channel: pm_events
Publisher: PM (Practice Management) — PM-02
Subscribers: CL-01 (Patient Chart — coverage info update), PM-08 (Claims — eligibility gate)
Trigger: After an eligibility check record is created and eligible field is set
Status: 📝 Planned
Payload Schema:
interface EligibilityVerifiedPayload {
  event_type: 'pm_eligibility_verified';
  organization_id: string;       // Tenant isolation (UUID)
  patient_id: string;            // UUID — patient identifier only; no PHI in payload
  policy_id: string | null;      // UUID — policy checked (null for manual/unlinked checks)
  check_id: string;              // UUID — pm_eligibility_checks.id
  eligible: boolean;             // Whether patient is currently eligible
  response_status: string;       // e.g. 'active_coverage', 'inactive', 'not_found', 'error'
  check_type: 'real_time' | 'batch' | 'manual';
  next_check_due: string | null; // ISO 8601 — when to re-verify; null if unknown
  timestamp: string;             // ISO 8601 — event occurrence time
}
PHI Logging Guidelines:
  • Allowed: check_id, patient_id (UUID only — no name/DOB), check_type, eligible, organization_id
  • Prohibited: benefit_details contents, policy_number, subscriber_dob, subscriber_name
  • Retention: Event logged to pf_audit_logs; no PHI in application logs or edge function stdout
Consumer Actions:
  1. CL-01: Update patient chart coverage status display (coverage info widget)
  2. PM-08: Allow/block claim submission based on eligibility status (eligibility gate)
  3. FW automations: Trigger workflows on eligibility change (e.g., notify staff of inactive coverage)
Implementation Note:
  • Register in fw_workflow_events table via seed migration (Phase 0, T0 task)
  • Channel pm_events must be added to the Event Delivery Mechanism channel list
  • Published via publishEvent() from @/platform/events after eligibility check record creation

Event: pm_benefits_parsed

Channel: pm_events Publisher: PM (Practice Management) — PM-02-EN-02 (pm-parse-271-benefits edge function) Subscribers: PM-48 (Patient Cost Estimation & Financial Clearance), PM-07 (Charge Capture — copay/deductible defaults) Trigger: After successful X12 271 EB-loop parsing and persistence of pm_benefit_details rows for an eligibility check Status: 📝 Planned (PM-02-EN-02) Spec Reference: PM-02-EN-02-eligibility-benefit-detail-parsing.md §FR-3.3 Payload Schema:
interface BenefitsParsedPayload {
  event_type: 'pm_benefits_parsed';
  organization_id: string;          // Tenant isolation (UUID)
  eligibility_check_id: string;     // UUID — pm_eligibility_checks.id
  patient_id: string;               // UUID — patient identifier only; no PHI in payload
  service_types_parsed: string[];   // X12 service type codes for which EB loops were extracted
  parsing_confidence: 'high' | 'medium' | 'low';
  benefit_detail_ids: string[];     // UUIDs of pm_benefit_details rows written
  timestamp: string;                // ISO 8601 — event occurrence time
}
PHI Logging Guidelines:
  • Allowed: eligibility_check_id, patient_id (UUID only — no name/DOB), parsing_confidence, service_types_parsed, organization_id
  • Prohibited: copay/coinsurance/deductible amounts, OOP max values, raw EB segments, subscriber identifiers
  • Retention: Event logged via publishEvent(); no benefit dollar amounts in application logs or edge function stdout (createLogger sanitization required)
Consumer Actions:
  1. PM-48 (Patient Cost Estimation): Trigger refresh of patient responsibility estimates for affected appointments
  2. PM-07 (Charge Capture): Refresh copay/deductible defaults shown in charge entry form for the patient
Implementation Note:
  • Published via publishEvent() from @/platform/events after pm-parse-271-benefits edge function completes successful parsing
  • Channel pm_events (already declared for pm_eligibility_verified)
  • Service-role edge function MUST scope all DB writes by organization_id before publishing (defense-in-depth per PM-02-EN-02 FR-3.1)

PM-01-EN-01: Patient Merge Events

Status: 📋 Specification — implementation pending Spec Reference: PM-01-EN-01-patient-merge-workflow.md Integration Reference: PM-01-EN-01-patient-merge-workflow-INTEGRATION.md

Event: pm_patient_merged

Channel: pm_events Publisher: PM (Practice Management) — pm_merge_patients() SECURITY DEFINER function (PM-01-EN-01) Subscribers: CL (chart cache invalidation), PM-08 (claims grouping cache), CE-29 (lead↔patient mapping), PF-71 (patient identity boundary) Trigger: Successful commit of pm_merge_patients() after all PM/CL FK re-points and audit row write. Status: 📋 Specification Schema Version: 1 Payload Schema:
interface PatientMergedPayload {
  event_type: 'pm_patient_merged';
  schema_version: 1;
  organization_id: string;        // UUID — tenant isolation
  survivor_patient_id: string;    // UUID — winning pm_patients.id
  merged_patient_id: string;      // UUID — soft-deleted pm_patients.id
  merge_log_id: string;           // UUID — pm_patient_merge_log.id (idempotency key)
  occurred_at: string;            // ISO 8601 — commit time of pm_merge_patients()
}
PHI Logging Guidelines:
  • Allowed: all payload fields above (UUIDs and timestamp only)
  • Prohibited: merge_reason body, demographics, MRN, any chart data
  • Retention: Event row retained in fw_workflow_events; PF-44 audit row retained per HIPAA §164.312(b)
Delivery Semantics:
  • Idempotency key: merge_log_id
  • Delivery: at-least-once
  • Ordering: per survivor_patient_id
  • Undo: v1 publishes no pm_patient_merge_undone event. Consumers MUST reconcile from pm_patient_merge_log (filter rolled_back_at IS NOT NULL) when maintaining long-lived projections.
Consumer Actions:
  1. CL: Invalidate chart-by-patient caches keyed on merged_patient_id; subsequent reads will resolve to the survivor via the re-pointed cl_patient_charts.patient_id.
  2. PM-08 (Claims): Drop in-memory groupings keyed on merged_patient_id.
  3. CE-29 (Lead Conversion): Re-point lead↔patient mapping rows where applicable.
  4. PF-71 (Patient Identity Boundary): Refresh identity caches.
Implementation Notes:
  • Registered in fw_workflow_events via the PM-01-EN-01 migration (one row, schema_version = 1, owning_core = pm).
  • Channel pm_events is already declared (PM-02 events).
  • Published from inside the SECURITY DEFINER function; if the fw_workflow_events insert fails, the entire merge transaction aborts (no partial state).

PM-50: AI Denial Prediction Events

Status: 📝 Planned Spec Reference: PM-50-ai-denial-prediction-prevention.md

Event 1: pm.denial_prediction.created

Channel: pm_events Publisher: PM (Practice Management) — PM-50 / AI Denial Prediction service Subscribers: None (available for future GR dashboards or analytics) Trigger: After a denial risk prediction is generated and saved to pm_denial_predictions Status: 📝 Planned Payload Schema:
interface DenialPredictionCreatedPayload {
  event_type: 'pm.denial_prediction.created';
  prediction_id: string;          // UUID — pm_denial_predictions.id
  claim_id: string;               // UUID — pm_claims.id (FK deferred until PM-08)
  risk_score: number;             // 0-100
  risk_level: 'low' | 'medium' | 'high';
  model_version: string;          // Model version used for prediction
  organization_id: string;        // Tenant isolation (UUID)
  site_id?: string;               // UUID — optional site scope
  timestamp: string;              // ISO 8601 — event occurrence time
}
Storage:
  • Event table: fw_domain_events (via publishEvent() from @/platform/events)
  • Retention: Standard event retention policy (see EVENT_DELIVERY.md)
PHI Logging Guidelines:
  • Allowed: prediction_id, claim_id (UUID only), risk_score, risk_level, model_version, organization_id
  • Prohibited: No PHI; claim-level features are categorical/aggregate only
  • Retention: Event logged to pf_audit_logs; no PHI in application logs or edge function stdout
Purpose: Notify when a new denial prediction is created. Available for future integration with GR dashboards or analytics tracking. Implementation Note:
  • Register in fw_workflow_events table via seed migration
  • Published via publishEvent() from @/platform/events after prediction record creation in predict-denial-risk edge function

Event 2: pm.denial_prediction.outcome_recorded

Channel: pm_events Publisher: PM (Practice Management) — PM-50 / PM-29 Denial Management (via feedback loop) Subscribers: PM-50 (retraining pipeline for model feedback) Trigger: When actual_outcome field is updated on pm_denial_predictions (claim adjudication result recorded) Status: 📝 Planned Payload Schema:
interface DenialPredictionOutcomeRecordedPayload {
  event_type: 'pm.denial_prediction.outcome_recorded';
  prediction_id: string;          // UUID — pm_denial_predictions.id
  claim_id: string;               // UUID — pm_claims.id
  actual_outcome: 'paid' | 'denied';
  actual_denial_reason?: string;  // Optional — denial reason code if denied
  prediction_correct: boolean;    // Whether prediction matched outcome
  organization_id: string;        // Tenant isolation (UUID)
  timestamp: string;              // ISO 8601 — event occurrence time
}
Storage:
  • Event table: fw_domain_events (via publishEvent() from @/platform/events)
  • Retention: Standard event retention policy (see EVENT_DELIVERY.md)
PHI Logging Guidelines:
  • Allowed: prediction_id, claim_id (UUID only), actual_outcome, actual_denial_reason (code only), organization_id
  • Prohibited: No PHI; denial reason is code-level only (no narrative)
  • Retention: Event logged to pf_audit_logs; no PHI in application logs or edge function stdout
Purpose: Notify when actual claim outcome is recorded for model feedback. PM-50 retraining pipeline consumes this to improve prediction accuracy. Consumer Actions:
  1. PM-50 Retraining: Add outcome to training dataset for monthly model retraining
  2. Analytics: Track prediction accuracy over time (precision/recall metrics)
Implementation Note:
  • Register in fw_workflow_events table via seed migration
  • Published via database trigger on pm_denial_predictions UPDATE when actual_outcome changes from NULL to non-NULL
  • Alternative: Published via publishEvent() from PM-29 when denial outcome is recorded

CL-09: cl_lab_order_created

Event: cl_lab_order_created
Channel: cl_pm_events
Publisher: CL (Clinical & EHR) — CL-09
Subscribers: PF-10 (Notifications), FW (Workflow Automation)
Status: 📝 Planned
Spec Reference: CL-09 – Lab & Diagnostic Orders & Results
Integration Doc: CL-09-lab-diagnostic-orders-results-INTEGRATION.md
Owner: CL team.
Purpose: Notify when a lab order transitions from draft to ordered so downstream systems can track pending orders and trigger workflow automations. Trigger Conditions: UPDATE on cl_orders WHERE NEW.status = 'ordered' AND OLD.status = 'draft'. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "cl_lab_order_created".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
site_iduuidOptionalIf site-scoped.
user_iduuidYesOrdering clinician.
correlation_idstring (uuid)OptionalFor audit/chain.
order_iduuidYesOrder record ID.
chart_iduuidYesPatient chart ID.
ordering_provider_iduuidYesOrdering provider ID.
loinc_codestringYesLOINC code for the ordered test.
prioritystringYesroutine or stat.
lab_iduuidOptionalReference lab ID if external.
PHI Logging Guidelines:
  • Allowed: order_id, chart_id, ordering_provider_id, loinc_code, priority, lab_id, organization_id
  • Prohibited: Patient names, DOB, SSN, result values, diagnosis information
  • Retention: Event logged to pf_audit_logs; no PHI in application logs or edge function stdout
Implementation: Not yet implemented. Published via publishEvent() from @/platform/events.

CL-09: cl_lab_result_received

Event: cl_lab_result_received
Channel: cl_pm_events
Publisher: CL (Clinical & EHR) — CL-09 / External Lab Interface
Subscribers: CL-08 (Clinical Decision Support — abnormal result alert via evaluateCdsRules()), PF-10 (Notifications)
Status: 📝 Planned
Spec Reference: CL-09 – Lab & Diagnostic Orders & Results
Integration Doc: CL-09-lab-diagnostic-orders-results-INTEGRATION.md
Owner: CL team.
Purpose: Notify when a lab result is ingested (via HL7v2/FHIR interface or manual entry) so CL-08 CDS can evaluate for abnormal result alerts and notifications can be sent to the ordering provider. Trigger Conditions: INSERT on cl_order_results (result ingested from external interface or manually entered); order status transitions to resulted. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "cl_lab_result_received".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
site_iduuidOptionalIf site-scoped.
user_iduuidOptionalNull for interface-ingested results.
correlation_idstring (uuid)OptionalFor audit/chain.
order_iduuidYesParent order ID.
result_iduuidYesResult record ID.
chart_iduuidYesPatient chart ID.
loinc_codestringYesLOINC code for the resulted test.
abnormal_flagstringOptionalN, L, H, LL, HH, A per HL7 Table 0078.
sourcestringYesinterface or manual.
PHI Logging Guidelines:
  • Allowed: order_id, result_id, chart_id, loinc_code, abnormal_flag, source, organization_id
  • Prohibited: Patient names, DOB, SSN, actual result values (result_value, result_value_numeric), reference ranges
  • Retention: Event logged to pf_audit_logs; no PHI in application logs or edge function stdout
Consumer Actions:
ConsumerActionStatus
CL-08 (CDS)Evaluate evaluateCdsRules() for abnormal result alerts📝 Planned
PF-10 (Notifications)Notify ordering provider of new result📝 Planned
Event ConsumerLog to pf_audit_logs📝 Planned
Implementation: Not yet implemented. Published via publishEvent() from @/platform/events or from the cl-lab-result-ingestion edge function for interface-ingested results.

CL-09: cl_lab_result_reviewed

Event: cl_lab_result_reviewed
Channel: cl_pm_events
Publisher: CL (Clinical & EHR) — CL-09
Subscribers: PF-10 (Notifications), PF-04 (Audit)
Status: 📝 Planned
Spec Reference: CL-09 – Lab & Diagnostic Orders & Results
Integration Doc: CL-09-lab-diagnostic-orders-results-INTEGRATION.md
Owner: CL team.
Purpose: Notify when a clinician signs off on (reviews) a lab result, completing the result review workflow. This creates an audit trail and can trigger downstream notifications. Trigger Conditions: UPDATE on cl_order_results WHERE NEW.reviewed_by IS NOT NULL AND OLD.reviewed_by IS NULL; order status transitions to reviewed. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "cl_lab_result_reviewed".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
site_iduuidOptionalIf site-scoped.
user_iduuidYesReviewing clinician.
correlation_idstring (uuid)OptionalFor audit/chain.
order_iduuidYesParent order ID.
result_iduuidYesResult record ID.
chart_iduuidYesPatient chart ID.
reviewed_byuuidYesClinician who reviewed/signed off.
PHI Logging Guidelines:
  • Allowed: order_id, result_id, chart_id, reviewed_by, organization_id
  • Prohibited: Patient names, DOB, SSN, actual result values, clinical notes
  • Retention: Event logged to pf_audit_logs; no PHI in application logs or edge function stdout
Implementation: Not yet implemented. Published via publishEvent() from @/platform/events.

PF-63: Teams Channel Notification Dispatch

Event: teams_channel_notification_dispatched
Publisher: PF (Platform Foundation) — event-consumer edge function
Subscribers: entra-teams-notify edge function
Status: ✅ Complete
Implemented: 2026-02-21
Description: When any domain event is consumed by event-consumer, it checks pf_teams_notification_config for matching rules. If active rules exist for the event type and organization, it dispatches messages to the configured Teams channels via entra-teams-notify. Routing Mechanism:
  • Table: pf_teams_notification_config
  • Match criteria: organization_id + event_name + is_active = true
  • Each matching rule triggers a separate call to entra-teams-notify
Payload Schema:
{
  event_type: string;          // The original domain event name
  payload: {
    organization_id: uuid;     // Required for tenant isolation
    [key: string]: unknown;    // Event-specific data
  };
}
Dispatch Payload (to entra-teams-notify):
{
  organization_id: uuid;
  team_id: string;             // From notification config rule
  channel_id: string;          // From notification config rule
  message_type: string;        // Original event_type
  payload: Record<string, unknown>;
  message_template?: string;   // Optional custom template from rule
}
Supported Event Types (built-in message templates):
  • hr_employee_hired — New hire announcement
  • credential_expiring — Credential expiry warning
  • form_submitted — Form submission notification
  • leave_approved — Leave approval notification
  • rh_resident_admitted — New resident admission (canonical; replaces resident_admitted)
Security:
  • Service-role authentication for dispatch calls
  • HTML escaping on all interpolated template values
  • Organization access verified via verifyOrgAccess()

CL-12: Care Coordination & Transitions Events

Event: referral_accepted

Channel: cl_pm_events
Publisher: PM (Practice Management) — PM-06
Subscribers: CL-12 (Care Coordination)
Status: ✅ Implemented (Consumer in event-consumer edge function) Spec Reference: CL-12, CL-PM-REFERRALS
Purpose: When a referral is accepted (PM-06 status → admitted), CL-12 creates a cl_transitions record (type = referral), links referral_id, and triggers discharge checklist / medication reconciliation as applicable. Trigger Conditions: UPDATE on pm_referrals WHERE NEW.status = 'admitted' AND OLD.status != 'admitted'. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "referral_accepted".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
user_iduuidYesUser who accepted the referral.
correlation_idstring (uuid)OptionalFor audit/chain.
referral_iduuidYesPM-06 referral record ID.
patient_iduuidYesPatient ID.
referral_directionstringYesinbound or outbound.
from_facilitystringOptionalOriginating facility.
to_facilitystringOptionalDestination facility.
from_level_of_carestringOptionalSource LOC.
to_level_of_carestringOptionalDestination LOC.
referral_reasonstringYesReason for referral.
urgencystringYesroutine, urgent, or emergent.
PHI Logging Guidelines:
  • Allowed: referral_id, patient_id, organization_id, urgency, referral_direction
  • Prohibited: Patient names, DOB, SSN, clinical notes, diagnosis codes
  • Retention: Event logged to pf_audit_logs; no PHI in application logs or edge function stdout
Consumer Actions (CL-12):
  1. Create cl_transitions record with transition_type = 'referral' and referral_id
  2. If outbound: trigger discharge checklist creation
  3. Trigger medication reconciliation (CL-05)
  4. Generate C-CDA transition summary (CL-16, when available)

Event: transition_completed

Channel: cl_pm_events
Publisher: CL (Clinical & EHR) — CL-12
Subscribers: PM-06 (Referral Management)
Status: ✅ Implemented (Published by useCompleteChecklist hook) Spec Reference: CL-12, CL-PM-REFERRALS
Purpose: Published when a discharge checklist is completed for a transition that has a linked referral_id. PM-06 consumes this to update the referral status to completed. Trigger Conditions: UPDATE on cl_discharge_checklists WHERE NEW.overall_status = 'completed' AND OLD.overall_status != 'completed' AND parent cl_transitions.referral_id IS NOT NULL. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "transition_completed".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
user_iduuidYesUser who completed the checklist.
correlation_idstring (uuid)OptionalFor audit/chain.
transition_iduuidYesCL-12 transition record ID.
chart_iduuidYesPatient chart ID.
referral_iduuidYesLinked PM-06 referral ID.
transition_typestringYesdischarge, transfer, referral, etc.
checklist_iduuidYesCompleted discharge checklist ID.
PHI Logging Guidelines:
  • Allowed: transition_id, chart_id, referral_id, checklist_id, organization_id, transition_type
  • Prohibited: Patient names, DOB, SSN, checklist item notes, clinical details
  • Retention: Event logged to pf_audit_logs; no PHI in application logs or edge function stdout
Consumer Actions (PM-06):
  1. Update pm_referrals status to completed where id = referral_id

CL-15: Clinical Reporting & Quality Measures Events

Event: cl_incident_reported

Channel: cl_events
Publisher: CL (Clinical & EHR) — CL-15
Subscribers: GR-03 (Compliance Tracking), GR-04 (Audit Management), GR-08 (Accreditation Management), PF-10 (Notifications)
Status: ✅ Implemented
Spec Reference: CL-15, CL-15 Integration
Purpose: Published when a clinical incident is formally reported to the state, indicating a regulatory reporting action. GR consumes this for compliance tracking, audit workflows, and accreditation evidence. PF-10 notifies compliance officers and administrators. Trigger Conditions: UPDATE on cl_incidents WHERE NEW.reported_to_state_at IS NOT NULL AND OLD.reported_to_state_at IS NULL. Payload Schema:
interface ClIncidentReportedPayload {
  incident_id: string;              // UUID of the reported incident
  organization_id: string;          // UUID of the organization
  chart_id: string | null;          // UUID of the patient chart, if applicable
  incident_type: string;            // 'death' | 'serious_injury' | 'abuse' | 'neglect' | 'elopement' | 'other'
  severity: string;                 // 'critical' | 'major' | 'moderate' | 'minor'
  reported_to_state_at: string;     // ISO timestamp when reported to state
  reporting_deadline: string;       // ISO timestamp of the regulatory deadline
  reported_by: string;              // UUID of the user who marked it as reported
  custom_fields: Record<string, unknown>;
}
Consumer Actions:
ConsumerActionStatus
GR-03 (Compliance Tracking)Invokes gr-handle-incident-reported edge function via fw_domain_events trigger; creates gr_compliance_checks row with result: fail, check_type: ad_hoc✅ Implemented
GR-04 (Audit Management)Initiate audit workflow for reportable incidents✅ Implemented
GR-08 (Accreditation Management)Log incident as accreditation evidence (Joint Commission, CARF)✅ Implemented
PF-10 (Notifications)Notify compliance officers and administrators✅ Implemented
PHI/PII Logging Guidelines:
  • Safe to log: incident_id, organization_id, incident_type, severity, reported_by
  • Log as flag only: chart_id → log has_chart_id: true/false
  • Prohibited: patient names, chart content, clinical details
  • custom_fields must be sanitized to remove any PII/PHI before logging
Idempotency: Handled by FW-16 workflow engine via event_name + payload_hash.

CL-16-EN-01: TEFCA/QHIN Connectivity Events (Planned) \

Publisher: CL (Clinical & EHR) — CL-16-EN-01
Status: 📝 Planned
Spec Reference: CL-16-EN-01
Integration Doc: CL-16-EN-01-tefca-qhin-connectivity-INTEGRATION.md
Ownership: CL-16-EN-01 owns event production and payload versioning.
Payload constraints (all TEFCA events):
  • Required identifiers: event_id (UUID), organization_id, patient_id (nullable when unresolved), correlation_id, status.
  • Identifier-only payloads; no PHI payload bodies.
  • event_id is required for idempotency and retry deduplication across at-least-once delivery.

Event: cl_tefca_query_submitted \

Channel: cl_pm_events
Publisher: CL-16-EN-01
Consumers: PF-04 audit, operations analytics
Status: 📝 Planned
Purpose: Record submission of a TEFCA/QHIN patient query with traceable correlation. Payload minimums: event_id, organization_id, patient_id, correlation_id, status = 'submitted', requester context. event_id MUST be a UUID string and is required for idempotency/retry semantics.

Event: cl_tefca_exchange_completed \

Channel: cl_pm_events
Publisher: CL-16-EN-01
Consumers: PF-04 audit, CL-12 downstream exchange consumers
Status: 📝 Planned
Purpose: Record successful TEFCA/QHIN exchange completion for downstream retrieval/processing. Payload minimums: event_id, organization_id, patient_id, correlation_id, status = 'completed', exchange log reference. event_id MUST be a UUID string and is required for idempotency/retry semantics.

Event: cl_tefca_exchange_blocked \

Channel: cl_pm_events
Publisher: CL-16-EN-01
Consumers: PF-04 audit, compliance workflows
Status: 📝 Planned
Purpose: Record policy/consent-blocked TEFCA exchange attempts (fail-closed path). Payload minimums: event_id, organization_id, patient_id, correlation_id, status = 'blocked', policy/consent block reason code. event_id MUST be a UUID string and is required for idempotency/retry semantics.

CL-16: FHIR Interoperability & Data Exchange Events

Event: cl_fhir_bundle_exported

Channel: cl_pm_events
Publisher: CL (Clinical & EHR) — CL-16
Subscribers: PF-04 (Audit), PF-10 (Notifications)
Status: 🟡 In Progress (Phase 1)
Spec Reference: CL-16
Purpose: Published when a FHIR $patient-everything bundle or bulk export is completed. Triggers audit logging and optional notifications to compliance staff. Trigger Conditions: Successful completion of patient-everything action in the fhir-r4 edge function. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "cl_fhir_bundle_exported".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
user_iduuidYesUser who triggered the export.
correlation_idstring (uuid)OptionalFor audit/chain.
chart_iduuidYesPatient chart ID.
exchange_log_iduuidYescl_data_exchange_log record ID.
exchange_typestringYesfhir_api, bulk_export, or patient_access.
resource_typesstring[]YesFHIR resource types included (e.g., ["Patient","Condition"]).
record_countnumberYesTotal resources in the bundle.
has_part2_consentbooleanYesWhether Part 2 consent was active (determines if SUD data was included).
PHI Logging Guidelines:
  • Allowed: chart_id, exchange_log_id, organization_id, user_id, exchange_type, resource_types, record_count, has_part2_consent
  • Prohibited: Patient names, DOB, SSN, diagnosis codes, medication names, clinical content
  • Retention: Event logged to pf_audit_logs; no PHI in application logs or edge function stdout
Consumer Actions:
  1. PF-04 (Audit): Log export event to pf_audit_logs with exchange details
  2. PF-10 (Notifications): Optionally notify compliance officer for bulk/patient-access exports
Idempotency: Unique on (correlation_id, event_type). Consumers should deduplicate by exchange_log_id.

Event: cl_ccda_document_sent

Channel: cl_pm_events
Publisher: CL (Clinical & EHR) — CL-16
Subscribers: PF-04 (Audit), GR (Governance & Compliance)
Status: 📝 Planned (Phase 2)
Spec Reference: CL-16
Purpose: Published when a C-CDA 2.1 document is sent to an external partner (e.g., Arizona Contexture HIE, DirectTrust recipient). Triggers audit logging and compliance tracking. Trigger Conditions: Successful transmission of C-CDA document to external recipient. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "cl_ccda_document_sent".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
user_iduuidYesUser or service account that initiated the send.
correlation_idstring (uuid)OptionalFor audit/chain.
chart_iduuidYesPatient chart ID.
exchange_log_iduuidYescl_data_exchange_log record ID.
document_typestringYesCCD, discharge_summary, or referral_note.
partner_iduuidOptionalRecipient organization/partner ID.
partner_namestringOptionalRecipient name (e.g., “Arizona Contexture”).
has_part2_consentbooleanYesWhether Part 2 consent was active.
redisclosure_notice_includedbooleanYesWhether 42 CFR Part 2 redisclosure notice was attached.
PHI Logging Guidelines:
  • Allowed: chart_id, exchange_log_id, organization_id, user_id, document_type, partner_id, partner_name, has_part2_consent, redisclosure_notice_included
  • Prohibited: Patient names, DOB, SSN, clinical content, diagnosis codes
  • Retention: Event logged to pf_audit_logs; no PHI in application logs
Consumer Actions:
  1. PF-04 (Audit): Log send event with partner details and document type
  2. GR (Compliance): Track C-CDA exchanges for regulatory reporting; verify redisclosure notice compliance
Idempotency: Unique on (correlation_id, event_type). Consumers deduplicate by exchange_log_id.

Event: cl_ccda_document_received

Channel: cl_pm_events
Publisher: CL (Clinical & EHR) — CL-16
Subscribers: CL-01 (Patient Chart), PF-10 (Notifications)
Status: 📝 Planned (Phase 2)
Spec Reference: CL-16
Purpose: Published when a C-CDA 2.1 document is received from an external partner (e.g., HIE, DirectTrust sender). Triggers chart update and notifications to the assigned clinician. Trigger Conditions: Successful ingestion and parsing of inbound C-CDA document. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "cl_ccda_document_received".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
user_iduuidOptionalService account or user who processed the document.
correlation_idstring (uuid)OptionalFor audit/chain.
chart_iduuidYesMatched patient chart ID (after MPI resolution).
exchange_log_iduuidYescl_data_exchange_log record ID.
document_typestringYesCCD, discharge_summary, referral_note, or adt_notification.
partner_iduuidOptionalSending organization/partner ID.
partner_namestringOptionalSender name.
resource_types_extractedstring[]YesFHIR resource types parsed from the C-CDA (e.g., ["Condition","MedicationRequest"]).
record_countnumberYesNumber of discrete data elements extracted.
reconciliation_neededbooleanYesWhether new data conflicts with existing chart data.
PHI Logging Guidelines:
  • Allowed: chart_id, exchange_log_id, organization_id, document_type, partner_id, partner_name, resource_types_extracted, record_count, reconciliation_needed
  • Prohibited: Patient names, DOB, SSN, extracted clinical content, diagnosis codes, medication names
  • Retention: Event logged to pf_audit_logs; no PHI in application logs
Consumer Actions:
  1. CL-01 (Chart): Flag chart for reconciliation review if reconciliation_needed = true; store document reference in cl_patient_chart_documents
  2. PF-10 (Notifications): Notify assigned clinician that new external data is available for review
Idempotency: Unique on (correlation_id, event_type). Consumers deduplicate by exchange_log_id.

PM-13: Telehealth Integration Events

Event: telehealth_session_started

Channel: cl_pm_events
Publisher: PM-13 (Telehealth Integration)
Status: ✅ Implemented
Last Verified: 2026-02-23
Purpose: Published when a telehealth session transitions to active status. Provides encounter context for modifier selection and clinical documentation. Trigger Conditions: pm_telehealth_sessions.session_status updated from scheduled or waiting to active. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "telehealth_session_started".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
user_iduuidYesProvider who started the session.
correlation_idstring (uuid)OptionalFor audit/chain.
session_iduuidYespm_telehealth_sessions.id.
appointment_iduuidYesLinked pm_appointments.id.
encounter_iduuidOptionalLinked encounter ID, if created.
telehealth_modalitystringYesaudio_video, audio_only, store_forward, or remote_monitoring.
platformstringYesPlatform name (e.g., Zoom Healthcare, Doxy.me, stub).
PHI Logging Guidelines:
  • Allowed: session_id, appointment_id, encounter_id, organization_id, telehealth_modality, platform, user_id
  • Prohibited: Patient names, DOB, SSN, session URLs, join links, recording URLs
  • Retention: Event logged to pf_audit_logs; no PHI in application logs
Consumer Actions:
  1. FW-16 (Workflow): Trigger automation rules on session start (e.g., notify care team)
  2. PF-10 (Notifications): Send session-started notification to relevant staff
Idempotency: Unique on (correlation_id, event_type). Consumers deduplicate by session_id.

Event: telehealth_session_completed

Channel: cl_pm_events
Publisher: PM-13 (Telehealth Integration)
Status: ✅ Implemented
Last Verified: 2026-02-23
Purpose: Published when a telehealth session transitions to completed status. Provides session metadata for PM-07 auto-modifier/POS assignment and CL-04 clinical documentation pre-fill. Trigger Conditions: pm_telehealth_sessions.session_status updated to completed. Payload Schema:
FieldTypeRequiredDescription
event_typestringYesMust equal "telehealth_session_completed".
organization_iduuidYesTenant isolation.
timestampstring (ISO 8601)YesEvent occurrence time.
user_iduuidYesProvider who ended the session.
correlation_idstring (uuid)OptionalFor audit/chain.
session_iduuidYespm_telehealth_sessions.id.
appointment_iduuidYesLinked pm_appointments.id.
encounter_iduuidOptionalLinked encounter ID.
telehealth_modalitystringYesaudio_video, audio_only, store_forward, or remote_monitoring.
is_audio_onlybooleanYesDeprecated flag for backward compat with PM-07 modifier-logic.ts.
patient_locationstringOptionalPatient location (e.g., home, office). Drives POS code (10 vs 02).
provider_locationstringOptionalProvider location.
duration_minutesnumberOptionalSession duration in minutes.
PHI Logging Guidelines:
  • Allowed: session_id, appointment_id, encounter_id, organization_id, telehealth_modality, is_audio_only, duration_minutes, user_id
  • Prohibited: Patient names, DOB, SSN, session URLs, recording URLs, patient_location (may reveal home address)
  • Masking: patient_location logged as presence flag (has_patient_location: true/false), not raw value
  • Retention: Event logged to pf_audit_logs; no PHI in application logs
Consumer Actions:
  1. PM-07 (Charge Capture): Apply telehealth modifiers (95/FQ/GQ) and POS (02/10) based on telehealth_modality and patient_location when clinical_note_finalized fires
  2. FW-16 (Workflow): Trigger post-session automation (e.g., satisfaction survey, follow-up scheduling)
  3. CL-04 (Progress Notes): Pre-fill telehealth fields (is_telehealth, telehealth_modality, patient_location, provider_location) on the clinical note
Idempotency: Unique on (correlation_id, event_type). Consumers deduplicate by session_id.
Next Review: 2026-03-03 (Quarterly)

PM-15: Clearinghouse Integration Events

Status: 📝 Planned Implemented: TBD Spec Reference: PM-15 (Clearinghouse Integration)

Event 1: clearinghouse_batch_submitted

Publisher: PM (Practice Management) — PM-15 Clearinghouse Subscribers: PM-08 (Claims), PF-10 (Notifications), PM-11 (RCM Dashboard) Payload Schema:
interface PmClearinghouseBatchSubmittedPayload {
  batch_id: string;              // UUID of the submitted batch
  clearinghouse_id: string;      // UUID of the clearinghouse config
  transaction_type: string;      // e.g., '837p', '837i'
  file_name: string;             // Name of the submitted file
  record_count: number;          // Number of records (claims) in batch
  submitted_at: string;          // ISO timestamp of submission
  organization_id: string;       // UUID of the organization
  user_id: string;               // UUID of user who triggered submission
}
Purpose: Notify downstream systems that a batch has been successfully transmitted to the clearinghouse. PHI Logging Guidelines:
  • Allowed: batch_id, clearinghouse_id, transaction_type, record_count, organization_id, user_id
  • Prohibited: file_name (if it contains patient names/MRNs)
  • Masking: Log file_name only if guaranteed safe (e.g., BATCH_20260223_001.x12); otherwise hash or redact
  • Retention: Logged to pf_audit_logs
Consumer Actions:
  1. PM-08 (Claims): Update claim status to submitted for all claims in the batch
  2. PM-11 (RCM Dashboard): Increment submission metrics
  3. PF-10 (Notifications): Notify billing admin of successful submission

Event 2: clearinghouse_batch_error

Publisher: PM (Practice Management) — PM-15 Clearinghouse Subscribers: PM-08 (Claims), PF-10 (Notifications) Payload Schema:
interface PmClearinghouseBatchErrorPayload {
  batch_id: string;              // UUID of the failed batch
  clearinghouse_id: string;      // UUID of the clearinghouse config
  transaction_type: string;      // e.g., '837p'
  error_code: string;            // Functional error code (e.g., 'AUTH_FAILED', 'SCHEMA_INVALID')
  error_message: string;         // Human-readable error
  organization_id: string;       // UUID of the organization
  timestamp: string;             // ISO timestamp of error
}
Purpose: Notify that a batch submission failed (e.g., connectivity error, 999 rejection). PHI Logging Guidelines:
  • Allowed: batch_id, clearinghouse_id, transaction_type, error_code, organization_id
  • Prohibited: error_message (if it contains patient identifiers from a rejection)
  • Masking: Sanitize error_message to remove potential PHI before logging
  • Retention: Logged to pf_audit_logs
Consumer Actions:
  1. PM-08 (Claims): Update claim status to error / draft (returned for correction)
  2. PF-10 (Notifications): Alert billing admin of submission failure

Event 3: clearinghouse_era_received

Publisher: PM (Practice Management) — PM-15-P2 Clearinghouse Transport (Phase 2b) Subscribers: PM-09 (Payment Posting & ERA), PM-29 (Denial Management) Channel: pm_events Status: 📝 Planned Payload Schema:
interface PmClearinghouseEraReceivedPayload {
  event_type: 'clearinghouse_era_received';
  event_id: string;              // UUID — Required for consumer deduplication (idempotency)
  correlation_id?: string;       // UUID — Optional correlation across related events
  era_file_id: string;           // UUID of the pm_era_files record created by parser
  organization_id: string;       // Tenant isolation (UUID)
  batch_id: string;              // UUID of the retrieval batch (pm_transaction_batches)
  claim_count: number;           // Number of CLP segments parsed
  total_paid: number;            // Sum of CLP-04 (total claim payment amount)
  timestamp: string;             // ISO 8601 — event occurrence time
}
Purpose: Notify downstream systems that an 835 ERA file has been retrieved from the clearinghouse and parsed. PM-09 uses this to trigger the payment posting pipeline; PM-29 uses CARC/RARC data from the parsed ERA for denial routing. PHI Logging Guidelines:
  • Allowed: event_id, correlation_id, era_file_id, batch_id, claim_count, total_paid, organization_id
  • Prohibited: Storage object paths and individual CLP/SVC claim-level data
  • Masking: If internal diagnostics require a storage lookup, log only the opaque era_file_id
  • Retention: Logged to pf_audit_logs
Consumer Actions:
  1. PM-09 (Payment Posting & ERA): Resolve storage location from era_file_id, then run payment posting pipeline — create pm_payments and pm_payment_applications from CLP/SVC data; persist CARC/RARC into pm_transaction_log.error_codes
  2. PM-29 (Denial Management): Route CARC/RARC codes for denial intake and appeal workflow

Event 4: clearinghouse_health_changed

Publisher: PM (Practice Management) — PM-15-P2 Health Monitoring (Phase 2c) Subscribers: PF-10 (Notifications) Channel: pm_events Status: 📝 Planned Payload Schema:
interface PmClearinghouseHealthChangedPayload {
  event_type: 'clearinghouse_health_changed';
  event_id: string;              // UUID — Required for consumer deduplication (idempotency)
  config_id: string;             // UUID of pm_clearinghouse_config
  organization_id: string;       // Tenant isolation (UUID)
  old_status: 'healthy' | 'degraded' | 'down' | 'unknown';
  new_status: 'healthy' | 'degraded' | 'down' | 'unknown';
  timestamp: string;             // ISO 8601 — event occurrence time
}
Purpose: Notify when clearinghouse connection health status changes. PF-10 fires alerts on transitions to down or degraded; recovery notifications are throttled (require 2 consecutive healthy checks before alerting on healthy transition). PHI Logging Guidelines:
  • Allowed: All fields (no PHI in health status events)
  • Prohibited: None (event contains no patient data)
  • Retention: Logged to pf_audit_logs
Consumer Actions:
  1. PF-10 (Notifications): Alert billing admin on down or degraded; send recovery notification on healthy (throttled: 2 consecutive healthy checks required)

PM-47: Managed Care Auth Tracking

Status: 📝 Planned Spec Reference: PM-47-managed-care-authorization-tracking.md Integration Doc: PM-47-managed-care-authorization-tracking-INTEGRATION.md

Event: pm_auth_expiring

Channel: pm_events Publisher: PM (Practice Management) — PM-47 Subscribers: PM (dashboard refresh), CL (clinical review preparation) Trigger: Daily cron edge function checks authorizations approaching expiration thresholds Status: 📝 Planned Payload Schema:
interface PmAuthExpiringPayload {
  event_type: 'pm_auth_expiring';
  event_id: string;              // UUID — Required for consumer deduplication (idempotency)
  correlation_id?: string;       // UUID — Optional correlation across related events
  organization_id: string;       // Tenant isolation (UUID)
  authorization_id: string;      // UUID — pm_managed_care_authorizations.id
  patient_id: string;            // UUID — patient identifier only; no PHI in payload
  payer_id: string;              // UUID — payer identifier
  expiration_date: string;       // ISO 8601 date
  days_remaining: number;        // Days until expiration
  service_type: string;          // e.g., 'residential', 'php', 'iop'
  timestamp: string;             // ISO 8601 — event occurrence time
}
PHI Logging Guidelines:
  • Allowed (PHI-safe identifiers): event_id, correlation_id, authorization_id, patient_id (UUID only), payer_id, expiration_date, days_remaining, service_type, organization_id
  • Prohibited: Patient name, DOB, auth details beyond what’s in schema
  • Retention: Event logged to pf_audit_logs
  • Logging Guidance: Log only event_id, correlation_id, and non-PHI identifiers (e.g., organization_id, authorization_id, payer_id) in application logs; omit patient-identifiable data
Consumer Actions:
  1. PM (dashboard): Refresh auth expiration dashboard counts
  2. CL (clinical review): Pre-populate concurrent review task with auth context

Event: pm_auth_validation_failed

Channel: pm_events Publisher: PM (Practice Management) — PM-47 Subscribers: PM-08 (claim submission gate) Trigger: Pre-submission auth-to-claim validation detects authorization coverage gaps Status: 📝 Planned Payload Schema:
interface PmAuthValidationFailedPayload {
  event_type: 'pm_auth_validation_failed';
  event_id: string;              // UUID — Required for consumer deduplication (idempotency)
  correlation_id?: string;       // UUID — Optional correlation across related events
  organization_id: string;       // Tenant isolation (UUID)
  claim_id: string;              // UUID — pm_claims.id
  failed_lines: Array<{
    line_number: number;
    reason_code: 'no_active_auth' | 'units_exceeded' | 'date_outside_auth';  // Machine-readable bounded enum
    message?: string;            // Optional human-readable message (localization-friendly)
  }>;
  timestamp: string;             // ISO 8601 — event occurrence time
}
Validation Failure Reason Codes:
  • no_active_auth — No active authorization found for the service date and service type
  • units_exceeded — Claim line units exceed remaining authorized units
  • date_outside_auth — Service date falls outside the authorization’s valid date range
PHI Logging Guidelines:
  • Allowed (PHI-safe identifiers): event_id, correlation_id, claim_id, line_number, reason_code, organization_id
  • Prohibited: Claim line service details, patient identifiers
  • Retention: Event logged to pf_audit_logs
  • Logging Guidance: Log only event_id, correlation_id, and non-PHI identifiers (e.g., organization_id, claim_id, reason_code) in application logs; omit patient-identifiable data and the optional message field
Consumer Actions:
  1. PM-08 (claim submission): Block claim submission; display validation failure details to user

CL-21: MAT/MOUD Tracking Events

cl_moud_monitoring_overdue

Publisher: CL-21 (MAT/MOUD Tracking)
Subscribers: PF-10 (Notifications)
Status: 📝 Planned
Channel: cl_events
Description: Fired when a monitoring event (UDS, hepatic panel, etc.) passes its due_by timestamp without a completed_at value. Payload Schema:
{
  event: 'cl_moud_monitoring_overdue';
  payload: {
    monitoring_event_id: uuid;
    enrollment_id: uuid;
    chart_id: uuid;
    monitoring_type: 'uds' | 'hepatic_panel' | 'pregnancy_test' | 'other_lab';
    due_by: string;           // ISO timestamp
    days_overdue: number;
  };
  metadata: {
    organization_id: uuid;
    user_id?: uuid;           // System-triggered; may be null
    timestamp: string;        // ISO timestamp
  };
}
PHI Logging Guidelines:
  • Allowed: monitoring_event_id, enrollment_id, monitoring_type, due_by, days_overdue, organization_id
  • Prohibited: chart_id should be logged as has_chart_id: true/false, not as raw UUID
  • Retention: Logged to pf_audit_logs
Consumer Actions:
  1. PF-10 (Notifications): Alert clinical staff and supervisors of overdue monitoring

cl_moud_adherence_risk

Publisher: CL-21 (MAT/MOUD Tracking)
Subscribers: PF-10 (Notifications)
Status: 📝 Planned
Channel: cl_events
Description: Fired when a patient’s medication adherence status indicates risk (e.g., consecutive missed doses or declining adherence pattern). Payload Schema:
{
  event: 'cl_moud_adherence_risk';
  payload: {
    enrollment_id: uuid;
    chart_id: uuid;
    adherence_status: 'missed' | 'late';
    consecutive_missed_count: number;
    last_event_at: string;    // ISO timestamp of last medication event
  };
  metadata: {
    organization_id: uuid;
    user_id?: uuid;           // System-triggered; may be null
    timestamp: string;        // ISO timestamp
  };
}
PHI Logging Guidelines:
  • Allowed: enrollment_id, adherence_status, consecutive_missed_count, organization_id
  • Prohibited: chart_id should be logged as has_chart_id: true/false, not as raw UUID
  • Retention: Logged to pf_audit_logs
Consumer Actions:
  1. PF-10 (Notifications): Alert prescriber and care team of adherence risk

PF-48: Security Event Detected

Status: ✅ Implemented
Event: security_event_detected
Channel: Database Webhook on pf_security_events INSERT
Publisher: PF-48 (Security Event Monitoring)
Subscribers: PF-04 (Audit), PF-10 (Notifications), PF-36 (Health Dashboard)
Delivery Mechanism: Supabase Database Webhook triggers security-event-alert-delivery Edge Function on INSERT to pf_security_events. Payload (webhook record):
interface SecurityEventWebhookPayload {
  record: {
    id: string;                    // Event UUID
    organization_id: string;       // Tenant (nullable for pre-auth events)
    event_type: string;            // e.g. 'failed_login', 'permission_violation'
    severity: string;              // 'info' | 'warning' | 'error' | 'critical'
    user_id?: string;              // Affected user (if known)
    ip_address?: string;           // Source IP (INET, nullable)
    is_suspicious: boolean;        // Pattern-based suspicion flag
  };
  type: 'INSERT';
}
Handler Requirements:
  1. Refetch full row from pf_security_events by event_id before processing
  2. Verify organization_id matches webhook payload (TOCTOU protection)
  3. Match against pf_security_alert_configs for active alert rules
  4. Deliver via PF-10 with retry (3 attempts, exponential backoff)
  5. Write to pf_security_alert_delivery_failures (DLQ) on permanent failure
PHI: No PHI in payload. Event metadata only (IDs, types, severity). Consumer Actions:
  1. PF-10 (Notifications): Deliver security alerts to configured recipients
  2. PF-04 (Audit): Log security event processing
  3. PF-36 (Health Dashboard): Display security event metrics

PF-43: Quota Violated

Status: 📝 Planned
Event: pf_quota_violated
Publisher: PF-43 (Quota enforcement framework)
Subscribers: PF-10 (Notifications), PF-48 (Security Event Monitoring — future)
Purpose: Notify platform and organization admins when a quota soft or hard limit is exceeded. Payload (canonical): All payload keys use snake_case. Envelope fields are required for idempotency and routing per Event Schema Standard (§ Idempotency and Retry).
FieldTypeRequiredDescription
event_idstring (UUID)YesUnique idempotency key; consumers MUST skip duplicates
occurred_atstringYesISO 8601 timestamp when the event occurred
sourcestringYesProducer identifier (e.g. pf-43-quota-enforcement)
spec_versionstringYesEvent contract version (e.g. semver 1.0.0) for evolution
event_versionstringYesContract version for pf_quota_violated (semver); required for safe evolution
organization_idstring (UUID)YesOrganization the quota applies to
resource_typestringYesOne of: storage, api_calls, users, custom_objects, workflow_executions
limit_typestringYessoft or hard
quota_valuenumberYesConfigured quota value
actual_usagenumberYesUsage that caused the violation
violated_atstringYesISO 8601 timestamp of the violation
Integration Doc: PF-43-tenant-resource-quotas-INTEGRATION.md — see pf_quota_violated schema and envelope. Consumer Actions:
  • PF-10: Send notification to platform/org admins per alert threshold and mute settings
  • PF-48: Ingest security event for monitoring/analytics

PF-36 Phase 2: SLA Violation Events

pf.sla.violation.detected

Publisher: PF-36 (System Health Dashboard — SLA Violation Detection)
Subscribers: PF-10 (Notifications)
Trigger: pf-detect-sla-violations edge function detects metric value breaching SLA threshold.
{
  event_type: 'pf.sla.violation.detected';
  violation_id: uuid;
  metric_id: uuid;
  metric_name: string;
  threshold_id: uuid;
  severity: 'critical' | 'warning' | 'info';
  current_value: number;
  threshold_value: number;
  organization_id: uuid;
  timestamp: timestamptz;
}
SLA: Processing < 1s p95 Consumer Actions:
  1. PF-10 (Notifications): Deliver SLA violation alerts to configured recipients (in-app + email)

pf.sla.violation.resolved

Publisher: PF-36 (System Health Dashboard — SLA Violation Detection)
Subscribers: PF-10 (Notifications)
Trigger: pf-detect-sla-violations detects metric returned to within SLA threshold.
{
  event_type: 'pf.sla.violation.resolved';
  violation_id: uuid;
  metric_id: uuid;
  metric_name: string;
  organization_id: uuid;
  resolved_at: timestamptz;
  duration_minutes: number;
  timestamp: timestamptz;
}
Consumer Actions:
  1. PF-10 (Notifications): Deliver resolution notification to original alert recipients

PF-68: Website Chatbot — Lead Captured

pf_chatbot_lead_captured

Status: ✅ Implemented
Publisher: chatbot-lead-capture edge function
Channel: domain_events
Subscribers:
SubscriberAction
CE-01 (Contacts/Leads)Create or update contact and lead records
PF-35 (Webhooks)Dispatch webhook to external CRM integrations
Payload:
interface PfChatbotLeadCapturedPayload {
  organization_id: uuid;
  session_id: uuid;
  contact_id: uuid;
  lead_id: uuid;
  visitor_name: string;
  visitor_email: string;
  source_url: string | null;
  timestamp: timestamptz;
}
Consumer Actions:
  1. CE-01: Link lead to chatbot session source, set source_type = 'chatbot'
  2. PF-35: Forward lead data to configured webhook endpoints

CE: Community Engagement Events

ce.suppression.created

Status: 📝 Planned (CE-16) Publisher: CE-16 (Communications Compliance & Suppression) Channel: domain_events Spec Reference: CE-16 spec Subscribers:
SubscriberAction
CE-08 (SMS)Invalidate suppression cache for the contact
CE-09 (Email Campaigns)Invalidate suppression cache; remove from in-flight campaign send lists
CE-03 (Call Management)Invalidate DNC/phone cache before next outbound dial
Payload (IDs only — no PII/PHI):
interface CeSuppressionCreatedPayload {
  suppression_id: string;   // uuid
  contact_id: string;       // uuid
  organization_id: string;  // uuid
  channels: Array<'sms' | 'email' | 'phone'>;
  reason: string;           // see ce_suppressions.suppression_reason CHECK
  source: string;           // see ce_suppressions.suppression_source CHECK
  created_at: string;       // ISO 8601
}
Idempotency: suppression_id — subscribers MUST deduplicate. PII Handling: No phone numbers, emails, or names in the payload. Consumers needing contact details MUST resolve via authorized read of ce_contacts.

ce_lead_converted

Status: ✅ Implemented (⚠️ Deprecated — CE-29: use ce_lead_converted_to_patient or ce_lead_converted_to_resident instead) Publisher: CE-01 (Contacts & Lead Management)
Channel: domain_events
Spec Reference: CE-17 CE–RH Admission Handoff Contract
Subscribers:
SubscriberAction
RH-01 (Resident Management)Create resident admission from converted lead
Payload:
interface CeLeadConvertedPayload {
  // Event metadata
  event_id: string; // UUID for idempotency
  organization_id: uuid;
  timestamp: string; // ISO 8601
  
  // Lead/Contact identifiers
  lead_id: uuid;
  contact_id: uuid; // REQUIRED: Consumer must resolve PII via authorized read from ce_contacts
  
  // Conversion metadata
  converted_by: uuid; // User ID who performed conversion
  converted_at: string; // ISO 8601
  conversion_type: 'resident_admission' | 'other';
  conversion_reason?: string;
  
  // Lead-specific data
  lead_data: {
    source_type?: string;
    source_details?: string;
    referral_source_id?: uuid;
    partner_id?: uuid;
    // NOTE: `notes` intentionally excluded — may contain PII/PHI.
    // Consumers needing notes must read from ce_leads via authorized query.
    expected_admission_date?: string;
  };
  
  // RH-specific fields (optional overrides)
  rh_fields?: {
    program_id?: uuid;
    site_id?: uuid;
    admission_date?: string;
    admission_notes?: string;
    referring_partner_id?: uuid;
  };
}
Consumer Actions:
  1. RH-01:
    • Resolve contact PII by reading ce_contacts via contact_id with authorized access (RLS-enforced)
    • Create resident admission record with mapped fields from resolved contact data
    • Check idempotency via lead_id + organization_id (or fallback to event_id from audit table)
PII Handling: This event does NOT include PII (names, emails, phones, addresses, DOB) in the payload. Consumers MUST resolve PII by reading from ce_contacts using the provided contact_id with proper authorization checks. This ensures PII is only accessed by authorized consumers and maintains audit trails. Idempotency: RH consumer MUST check for existing admission using lead_id + organization_id before creating resident record. If lead_id is not available, fallback to event_id lookup in audit tables.

ce_lead_converted_to_patient

Status: 🔜 In Progress
Publisher: CE-29 (Lead-to-Patient Conversion Pipeline)
Channel: domain_events
Spec Reference: CE-29 Integration
Subscribers:
SubscriberAction
PM-01 (Patient Registration)Create patient record from converted lead
PM-38 (Intake Appointment Automation)Auto-schedule intake appointment
Payload: IDs only (no PII/PHI). See CE-29 integration doc for full schema.
interface CeLeadConvertedToPatientPayload {
  organization_id: uuid;
  lead_id: uuid;
  contact_id: uuid;
  correlation_id: string;
  converted_by: uuid;
  converted_at: string;
}
Idempotency: correlation_id — subscribers MUST deduplicate.

ce_lead_converted_to_resident

Status: 🔜 In Progress
Publisher: CE-29 (Lead-to-Patient Conversion Pipeline)
Channel: domain_events
Spec Reference: CE-29 Integration
Subscribers:
SubscriberAction
RH-01 (Admission Wizard)Create resident record from converted lead
PM-39 (Waitlist Management)Add to waitlist if no bed available
Payload: IDs only (no PII/PHI). See CE-29 integration doc for full schema.
interface CeLeadConvertedToResidentPayload {
  organization_id: uuid;
  site_id?: uuid;
  lead_id: uuid;
  contact_id: uuid;
  correlation_id: string;
  converted_by: uuid;
  converted_at: string;
}
Idempotency: correlation_id — subscribers MUST deduplicate.

donation_received

Status: 📝 Planned
Publisher: CE-18 (Fundraising & Donation Events)
Channel: domain_events
Spec Reference: CE-18 Fundraising & Donation Events, FA-31 CE-FA Donation Revenue Integration
Subscribers:
SubscriberAction
FA-31 (CE-FA Donation Revenue Integration)Post donation revenue to GL (FA-02, FA-05)
Payload:
interface DonationReceivedPayload {
  // Event metadata
  event_id: string; // UUID for idempotency
  organization_id: uuid;
  timestamp: string; // ISO 8601
  
  // Donation identifiers
  donation_id: uuid; // CE donation record ID
  contact_id?: uuid; // Donor contact (if linked)
  
  // Financial data
  amount: number; // Donation amount (positive number)
  currency: string; // ISO 4217 currency code (default: 'USD')
  donation_date: string; // ISO 8601 date
  
  // Fund allocation (REQUIRED for FA-31)
  fund_id?: uuid; // UUID of fa_funds row (optional if fund_type provided)
  fund_type: 'unrestricted' | 'temporarily_restricted' | 'permanently_restricted'; // REQUIRED
  
  // Campaign linkage (optional)
  campaign_id?: uuid; // CE campaign ID
  
  // Payment metadata
  payment_method?: 'cash' | 'check' | 'credit_card' | 'ach' | 'wire' | 'other';
  payment_reference?: string; // Check number, transaction ID, etc.
  
  // Donor information (non-identifying)
  donor_type?: 'individual' | 'organization' | 'anonymous';
  is_anonymous: boolean;
  
  // Additional metadata
  notes?: string;
  custom_fields?: Record<string, unknown>;
}
Consumer Actions:
  1. FA-31: Create GL journal entry (debit cash/AR, credit revenue) with fund allocation; check idempotency via event_id
Idempotency: FA consumer MUST track processed event_ids and MUST NOT create duplicate GL entries.

fundraising_campaign_completed

Status: 📝 Planned
Publisher: CE-18 (Fundraising & Donation Events)
Channel: domain_events
Spec Reference: CE-18 Fundraising & Donation Events, FA-31 CE-FA Donation Revenue Integration
Subscribers:
SubscriberAction
FA-07 (Financial Reporting)Update campaign revenue reports
FA-31 (Optional)Generate campaign summary entry
Payload:
interface FundraisingCampaignCompletedPayload {
  // Event metadata
  event_id: string; // UUID for idempotency
  organization_id: uuid;
  timestamp: string; // ISO 8601
  
  // Campaign identifiers
  campaign_id: uuid; // CE campaign ID
  campaign_name: string;
  
  // Campaign summary
  total_raised: number; // Total donations received
  goal_amount?: number; // Campaign goal (if set)
  completion_date: string; // ISO 8601 date
  
  // Campaign metadata
  campaign_type?: string; // e.g., 'annual_appeal', 'event', 'capital_campaign'
  start_date?: string; // ISO 8601
  
  // Additional metadata
  notes?: string;
  custom_fields?: Record<string, unknown>;
}
Consumer Actions:
  1. FA-07: Update campaign revenue reports with completion summary
  2. FA-31 (Optional): Generate campaign summary journal entry or report flag
Idempotency: FA consumer MUST track processed event_ids or use campaign_id + organization_id + completion_date composite key.

ce_web_form_submitted

Status: 📝 Planned
Publisher: CE-10 (Web-to-Lead Capture)
Channel: domain_events
Spec Reference: CE-10 Web-to-Lead Capture
Subscribers:
SubscriberAction
CE-01 (Contacts/Leads)Lead already created by CE-10; event provides notification for workflow triggers
CE-05 (Pipeline & Reporting)Update pipeline analytics (web form submission count, conversion tracking)
PF-10 (Notifications)Send notification to assigned staff member (if lead assignment configured)
Payload:
interface CeWebFormSubmittedPayload {
  // Event metadata
  event_id: string; // UUID for idempotency
  organization_id: uuid;
  timestamp: string; // ISO 8601
  
  // Form identifiers
  form_id: uuid; // CE web form ID
  form_name: string;
  submission_id: uuid; // Web form submission record ID
  
  // Lead/Contact identifiers (created by CE-10)
  contact_id: uuid; // Contact created from submission
  lead_id: uuid; // Lead created from submission (if applicable)
  
  // Submission metadata
  submitted_at: string; // ISO 8601
  source_url?: string; // URL where form was embedded
  utm_source?: string; // UTM parameters for attribution
  utm_medium?: string;
  utm_campaign?: string;
  
  // Submission data (non-identifying summary)
  field_count: number; // Number of fields in submission
  has_phone: boolean; // Whether phone number provided
  has_email: boolean; // Whether email provided
  
  // Additional metadata
  custom_fields?: Record<string, unknown>;
}
Consumer Actions:
  1. CE-01: Lead already created; event enables workflow automation triggers
  2. CE-05: Update pipeline analytics (web form submission metrics)
  3. PF-10: Send notification to assigned staff member
Note: Full submission data is stored in ce_web_form_submissions table (accessible via submission_id). Event payload contains only summary metadata (no PII).

FW-49: Execution Timeout & Watchdog Events

Integration: FW-49-execution-timeout-watchdog-INTEGRATION.md
See also: EVENT_DELIVERY.md — when these fire relative to the table-driven automation path.

workflow.execution.timed_out

Status: ✅ Implemented
Publisher: FW (via workflow-timeout-checker Edge Function; pg_cron–scheduled)
Channel: fw_events
Consumers: FW-47 (DLQ), FW-25 (compensation), FW-22 (monitoring)
interface WorkflowExecutionTimedOut {
  execution_id: string;
  organization_id: string;
  workflow_definition_id: string;
  on_timeout: 'fail' | 'cancel' | 'escalate';
  deadline_at: string;       // ISO-8601
  timed_out_at: string;      // ISO-8601
  duration_seconds: number;
  error_message?: string;    // Sanitized timeout error description
}

workflow.execution.deadline_extended

Status: ✅ Implemented
Publisher: FW (via extend-execution-deadline Edge Function)
Channel: fw_events
Consumers: Audit trail, FW-22 (monitoring)
interface WorkflowExecutionDeadlineExtended {
  execution_id: string;
  organization_id: string;
  previous_deadline_at: string;  // ISO-8601
  new_deadline_at: string;       // ISO-8601
  extended_by: string;           // user ID
  reason: string;
}

FW-47: Dead Letter Queue Alert Events

Integration: FW-47-dead-letter-queue-INTEGRATION.md
Publisher: FW DLQ threshold monitoring (scheduled job / worker path per integration doc)
Channel: In-app / PF-10 notifications (operational alerts; not necessarily pg_notify channels)

fw_dlq_threshold_exceeded

Status: ✅ Implemented (operational alert via PF-10)
Consumers: Automation admins, org admins (notification); optional future subscribers for dashboards
Payload (logical):
interface DlqThresholdExceededPayload {
  event_id: string; // UUID — idempotency key for notification delivery / deduplication
  organization_id: string;
  threshold_count: number;
  current_depth: number;
  source_scope?: string; // e.g. org-wide DLQ
  checked_at: string; // ISO-8601
  correlation_id?: string; // optional UUID — links related operational events (aligns with FW-16 / execution correlation)
}
Note: event_id MUST be a UUID. Timestamps remain ISO-8601, consistent with the document’s idempotency/retry guidance.

fw_dlq_new_permanent_failure

Status: ✅ Implemented (operational alert via PF-10)
Consumers: Automation admins; links to DLQ entry review UI
Payload (logical):
interface DlqNewPermanentFailurePayload {
  event_id: string; // UUID — idempotency key for notification delivery / deduplication
  organization_id: string;
  dlq_entry_id: string;
  source_type: string;
  source_id: string;
  error_classification?: string;
  failed_at: string; // ISO-8601
  correlation_id?: string; // optional UUID — links related operational events (aligns with FW-16 / execution correlation)
}
Note: event_id MUST be a UUID. Timestamps remain ISO-8601, consistent with the document’s idempotency/retry guidance.
Note: Exact notification payload shapes may mirror PF-10 notification templates; align with fw_dead_letter_queue and DLQ settings in FW module.

Planned Events (PF-82 Business Process Registry)

process_health_changed

Status: 📝 Planned
Publisher: PF (via pf_refresh_process_health scheduled function)
Channel: domain_events
Consumers: PF-36 (System Health Dashboard), PF-10 (Notifications)
interface ProcessHealthChanged {
  processId: string;           // UUID of the process
  organizationId: string;      // Tenant scoping
  processName: string;         // Human-readable process name
  previousStatus: 'healthy' | 'degraded' | 'critical' | 'unknown';
  newStatus: 'healthy' | 'degraded' | 'critical' | 'unknown';
  healthScore: number;         // Composite score 0–100
  topContributingFactor: string; // Component with largest negative impact
  changedAt: string;           // ISO-8601
}

process_discovered

Status: 📝 Planned
Publisher: PF (via auto-discovery cron)
Channel: domain_events
Consumers: PF-04 (Audit Logging)
interface ProcessDiscovered {
  processId: string;           // UUID of newly created/updated process
  organizationId: string;      // Tenant scoping
  processName: string;         // Discovered process name
  owningCore: string;          // Inferred owning core
  processType: string;         // Inferred process type
  linkedRuleCount: number;     // Number of linked automation rules
  linkedWorkflowCount: number; // Number of linked workflow definitions
  discoveredAt: string;        // ISO-8601
}

PF-83: SLA Management Events

pf_sla_warning_triggered

Status: 📝 Planned
Publisher: PF (via pf-sla-checker edge function)
Channel: domain_events
Consumers: PF-10 (Notifications)
interface PfSlaWarningTriggered {
  slaInstanceId: string;        // UUID
  slaDefinitionId: string;      // UUID
  organizationId: string;       // Tenant scoping
  targetEntityType: string;     // e.g., 'lead', 'admission'
  targetEntityId: string;       // UUID of tracked entity
  warningLevel: number;         // Threshold percentage crossed (e.g., 75, 90)
  percentageElapsed: number;    // Current % elapsed
  deadlineAt: string;           // ISO-8601
  triggeredAt: string;          // ISO-8601
}

pf_sla_breached

Status: 📝 Planned
Publisher: PF (via pf-sla-checker edge function)
Channel: domain_events
Consumers: PF-10 (Notifications), FW-03 (Workflow Automation, optional)
interface PfSlaBreached {
  slaInstanceId: string;        // UUID
  slaDefinitionId: string;      // UUID
  organizationId: string;       // Tenant scoping
  targetEntityType: string;
  targetEntityId: string;
  deadlineAt: string;           // ISO-8601 original deadline
  breachedAt: string;           // ISO-8601
  escalationLevel: number;      // Current escalation level
}

pf_sla_completed

Status: 📝 Planned
Publisher: PF (via event-driven instance resolution)
Channel: domain_events
Consumers: PF-04 (Audit Logging)
interface PfSlaCompleted {
  slaInstanceId: string;        // UUID
  slaDefinitionId: string;      // UUID
  organizationId: string;       // Tenant scoping
  targetEntityType: string;
  targetEntityId: string;
  startedAt: string;            // ISO-8601
  completedAt: string;          // ISO-8601
  deadlineAt: string;           // ISO-8601
  metSla: boolean;              // Whether completed before deadline
  elapsedSeconds: number;       // Total elapsed time
}

PF-91: Compliance Automation & Regulatory Dashboard

Spec / integration: PF-91 spec, PF-91 integration

pf_compliance_drift_detected

Status: 📝 Planned Publisher: PF (via compliance-run-checks Edge Function) Channel: domain_events Consumers: PF-10 (Notifications), PF-04 (Audit Logging)
interface PfComplianceDriftDetected {
  organization_id: string;
  compliance_check_id: string; // row id in pf_compliance_checks
  check_type: 'rls_coverage' | 'audit_completeness' | 'phi_access' | 'consent_status' | 'drift_detection';
  severity: 'warning' | 'fail';
  summary: string; // non-PHI description for operators
  dashboard_deep_link: string; // in-app path only; no tokens
  detected_at: string; // ISO-8601
}

pf_compliance_evidence_ready

Status: 📝 Planned Publisher: PF (via generate-compliance-evidence Edge Function) Channel: domain_events Consumers: PF-10 (Notifications, optional)
interface PfComplianceEvidenceReady {
  organization_id: string;
  evidence_id: string;
  framework: 'hipaa' | 'soc2' | 'joint_commission' | 'carf';
  storage_path: string; // opaque path; clients use signed URL flow
  completed_at: string; // ISO-8601
}

PF-96: Medicaid State Compliance Configuration

Spec / integration: PF-96 spec, PF-96 integration

pf_jurisdiction_profile_changed

Status: 📝 Planned Publisher: PF-96 (on org/site jurisdiction config change) Channel: domain_events Subscribers: CL-02, CL-04, CL-11, CL-40, PM-07, PM-08, PM-10, PM-18, PM-41, PF-91 Version: 1.0 Purpose: Notifies consumers when an organization or site changes its jurisdiction profile assignment, enabling cache invalidation and rule refresh across clinical and billing modules. Payload Schema:
interface PfJurisdictionProfileChanged {
  event: 'pf_jurisdiction_profile_changed';
  event_version: '1.0';
  payload: {
    event_id: string;              // UUID - unique event identifier for deduplication
    organization_id: string;      // UUID - tenant that changed profile
    site_id?: string;              // UUID - present if site-level change
    old_profile_code: string;      // e.g., "az-ahcccs" or "us-federal-baseline"
    new_profile_code: string;      // e.g., "ca-medi-cal"
    changed_by: string;            // UUID - user who made the change
  };
  metadata: {
    organization_id: string;
    site_id?: string;
    user_id: string;
    timestamp: string;             // ISO-8601
    correlation_id?: string;
  };
}
Deduplication: Use event_id for idempotency. Ordering: Consumers should process events by timestamp ascending within each (organization_id, site_id) partition. Consumer Actions:
  • CL-02, CL-04, CL-11, CL-40: Invalidate cached clinical rules; refetch useClinicalRules() for assessment/note/consent validation
  • PM-07, PM-08, PM-10, PM-18, PM-41: Invalidate cached billing rules; refetch useBillingRules() for charge capture/claims/scrub
  • PF-91: Refresh compliance dashboard to reflect new jurisdiction requirements
Error Handling: Consumers must handle profile resolution failures gracefully; fallback to federal baseline if new profile unavailable.

ce_screening_completed

Status: ✅ Implemented
Publisher: CE-28 (Intake Screening & Triage Workflow)
Channel: domain_events
Spec Reference: CE-28 Integration
Implementation: src/cores/ce/hooks/useCreateScreening.ts (client-side, consent-gated per 42 CFR Part 2)
Subscribers:
SubscriberAction
PM-38 (Intake Appointment Automation)Auto-create intake appointment when disposition = 'proceed'
PM-39 (Waitlist Management)Route to waitlist when disposition = 'waitlist' or proceed+no-bed
CE-29 (Lead Conversion Pipeline)Trigger lead-to-patient conversion
CL-40 (Clinical Intake Assessment)Pre-populate intake assessment from screening data
Payload:
interface CeScreeningCompletedPayload {
  event_id: uuid;
  source: 'ce-28';
  timestamp: string; // ISO 8601
  correlation_id: uuid; // screening attempt ID
  organization_id: uuid;
  data: {
    screening_id: uuid;
    lead_id: uuid;
    disposition: 'proceed' | 'waitlist' | 'refer_out' | 'decline';
    clinical_flag_codes: 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';
  };
}
Consent Gate (CRITICAL): This event is only published when consent_obtained = true on the screening attempt. No PHI is included in the payload — only IDs and clinical disposition metadata. This complies with 42 CFR Part 2 requirements for SUD data. Idempotency: correlation_id (screening attempt ID) — subscribers MUST deduplicate.

ce_lead_waitlisted

Status: ✅ Implemented
Publisher: CE-28 (conditional — emitted when disposition = 'proceed' but bed unavailable)
Channel: domain_events
Spec Reference: CE-28 Integration
Implementation: src/cores/ce/hooks/useCreateScreening.ts
Subscribers:
SubscriberAction
PM-39 (Waitlist Management)Add lead to waitlist queue with program type and priority
Payload:
interface CeLeadWaitlistedPayload {
  event_id: uuid;
  source: 'ce-28';
  timestamp: string; // ISO 8601
  correlation_id: uuid; // screening attempt ID
  organization_id: uuid;
  data: {
    lead_id: uuid;
    screening_id: uuid;
    program_type: 'residential' | 'iop' | 'php' | 'outpatient' | 'sober_living' | 'detox' | 'mat' | 'otp';
    reason: 'no_bed_available';
  };
}
Consent Gate: Only published when consent_obtained = true. Idempotency: correlation_id — subscribers MUST deduplicate.

ce_crisis_alert_created

Status: 📝 Planned — CE-28-ENHANCEMENTS EN-01 Publisher: CE-28-ENHANCEMENTS EN-01 (Crisis-Keyword AI Alerting) Channel: domain_events Spec Reference: CE-28-ENHANCEMENTS §EN-01; CONTEXT D-10 Subscribers:
SubscriberAction
PF-83 (SLA Platform)Start crisis SLA timer (Tier-1 = 60s page; Tier-2 = 5min queue)
PF-10 (Notifications)Page on-call user (Tier-1 only)
CE Crisis Queue UIRefresh queue / unacknowledged-alert widget
CE-29 (Conversion Pipeline)Mark conversion-pipeline aware of crisis hand-off
Payload:
interface CeCrisisAlertCreatedPayload {
  event_id: uuid;
  source: 'ce-28-en01';
  timestamp: string; // ISO 8601
  correlation_id: uuid; // ce_crisis_alerts.id
  organization_id: uuid;
  data: {
    alert_id: uuid;
    source_kind: 'sms' | 'web_form' | 'call_transcript' | 'keyword_manual';
    confidence_tier: 'tier_1' | 'tier_2';
    contact_id: uuid;
    screening_attempt_id: uuid | null;
  };
}
PHI Gate (CRITICAL): Payload contains IDs and tier metadata only — NO patient narrative, NO detected keywords, NO evidence excerpts. Subscribers needing alert detail MUST query the CE API with alert_id (RLS-enforced). Idempotency: correlation_id (alert ID) — subscribers MUST deduplicate.

CL-14-EN-01: Group Encounter Generation Events

cl_group_encounters_approved

Contract ID: EVT-CL-14-EN-01-001
Publisher: CL-14-EN-01
Subscribers: PM-07
Channel: cl_events
Version: 1.0
Purpose: Notify PM-07 that a reviewed set of generated group encounters has been approved and is ready for charge creation.
Trigger: Batch approval action in CL-14-EN-01 review UI (single or bulk approve).
Payload Schema:
interface ClGroupEncountersApproved {
  event: 'cl_group_encounters_approved';
  event_version: '1.0';
  payload: {
    event_id: string; // UUID
    session_id: string; // UUID
    organization_id: string; // UUID
    approved_generations: Array<{
      generation_id: string; // UUID
      encounter_id: string; // UUID
      patient_id: string; // UUID
      proposed_cpt_code: string;
      duration_minutes: number;
      modifiers: string[];
    }>;
  };
  metadata: {
    organization_id: string; // UUID
    user_id: string; // UUID
    timestamp: string; // ISO-8601
    correlation_id?: string; // UUID
  };
}
PHI: Payload contains identifiers only; no direct PHI content. Idempotency: event_id — PM-07 consumer must deduplicate and process at-most-once per event_id.

CL-40: Clinical Intake & SDOH Assessment Events \

cl_intake_finalized

Publisher: CL-40 (on intake assessment finalization) Subscribers: PM-07 (charge creation), CL-18 (SDOH referral follow-up) Version: 1.0 Payload Schema:
interface ClIntakeFinalized {
  event: 'cl_intake_finalized';
  event_version: '1.0';
  payload: {
    event_id: string;                // UUID
    intake_assessment_id: string;    // UUID
    patient_id: string;              // UUID
    chart_id: string;                // UUID
    clinician_id: string;            // UUID
    organization_id: string;         // UUID
    appointment_id?: string;         // UUID — if created from appointment
  };
  metadata: {
    organization_id: string;
    user_id: string;
    timestamp: string;               // ISO-8601
    correlation_id?: string;
  };
}
PHI: Payload contains IDs only — no PHI per 42 CFR Part 2 / HIPAA. Idempotency: event_id — subscribers MUST deduplicate.

cl_sdoh_referral_created

Publisher: CL-40 (on SDOH screening positive → auto-referral) Subscribers: CL-18 (social referral tracking) Version: 1.0 Payload Schema:
interface ClSdohReferralCreated {
  event: 'cl_sdoh_referral_created';
  event_version: '1.0';
  payload: {
    event_id: string;                // UUID
    referral_id: string;             // UUID — cl_social_referrals.id
    screening_id: string;            // UUID — cl_sdoh_screenings.id
    patient_id: string;              // UUID
    organization_id: string;         // UUID
  };
  metadata: {
    organization_id: string;
    user_id: string;
    timestamp: string;               // ISO-8601
    correlation_id?: string;
  };
}
PHI: Payload contains IDs only — no PHI. Idempotency: event_id — subscribers MUST deduplicate.

cl_peer_encounter_documented

Publisher: CL-40 (on peer encounter creation/signature) Subscribers: PM-07 (CPT charge creation) Version: 1.0 Payload Schema:
interface ClPeerEncounterDocumented {
  event: 'cl_peer_encounter_documented';
  event_version: '1.0';
  payload: {
    event_id: string;                // UUID
    peer_encounter_id: string;       // UUID
    patient_id: string;              // UUID
    peer_supporter_id: string;       // UUID
    encounter_id?: string;           // UUID — pm_encounters.id
    organization_id: string;         // UUID
  };
  metadata: {
    organization_id: string;
    user_id: string;
    timestamp: string;               // ISO-8601
    correlation_id?: string;
  };
}
PHI: Payload contains IDs only — no PHI. Idempotency: event_id — subscribers MUST deduplicate.

PF-98: AI Staff Headshot Generator

pf_headshot_job_completed

Publisher: PF-98 (Edge Function pf-headshot-webhook) Subscribers: PF-10 (user notification), PF-43 (quota decrement) Version: 1.0 Status: 📝 Planned Payload Schema:
interface PfHeadshotJobCompleted {
  event: 'pf_headshot_job_completed';
  event_version: '1.0';
  payload: {
    event_id: string;                // UUID
    job_id: string;                  // UUID — pf_headshot_jobs.id
    user_id: string;                 // UUID — staff member
    organization_id: string;         // UUID
    generated_count: number;         // Number of headshots generated
    provider: string;                // 'headshotpro' | 'replicate' | 'modelslab'
    actual_cost_cents: number;       // Cost in cents for quota tracking
  };
  metadata: {
    organization_id: string;
    user_id: string;
    timestamp: string;               // ISO-8601
    correlation_id?: string;
  };
}
PHI: Payload contains IDs only — no PHI or biometric data. Idempotency: event_id — subscribers MUST deduplicate.

pf_headshot_campaign_completed

Publisher: PF-98 (Edge Function pf-headshot-webhook or pf-headshot-status-poll) Subscribers: PF-10 (admin notification) Version: 1.0 Status: 📝 Planned Payload Schema:
interface PfHeadshotCampaignCompleted {
  event: 'pf_headshot_campaign_completed';
  event_version: '1.0';
  payload: {
    event_id: string;                // UUID
    campaign_id: string;             // UUID — pf_headshot_campaigns.id
    organization_id: string;         // UUID
    completed_count: number;         // Staff who completed generation
    total_count: number;             // Total staff invited
  };
  metadata: {
    organization_id: string;
    user_id: string;                 // Campaign admin who created it
    timestamp: string;               // ISO-8601
    correlation_id?: string;
  };
}
PHI: Payload contains IDs and counts only — no PHI or biometric data. Idempotency: event_id — subscribers MUST deduplicate.

cl_referral_status_updated

Publisher: CL-12-EN-67 (Bi-Directional Referral — status history insert trigger) Subscribers: PF-10 (notifications, audit logging) Channel: cl_events Version: 1.0 Status: 📝 Planned Trigger Conditions:
  • INSERT on cl_referral_status_history — fires after a new status entry is recorded for a referral.
Payload Schema:
interface ClReferralStatusUpdated {
  event: 'cl_referral_status_updated';
  event_version: '1.0';
  payload: {
    event_id: string;                // UUID — idempotency key
    organization_id: string;         // UUID
    referral_id: string;             // UUID — references pm_referrals.id (bare UUID)
    status: 'sent' | 'accepted' | 'declined' | 'patient_connected' | 'patient_did_not_connect' | 'closed';
    patient_connected: boolean | null;
    created_at: string;              // ISO-8601
  };
  metadata: {
    organization_id: string;
    user_id: string;                 // UUID — auth.uid() of the user who recorded the status
    timestamp: string;               // ISO-8601
    correlation_id?: string;
  };
}
PHI: Payload contains IDs and status only — no PHI, patient names, or narrative content. Idempotency: event_id — subscribers MUST deduplicate.

PF-100: Platform Ambient Transcription Events

Status: 📋 Planned Spec: PF-100 Integration: PF-100 Integration Channel: pf_transcription_events Common metadata: every payload includes { session_id: uuid, organization_id: uuid, timestamp: ISO-8601, correlation_id: uuid }. PHI-safe: payloads carry IDs only — never transcript text, names, or clinical narrative. All subscribers MUST deduplicate by event_id.

Published events

EventPublisherSubscribersPurpose / Payload (in addition to common metadata)
pf.transcription.session.createdPF-100CL-36 (encounter link), PM-08 (charge prep), PF-91 (evidence){ event_id, module_key, recording_purpose, source, subject_of_record_type, subject_of_record_id?, encounter_id?, jurisdiction_profile_id, is_part2_program }
pf.transcription.session.consent_verifiedPF-100CL-11 (audit), PF-91{ event_id, consent_record_type, consent_record_id, jurisdiction_profile_id, is_part2_program }
pf.transcription.session.consent_revokedPF-100All consumers (STOP downstream processing){ event_id, revoked_by, revoked_at, reason? }
pf.transcription.session.cancelledPF-100All consumers{ event_id, reason, cancelled_by }
pf.transcription.draft.readyPF-100CL-36, HR/GR/CE/RH UIs, PF-10 (notify reviewer){ event_id, draft_id, template_id, generation_latency_ms, requires_manual_drafting: boolean }
pf.transcription.draft.attestedPF-100Consumer core (writes domain record), PF-91, PF-04 (audit){ event_id, draft_id, reviewer_id, attested_at, attested_content_sha256, ai_vs_final_diff_pct, module_attest_payload?: object }
pf.transcription.audio.deletedPF-100PF-91, PF-04, subject-of-record portal{ event_id, deleted_at, retention_policy }
pf.transcription.deletion_requestedPF-100Operator alert, PF-91{ event_id, requested_by, requested_at, scope: 'audio' | 'transcript' | 'draft' | 'all' }
pf.transcription.deletion_completedPF-100PF-91, subject portal{ event_id, completed_at, scope }
pf.transcription.policy.violationPF-100PF-91 (evidence), PF-10 (notify admin){ event_id, violation_type, blocked_at, policy_key }

Consumed events

EventPublisherPF-100 reaction
pf.consent.cl_consent.revokedCL-11Triggers session-revocation cascade for any active CL session referencing the consent (publishes pf.transcription.session.consent_revoked for each affected session).
pf.encounter.createdPMOptional auto-link of a clinical session in pre_record state to the new encounter.
pf.encounter.cancelledPMCancels any in-progress capture for that encounter (publishes pf.transcription.session.cancelled with reason='encounter_cancelled').
PHI / privacy: No event payload may contain transcript text, draft content, patient/employee/resident names, or any free-text clinical narrative. Numeric metrics (latency, diff %, counts) and IDs only. Subscribers needing content MUST query the appropriate pf_transcription_* table directly (subject to RLS). Idempotency: All events carry event_id (UUID). Subscribers MUST deduplicate. Per-event triggers are SECURITY DEFINER and emit at-least-once.

Planned Events (PM-64 AI Coding Assistant)

Spec: PM-64 AI Coding Assistant — 📋 Specification Pattern: Event + Platform Integration Layer. PM-64 consumes a CL-04 event to trigger redaction → RAG → LLM → suggestion, then publishes its own events when suggestions are created and when coders accept / edit / reject. NO PHI in any payload (constitution §4.3, GR-06-EN-01).

CL-04: Note Finalized (consumed by PM-64)

Event: cl_note_finalized Publisher: CL (Clinical) — CL-04 Subscribers: PM-64 (AI coding suggestion trigger), PM-07 (charge capture eligibility), PF-10 (notifications) Status: 📋 Planned (PM-64 will be the first formal consumer) Channel: cl_clinical_events PHI: Payload carries IDs only — never note text. PM-64 reads the note via @/platform/clinical and runs PHI redaction (fail-closed) before any LLM call.
{
  event_type: 'cl_note_finalized';
  organization_id: uuid;
  payload: {
    encounter_id: uuid;            // pm_encounters.id
    note_id: uuid;                 // cl_clinical_notes.id
    finalized_at: string;          // ISO timestamp
    finalized_by: uuid;            // pf_profiles.id
    note_type: string;             // e.g. 'progress_note', 'assessment'
    sud_flag: boolean;             // true → consumers must respect 42 CFR Part 2
  };
}

PM-64: AI Coding Suggestion Created

Event: pm.ai_coding_suggestion_created Publisher: PM (PM-64 pm-ai-coding-suggest edge function) Subscribers: PM (Coder UI sidecar — CodingSuggestionSidecar), GR (compliance audit), PM-50-EN-01 (fairness drift monitor) Status: 📋 Planned (PM-64) Channel: pm_events PHI: None. IDs and model metadata only.
{
  event_type: 'pm.ai_coding_suggestion_created';
  organization_id: uuid;
  payload: {
    suggestion_id: uuid;           // pm_ai_coding_suggestions.id
    encounter_id: uuid;
    note_id: uuid;
    suggested_at: string;          // ISO timestamp
    vendor: string;                // e.g. 'anthropic-bedrock'
    model_version: string;
    confidence_score: number;      // 0..1
    suggestion_counts: {
      icd10: number;
      cpt: number;
      hcpcs: number;
      modifiers: number;
      em_level_present: boolean;
    };
  };
}

PM-64: AI Coding Decision Recorded

Event: pm.ai_coding_decision_recorded Publisher: PM (PM-64 pm-ai-coding-record-decision edge function) Subscribers: PM-07 (charge capture — only on accepted / edited), PM-50 (denial-risk model retraining feed), GR (compliance audit queue), PM-50-EN-01 (fairness drift monitor) Status: 📋 Planned (PM-64) Channel: pm_events PHI: None. Decision metadata + IDs only; rejection_reason is structured (enum) — no free-text narrative.
{
  event_type: 'pm.ai_coding_decision_recorded';
  organization_id: uuid;
  payload: {
    audit_id: uuid;                // pm_ai_coding_suggestion_audits.id
    suggestion_id: uuid;
    encounter_id: uuid;
    coder_id: uuid;                // pf_profiles.id
    decided_at: string;            // ISO timestamp
    decision: 'accepted' | 'edited' | 'rejected' | 'partial';
    rejection_reason_code?: string; // structured enum, no free text
    edit_summary?: {                // counts only; full diff is in audit row
      codes_added: number;
      codes_removed: number;
      codes_modified: number;
    };
  };
}
Naming exception: PM-64 events use the dotted pm.ai_coding_* form to align with the existing PM-51 RPA naming exception and to namespace the AI coding subsystem cleanly. New non-AI PM events should still follow the pm_{entity}_{action} underscore convention.

CL-43: Concurrent Review & Utilization Management Events

Status: 📋 Planned (CL-43). Payloads are PHI-free — IDs and structured metadata only (no clinical narrative, no patient demographics). Channel: cl_clinical_events Integration doc: CL-43-concurrent-review-utilization-management-INTEGRATION.md

CL-43: Review Overdue

Event: cl_review_overdue Publisher: CL (CL-43 — cl-review-overdue-scan cron / trigger on cl_concurrent_reviews) Subscribers: PF-10 (notifications — UM coordinator + supervisor escalation), CL-08 (CDS alert surface) Status: 📋 Planned (CL-43) Channel: cl_clinical_events PHI: None. IDs only — consumers must read the review record via @/platform/clinical if narrative context is needed.
{
  event_type: 'cl_review_overdue';
  organization_id: uuid;
  payload: {
    review_id: uuid;             // cl_concurrent_reviews.id
    authorization_id: uuid;      // pm_prior_authorizations.id (UUID-only cross-core ref)
    chart_id: uuid;              // cl_patient_charts.id
    reviewer_id: uuid | null;    // pf_profiles.id (assigned UM coordinator, may be null)
    review_due_date: string;     // ISO date — original deadline
    overdue_days: number;        // integer days past review_due_date
    review_type: 'concurrent' | 'continued_stay' | 'level_of_care_change';
    level_of_care: 'residential' | 'php' | 'iop' | 'outpatient';
    escalation_tier: 'soft' | 'supervisor' | 'director'; // derived from grace + escalation thresholds
    detected_at: string;         // ISO timestamp
  };
}
Idempotency: Consumers MUST dedupe on (review_id, escalation_tier) — the scan re-emits at most once per tier per review.

CL-43: Review Determination Recorded

Event: cl_review_determination_recorded Publisher: CL (CL-43 — useRecordDetermination mutation, post-commit trigger on cl_concurrent_reviews) Subscribers: PM-11 (revenue cycle analytics — auth utilization + denial impact) Status: 📋 Planned (CL-43) Channel: cl_clinical_events PHI: None. Determination metadata + IDs + payer reference only. denial_reason_code is a structured payer reason code (no free-text narrative).
{
  event_type: 'cl_review_determination_recorded';
  organization_id: uuid;
  payload: {
    review_id: uuid;                 // cl_concurrent_reviews.id
    authorization_id: uuid;          // pm_prior_authorizations.id (cross-core UUID ref)
    chart_id: uuid;                  // cl_patient_charts.id
    determination: 'approved' | 'modified' | 'denied' | 'pending';
    approved_days: number | null;    // days approved by payer (null if denied)
    approved_through_date: string | null; // ISO date
    payer_reference: string | null;  // payer-issued tracking number
    denial_reason_code: string | null; // structured enum/code, no free text
    review_type: 'concurrent' | 'continued_stay' | 'level_of_care_change';
    level_of_care: 'residential' | 'php' | 'iop' | 'outpatient';
    recorded_by: uuid;               // pf_profiles.id
    recorded_at: string;             // ISO timestamp
  };
}
Idempotency: Consumers MUST dedupe on review_id — re-emission only occurs if a prior determination is overturned via appeal (CL-43 publishes a new event with updated determination).

PM-55: ONC HTI-1 / USCDI v3 Patient Access API Events

Status: 📋 Planned (PM-55). Payloads are PHI-free — IDs only. Full schemas to be finalized when PM-55 Phase 1 implements the publishers. Naming exception: PM-55 uses the dotted pm.fhir_* form to namespace the FHIR/SMART subsystem (consistent with PM-51 RPA and PM-64 AI Coding exceptions).

pm.fhir_app_authorized

Publisher: PM (PM-55 useGrantAppConsent mutation / pm-fhir-token edge function) Subscribers: PF-04 (audit), GR (compliance metrics) Channel: pm_events PHI: None — IDs only.
{
  event_type: 'pm.fhir_app_authorized';
  organization_id: uuid;
  payload: {
    consent_id: uuid;             // pm_patient_access_consents.id
    patient_id: uuid;
    app_registration_id: uuid;
    scopes_granted: string[];     // SMART scope strings, no PHI
    granted_at: string;           // ISO timestamp
    has_part2_scope: boolean;     // signals SUD-related access
  };
}

pm.fhir_app_revoked

Publisher: PM (PM-55 useRevokeAppAccess) Subscribers: PF-04 (audit), GR Channel: pm_events PHI: None.
{
  event_type: 'pm.fhir_app_revoked';
  organization_id: uuid;
  payload: {
    consent_id: uuid;
    patient_id: uuid;
    app_registration_id: uuid;
    revoked_at: string;
    revoked_reason_code?: 'patient_initiated' | 'admin_revoked' | 'part2_consent_lost' | 'app_suspended';
  };
}

pm.fhir_information_blocking_logged

Publisher: PM (PM-55 pm-fhir-router) Subscribers: GR-08 (incident reporting — escalates when disposition = info_blocking) Channel: pm_events PHI: None — denial_narrative is NOT included in event payload (stored only on pm_information_blocking_log row, retrieved server-side).
{
  event_type: 'pm.fhir_information_blocking_logged';
  organization_id: uuid;
  payload: {
    log_id: uuid;                 // pm_information_blocking_log.id
    occurred_at: string;
    patient_id?: uuid;
    app_registration_id?: uuid;
    denial_category:
      | 'preventing_harm' | 'privacy' | 'security' | 'infeasibility'
      | 'health_it_performance' | 'content_manner' | 'fees' | 'licensing';
  };
}

pm.fhir_access_logged

Publisher: PM (PM-55 pm-fhir-router — emitted on every FHIR request, success or denial) Subscribers: PF-04 (HIPAA audit stream) Channel: pm_events PHI: None — IDs + status only; no request body, no resource contents. Volume note: High-cardinality. Subscribers should batch.
{
  event_type: 'pm.fhir_access_logged';
  organization_id: uuid;
  payload: {
    access_log_id: uuid;          // pm_fhir_access_log.id
    patient_id?: uuid;
    app_registration_id?: uuid;
    request_method: 'GET' | 'POST' | 'DELETE';
    resource_type?: string;       // FHIR resource type, no PHI
    status_code: number;
    denied_reason_code?: string;
    occurred_at: string;
  };
}
Consumed events from CL-11: cl.part2_consent_granted and cl.part2_consent_revoked are required by PM-55. TBD by CL-11 owner — tracked in PENDING_CONTRACTS.md until CL-11 publishes them. If CL-11 cannot publish, PM-55 will fall back to polling cl_consents.updated_at per a separate decision log entry.

CL-42: Clinical Pathways & Protocol-Driven Care

Owning core: CL · Channel: cl_events · Spec: specs/cl/specs/CL-42-clinical-pathways-protocol-driven-care.md CL-42 publishes 3 canonical snake_case events. Payloads carry IDs only — no PHI/PII. Consumers join to their own data using the IDs.

cl_pathway_milestone_completed

Publisher: CL (useMilestoneMutations.useCompleteMilestone) Consumers: CL-10 (outcomes trigger), CL-08 (CDS rule re-evaluation), CL-23 (in-basket task closure)
interface CLPathwayMilestoneCompletedPayload {
  organization_id: string;
  patient_pathway_id: string;
  milestone_id: string;
  milestone_template_id: string;       // template milestone uuid (JSONB)
  template_id: string;
  patient_id: string;                  // pm_patients.id
  completed_by: string;                // pf_profiles.id
  actual_completion_date: string;      // ISO timestamptz
  occurred_at: string;
}
Idempotency: keyed on (milestone_id) — milestone status transitions to completed exactly once. Retry: at-least-once delivery; consumers must dedupe on milestone_id.

cl_pathway_variance_created

Publisher: CL (useDocumentVariance) Consumers: CL-08 (CDS rule trigger), GR (variance reporting), CL-15 (quality measures)
interface CLPathwayVarianceCreatedPayload {
  organization_id: string;
  variance_id: string;
  patient_pathway_id: string;
  milestone_id: string;
  template_id: string;
  patient_id: string;                  // pm_patients.id
  reason_code: string;                 // from cl_pathway_variance_reasons picklist
  documented_by: string;               // pf_profiles.id
  documented_at: string;               // ISO timestamptz
  occurred_at: string;
}
Idempotency: keyed on (variance_id). PHI: rationale field is NEVER included in the event payload — only the reason_code reference.

cl_pathway_milestone_overdue

Publisher: CL edge function cl-pathway-overdue-check (hourly pg_cron) Consumers: CL-08 (CDS alert generation), CL-23 (in-basket task creation), GR (compliance tracking)
interface CLPathwayMilestoneOverduePayload {
  organization_id: string;
  patient_pathway_id: string;
  milestone_id: string;
  template_id: string;
  patient_id: string;                  // pm_patients.id
  expected_completion_date: string;    // ISO timestamptz
  hours_overdue: number;
  occurred_at: string;
}
Idempotency: keyed on (milestone_id) — published once per milestone status transition pending|in_progressoverdue. The cron updates status to overdue in the same transaction; subsequent runs skip already-overdue milestones. Batching: processed in batches of 100 milestones per invocation.

CL-56: Centralized Clinical Notification & Critical Result Alerting Events

cl_notification_dispatched

Publisher: CL edge function cl-clinical-notify Consumers: CL-25 (audit dashboard SLA metrics)
interface CLNotificationDispatchedPayload {
  organization_id: string;
  event_id: string;                    // cl_notification_events.id
  signal_type: string;                 // e.g. 'lab_critical', 'metabolic_overdue'
  signal_source: string;               // originating spec (e.g. 'CL-09')
  severity: 'informational' | 'urgent' | 'critical';
  chart_id: string | null;
  recipient_user_id: string | null;    // pf_profiles.id
  recipient_role_key: string | null;
  escalation_step: number;
  sla_deadline: string;                // ISO timestamptz
  dispatched_at: string;               // ISO timestamptz
  occurred_at: string;
}
PHI: No PHI. IDs and severity only — patient name, diagnosis, lab values, and narrative are explicitly prohibited (DB CHECK constraint chk_cl_notification_no_phi on cl_notification_events.payload). Idempotency: keyed on (event_id). Dedup is enforced upstream by cl-clinical-notify (key: signal_type + chart_id + severity [+ source_record_id] within dedup_window_seconds); only the surviving (non-deduped) event publishes this event.

cl_notification_sla_breached

Publisher: CL cron edge function cl-notification-sla-evaluator (every 60s) Consumers: GR-09 (incident reporting — auto-creates safety incident for unacknowledged criticals), CL-25 (audit dashboard)
interface CLNotificationSlaBreachedPayload {
  organization_id: string;
  event_id: string;                    // original cl_notification_events.id (breached)
  next_event_id: string | null;        // new escalation event id, or null if chain exhausted
  signal_type: string;
  severity: 'informational' | 'urgent' | 'critical';
  chart_id: string | null;
  escalation_step: number;             // step that breached
  next_escalation_step: number | null; // step the alert was escalated to, if any
  sla_deadline: string;                // ISO timestamptz of breached deadline
  breached_at: string;                 // ISO timestamptz (now())
  chain_exhausted: boolean;
  occurred_at: string;
}
PHI: No PHI — IDs and severity only. Idempotency: keyed on (event_id). The evaluator sets sla_breached_at in the same transaction it publishes; subsequent runs skip events with non-null sla_breached_at.

CL-68 / PM-74 / GR-27: BHRF Clinical Residential Episode Lifecycle Events

Full contract: CL-GR-PM-BHRF-EPISODE-LIFECYCLE.md. BHRF = A.A.C. R9-10-701–722 (adult), a licensed clinical residential level of care — distinct from RH recovery housing. CL is downstream: GR-27/PM-74 consume CL-68 events but do not depend on CL. No cross-core imports or FKs; residence_ref/chart_ref are id values from payloads. SUD-identifying context gated by CL-11 (42 CFR Part 2) before emission. Idempotency & retry standard (applies to all BHRF events below): every payload carries a unique event_id (UUID) which is the canonical cross-system dedupe key. Consumers MUST record processed event_ids and treat duplicates as success (idempotent). The per-event domain tuple listed under Idempotency is a secondary guard for replay/race safety. Delivery is at-least-once: on transient consumer errors (5xx, timeout) retry with exponential backoff per the canonical R7 policy (1s, 2s, 4s; max 3 retries; do not retry 4xx except 429); fatal errors (schema/validation, consent-denied) are not retried and are dead-lettered for review. Canonical RH event / alias: rh_psychiatric_residential_admission is a logical alias for the canonical RH-01.1 rh_resident_admitted event filtered to facility_type = 'psychiatric_residential' (and likewise rh_resident_discharged). No new RH event is introduced — RH-01.1 canonical names remain authoritative; consumers subscribe to the canonical events and filter by facility_type.

rh_resident_admitted (BHRF-filtered view: facility_type='psychiatric_residential')

Channel: rh_events Publisher: RH (RH-01.1 — canonical rh_resident_admitted) Consumers: CL-68 (open clinical episode), PM-74 (per-diem + 5-day exemption), GR-27 (licensure/staffing applicability) Status: 📝 Planned
interface RhPsychiatricResidentialAdmissionPayload {
  event_id: string;              // UUID — canonical dedupe key (required)
  event_type: 'rh_resident_admitted'; // canonical RH-01.1 event; BHRF consumers filter facility_type
  organization_id: string;
  timestamp: string;             // ISO timestamptz
  residence_id: string;          // rh_residences.id value (no cross-core FK)
  chart_id: string;
  site_id?: string;
  admitted_at: string;
  facility_type: 'psychiatric_residential';
  urgency?: 'urgent' | 'routine';
  correlation_id?: string;
}
PHI: IDs only; no clinical narrative. Idempotency: canonical key event_id; secondary domain guard (organization_id, chart_id, residence_id, admitted_at).

cl_bhrf_loc_determined

Channel: cl_events (single canonical channel) Cross-core handoff: PM-74/GR-27 subscribe to cl_events for this contract; do not dual-publish to alternate channels. Publisher: CL (CL-68) Consumers: PM-74 (authorization context), GR-27 (compliance counters) Status: 📝 Planned
interface ClBhrfLocDeterminedPayload {
  event_id: string;              // UUID — canonical dedupe key (required)
  event_type: 'cl_bhrf_loc_determined';
  organization_id: string;
  timestamp: string;
  episode_id: string;
  chart_id: string;
  site_id?: string;
  loc_value: string | null;      // coded level (e.g. 'ASAM 3.5'); null (redacted, not omitted) when CL-11 SUD consent absent/revoked
  determined_at: string;
  correlation_id?: string;
}
PHI: Coded LOC only; SUD-implying LOC gated by CL-11 before emission. Idempotency: canonical key event_id; secondary domain guard (organization_id, episode_id, determined_at).

cl_bhrf_clinical_assessment_completed

Channel: cl_events Publisher: CL (CL-68) Consumers: GR-27 (15-day timeliness compliance), PM-74 (optional) Status: 📝 Planned
interface ClBhrfClinicalAssessmentCompletedPayload {
  event_id: string;              // UUID — canonical dedupe key (required)
  event_type: 'cl_bhrf_clinical_assessment_completed';
  organization_id: string;
  timestamp: string;
  episode_id: string;
  chart_id: string;
  site_id?: string;
  completed_at: string;
  correlation_id?: string;
}
PHI: IDs/timestamps only. Idempotency: canonical key event_id; secondary domain guard (organization_id, episode_id, completed_at).

pm_bhrf_continued_stay_review_required

Channel: cl_pm_events Publisher: PM (PM-74) Consumers: CL-43 (Concurrent Review / UM) — PM-74 publishes; it does not import CL-43. Status: 📝 Planned
interface PmBhrfContinuedStayReviewRequiredPayload {
  event_id: string;              // UUID — canonical dedupe key (required)
  event_type: 'pm_bhrf_continued_stay_review_required';
  organization_id: string;
  timestamp: string;
  chart_ref: string;
  residence_ref: string;
  authorization_id: string;
  remaining_days: number;
  expires_on?: string;           // ISO date
  correlation_id?: string;
}
PHI: No clinical/SUD context on the authorization handoff. Idempotency: canonical key event_id; secondary domain guard (organization_id, authorization_id, expires_on) — use a stable time boundary (expires_on, or timestamp if expires_on is null). Do not dedupe on remaining_days (mutable across valid successive reviews — would suppress legitimate continued-stay events).

gr_bhrf_compliance_finding_raised

Channel: gr_events Publisher: GR (GR-27) Consumers: PF notifications/dashboards Status: 📝 Planned
interface GrBhrfComplianceFindingRaisedPayload {
  event_id: string;              // UUID — canonical dedupe key (required)
  event_type: 'gr_bhrf_compliance_finding_raised';
  organization_id: string;
  timestamp: string;
  residence_ref: string;
  finding_type: 'missing_license' | 'staffing_gap' | 'incident_timeframe' | 'retention_gap';
  due_at?: string;
  correlation_id?: string;
}
PHI: None — facility/regulatory metadata only. Idempotency: canonical key event_id; secondary domain guard (organization_id, residence_ref, finding_type, COALESCE(due_at, timestamp))due_at is optional, so fall back to the event timestamp to avoid falsely deduping distinct findings that both have due_at = null.

pm_residential_charge_held

Channel: pm_events Publisher: PM (PM-74) Consumers: PF dashboards / notifications (operational held-charge worklist) Status: 📝 Planned
interface PmResidentialChargeHeldPayload {
  event_id: string;              // UUID — canonical dedupe key
  event_type: 'pm_residential_charge_held';
  organization_id: string;
  timestamp: string;             // ISO timestamptz
  service_date: string;          // ISO date of the held per-diem day
  residence_ref: string;
  chart_ref: string;
  hold_reason:                   // coded values only — never free text (no PHI/operational narrative)
    | 'bhrf_continued_stay_auth_required'
    | 'authorization_expired'
    | 'authorization_missing'
    | 'payer_response_pending';
  correlation_id?: string;
}
PHI: None — billing/operational ids and a coded hold reason only; no clinical/SUD context. Idempotency: canonical key event_id; secondary domain guard (organization_id, residence_ref, chart_ref, service_date, hold_reason) (one hold per per-diem day per reason). At-least-once delivery; retry per the canonical R7 policy as stated in the BHRF idempotency & retry standard above.

CE-24: Partner Contract Renewal Notification

Type: PF-10 notification (not a domain event). Notification type key: contract_renewal_reminder Owner: CE-24 (Partner Document & Contract Management) Producer: ce-contract-renewal-check edge function (daily cron, 08:00 UTC) Consumer: PF-10 (pf_notifications) — delivered to in-app inbox per user notification preferences. Payload (PF-10 notification metadata):
{
  type: 'contract_renewal_reminder';
  title: string;            // e.g. "Contract Renewal Reminder: [Contract Name]"
                            // Auto-renew contracts prefix with "[Auto-Renew] "
  message: string;          // "[Partner Name] — [Contract Name] expires in [N] days ([End Date])."
  data: {
    contract_id: string;    // ce_partner_contracts.id
    partner_id: string;     // ce_partners.id
    window_days: 30 | 60 | 90;
    end_date: string;       // ISO date
    auto_renew: boolean;
  };
}
Recipients:
  • Contract created_by user
  • All org users holding permission ce.contracts.manage (resolved via ce_users_with_permission(p_org_id, 'ce.contracts.manage') SECURITY DEFINER helper)
Idempotency: Deduplicated per (contract_id, notification_window) via ce_contract_renewal_log rows with action = 'notification_sent'. Each successful send writes a log row before exiting the per-contract handler. PHI: No PHI — partner and contract metadata only.