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

# Bed Board & Census — Integration

> Version: 1.1 Last Updated: 2026-03-20 Spec: RH-01 Census, Beds & Episodes · RH-01.1 Bed Board & Facility Types Constitution Reference: Section 1.2 (Core Indepe…

**Version:** 1.1
**Last Updated:** 2026-03-20
**Spec:** [RH-01 Census, Beds & Episodes](../../../specs/rh/specs/RH-01-census-beds-episodes.md) · [RH-01.1 Bed Board & Facility Types](../../../specs/rh/specs/RH-01.1-bed-board-facility-types.md)
**Constitution Reference:** Section 1.2 (Core Independence), Section 1.3 (Integration Patterns)

***

## Overview

The RH Bed Board and census system provides real-time occupancy data for all facility types:

| `facility_type`           | Setting                                  | POS |
| ------------------------- | ---------------------------------------- | --- |
| `recovery_housing`        | NARR Level 2/3 recovery housing          | 55  |
| `psychiatric_residential` | Behavioral health residential (RTC/BHRF) | 56  |
| `inpatient_unit`          | Inpatient psychiatric                    | 51  |

The bed board UI (`/rh/bed-board`) is owned by RH. Other cores consume census and admission/discharge data via the Platform Integration Layer and domain events — no direct core-to-core imports.

***

## Quick Reference

| I need to…                                 | Pattern                                                                                                                    | Location                                                                                           |
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| View the real-time bed board               | Navigate to `/rh/bed-board` UI                                                                                             | `src/cores/rh/pages/BedBoardPage.tsx`                                                              |
| Fetch census data in another core          | Platform Census Layer (`useCensusData`)                                                                                    | `src/platform/census`                                                                              |
| React to admission/discharge in FA or PM   | Read `rh_resident_admitted` / `rh_resident_discharged` from `fw_domain_events` (canonical; legacy `resident_*` deprecated) | [EVENT\_CONTRACTS.md](./EVENT_CONTRACTS.md#rh-lifecycle-events-canonical-names--persistence-fw-16) |
| Read current residence for a patient in CL | GET `/api/v1/rh/current-residence?patient_id=` via Platform Integration Layer                                              | `API_CONTRACTS.md` — RH-01                                                                         |
| Derive POS from facility type in PM        | Map `facility_type` from event payload using PM-07 rules                                                                   | `Facility Type → POS Mapping` section below                                                        |

***

## Decision Tree

* **Fetch census data (HR workload, PM census reporting)?**
  → Use `useCensusData` from `src/platform/census` (Platform Integration Layer, Pattern 1).
  → Filter by `facilityType` if needed; do NOT query `rh_residences` or `rh_beds` directly from outside RH.

* **React to admission or discharge (FA billing, PM charge capture)?**
  → Consume `rh_resident_admitted` / `rh_resident_discharged` from `fw_domain_events` (FW-16 / automation-compatible).
  → Check `facility_type` in event payload → map to POS (55/56/51) for PM-07.
  → Do NOT call RH hooks or import from `@/cores/rh/...`.

* **Show current residence/bed on patient chart (CL)?**
  → Call Platform Integration Layer API: `GET /api/v1/rh/current-residence?patient_id=`.
  → Returns `null` if patient is not currently admitted.

* **Assign or release a bed (within RH)?**
  → Use `useBedBoard` hook inside RH only.
  → After mutation, emit `rh_bed_assigned` / `rh_bed_released` (📋 when registered) to `fw_domain_events` so HR can update census.

* **Handle inpatient\_unit grouping?**
  → Check `facility_type === 'inpatient_unit'` → use `unit_label` for bed grouping on the board.
  → For `recovery_housing` and `psychiatric_residential`, use `room_number` instead.

***

## Pattern Library

| Pattern                                             | Usage                                                                                                                                                                                                                                                                                                                                                                                                                                                       | Constraints                                                                              | Example                                 |
| --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | --------------------------------------- |
| **Real-time census via Platform Integration Layer** | HR/PM read census counts by `facility_type` without querying RH tables directly                                                                                                                                                                                                                                                                                                                                                                             | Do not import `@/cores/rh/...`; use `src/platform/census` only                           | `Example: Census Query` below           |
| **Event-driven admission/discharge (Pattern 2)**    | FA creates billing account; PM derives POS; HR updates staffing census                                                                                                                                                                                                                                                                                                                                                                                      | Subscribers must be idempotent; `episode_id` is the deduplication key                    | `Example: Event Payload` sections below |
| **Platform API for cross-core read (Pattern 3)**    | CL reads current residence/bed on patient chart                                                                                                                                                                                                                                                                                                                                                                                                             | Read-only; no direct DB join; returns null if not admitted                               | `GET /api/v1/rh/current-residence`      |
| **Facility type → POS mapping**                     | PM-07 uses `facility_type` from event payload to derive Place of Service code                                                                                                                                                                                                                                                                                                                                                                               | Mapping is static: recovery\_housing→55, psychiatric\_residential→56, inpatient\_unit→51 | `Facility Type → POS Mapping` section   |
| **Bed board auto-refresh**                          | `useBedBoard` polls every 30 s via `refetchInterval: 30_000` for near-real-time accuracy. 30 s was chosen as a tradeoff between data freshness and resource usage based on expected occupancy and bed-assignment change frequency (typical update cadence and acceptable staleness for the board). `staleTime: 5 min` and `gcTime: 10 min` still apply; `refetchInterval` runs in the background so the board stays reasonably fresh without over-querying. | `staleTime: 5 min`, `gcTime: 10 min`; manual Refresh button available                    | `src/cores/rh/hooks/useBedBoard.ts`     |

***

## Common Mistakes

| Mistake                                                      | Impact                                                             | Mitigation                                                                                             |
| ------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ |
| Importing from `@/cores/rh/...` in another core              | Couples cores; breaks Core Independence (constitution Section 1.2) | Use Platform Census Layer, `rh_events`, or Platform API instead                                        |
| Reading `rh_residences.facility_type` directly from FA/PM/HR | Schema changes in RH silently break consumers; bypasses RLS        | Consume `facility_type` from event payload or Platform Census Layer only                               |
| Using stale census data without `refetchInterval`            | Bed count shown to HR/PM may lag after admissions/discharges       | Set `refetchInterval: 30_000` in any census-consuming hook; rely on `rh_events` for immediate triggers |
| Mis-mapping `facility_type` to POS                           | Wrong POS on claims → denials or incorrect reimbursement           | Always use the canonical mapping table in this doc; do not hard-code POS without checking              |
| Omitting `organization_id` filter on bed queries             | Multi-tenant data leakage; cross-org bed records may be returned   | Always `.eq('organization_id', currentOrganization.id)` as defense-in-depth alongside RLS              |

***

## Pre-Flight Checklist

Before releasing any change to the RH bed board or census integration:

* [ ] **End-to-end test:** Admit a resident → verify `rh_resident_admitted` row in `fw_domain_events` with `facility_type` and actor UUIDs (no PHI).
* [ ] **Event emission:** Confirm `rh_bed_assigned` / `rh_bed_released` (when implemented) after bed assignment mutations; HR census updates correctly.
* [ ] **Schema compatibility:** Run `supabase db diff` to confirm migration is applied; regenerate `types.ts` via `bash scripts/utils/generate-types.sh` and verify no `as never` / `as unknown as` casts remain in RH hooks.
* [ ] **RBAC:** Verify `rh.beds.view` permission is required to access `/rh/bed-board`; confirm `PermissionGate` renders access-denied for unpermitted users.
* [ ] **POS mapping:** Spot-check PM-07 charge capture for one episode per `facility_type`; confirm POS codes 55, 56, 51 are derived correctly.

***

## Integration Points

| Dependency | Pattern                                                 | Purpose                                                                                        |
| ---------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| **FA**     | Event (Pattern 2)                                       | Resident admission/discharge events trigger billing account creation and finalization          |
| **PM**     | Event / Census Data (Pattern 2 / Platform Layer)        | `facility_type` in events allows PM to derive POS (51/55/56) for charge capture and prior auth |
| **HR**     | Platform Census Layer (Pattern 1)                       | Census count (by facility\_type) drives HR workload and staffing calculations                  |
| **CL**     | Platform Integration Layer / API (Pattern 3 — optional) | Optional: current residence/bed read-only on patient chart                                     |
| **PF-10**  | Platform Layer (Pattern 1)                              | Notifications for bed availability, admission alerts, license expiry                           |
| **PF-11**  | Platform Layer (Pattern 1)                              | Resident agreement document storage                                                            |

***

## Event Contracts

### Event: `rh_resident_admitted`

**Publisher:** RH (RH-01)\
**Subscribers:** FA (billing account creation), PM (POS context)\
**Persistence:** `fw_domain_events` (`event_source` = `trigger_rh_episodes_domain_events`)\
**Status:** 🟡 Persistence implemented; FA/PM batch consumers 📋 Planned

**Deprecated alias:** `resident_admitted`

**Example: Event Payload**

```typescript theme={null}
{
  event_name: 'rh_resident_admitted';
  event_timestamp: string;       // ISO 8601
  organization_id: string;       // UUID
  episode_id: string;            // UUID
  resident_profile_id: string;   // UUID
  residence_id: string;          // UUID
  bed_id: string;                // UUID
  admission_date: string;        // ISO date
  facility_type: 'recovery_housing' | 'psychiatric_residential' | 'inpatient_unit';
  // PM uses facility_type to derive POS: recovery_housing→55, psychiatric_residential→56, inpatient_unit→51
  agreement_id?: string;         // UUID — if agreement already created at admission
}
```

### Event: `rh_resident_discharged`

**Publisher:** RH (RH-01)\
**Subscribers:** FA (billing finalization)\
**Persistence:** `fw_domain_events` (`trigger_rh_episodes_domain_events`)\
**Status:** 🟡 Persistence implemented; FA consumer 📋 Planned

**Deprecated alias:** `resident_discharged`

**Example: Event Payload**

```typescript theme={null}
{
  event_name: 'rh_resident_discharged';
  event_timestamp: string;
  organization_id: string;
  episode_id: string;
  resident_profile_id: string;
  residence_id: string;
  discharge_date: string;
  discharge_reason: string;
  discharge_type: 'planned' | 'ama' | 'non_compliance' | 'completion' | 'extension';
  facility_type: 'recovery_housing' | 'psychiatric_residential' | 'inpatient_unit';
  exit_destination?: string;
}
```

### Event: `rh_bed_assigned` (planned)

**Publisher:** RH (RH-01)\
**Subscribers:** HR (workload/census update)\
**Persistence:** 📋 Planned (`fw_domain_events`)\
**Status:** 📝 Planned (RH-01.1 Implementation)

**Deprecated alias:** `bed_assigned`

**Example: Event Payload**

```typescript theme={null}
{
  event_name: 'rh_bed_assigned';
  event_timestamp: string;
  organization_id: string;
  episode_id: string;
  bed_id: string;
  residence_id: string;
  facility_type: 'recovery_housing' | 'psychiatric_residential' | 'inpatient_unit';
  unit_label?: string;   // Non-null for inpatient_unit
  assigned_at: string;
}
```

### Event: `rh_bed_released` (planned)

**Publisher:** RH (RH-01)\
**Subscribers:** HR (workload/census update)\
**Persistence:** 📋 Planned (`fw_domain_events`)\
**Status:** 📝 Planned (RH-01.1 Implementation)

**Deprecated alias:** `bed_released`

**Example: Event Payload**

```typescript theme={null}
{
  event_name: 'rh_bed_released';
  event_timestamp: string;
  organization_id: string;
  episode_id: string;
  bed_id: string;
  residence_id: string;
  facility_type: 'recovery_housing' | 'psychiatric_residential' | 'inpatient_unit';
  released_at: string;
}
```

### Event: `rh_invoice_creation_requested`

**Publisher:** RH (RH-01)
**Subscribers:** FA (invoice creation)
**Channel:** `rh_events`
**Status:** 📝 Planned (RH-01 Implementation)

**Example: Event Payload**

```typescript theme={null}
{
  event_type: 'rh_invoice_creation_requested';
  event_timestamp: string;
  organization_id: string;
  episode_id: string;
  resident_profile_id: string;
  residence_id: string;
  agreement_id: string;
  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';
}
```

***

## API Contracts

### RH → FA: Episode Balance Query

**Consumer:** RH (episode detail page, bed board payment status)
**Provider:** FA
**Method:** GET
**URL:** `/api/v1/fa/episode-balance?episode_id={episodeId}`
**Status:** 📝 Planned

**Example: Query Response**

```typescript theme={null}
// Response
{
  episode_id: string;
  current_balance: number;
  last_payment_date: string | null;
  last_payment_amount: number | null;
  payment_status: 'current' | 'past_due' | 'paid_in_full' | 'unavailable';
}
```

### Platform Census → HR/PM: Census by Facility Type

**Consumer:** HR (workload drivers), PM (census reporting)
**Provider:** Platform Census Layer (`src/platform/census`)
**Pattern:** Platform Integration Layer (Pattern 1)
**Status:** 📝 Planned — requires `facility_type` on `rh_residences` (migration added 2026-02-22)

**Example: Census Query**

```typescript theme={null}
import { useCensusData } from '@/platform/census';

const { data } = useCensusData({
  organizationId,
  facilityType: 'inpatient_unit',  // optional filter
});
// data.totalCensus, data.totalCapacity, data.averageOccupancy
```

### CL → RH: Current Residence/Bed (Optional)

**Consumer:** CL (patient chart — current residence/bed read-only)
**Provider:** RH via Platform Integration Layer
**Pattern:** Platform Integration Layer / API (Pattern 3) — optional enhancement
**Status:** 📝 Planned (CL-01 chart enhancements)

**Example: Query**

```typescript theme={null}
// Returns current episode's residence + bed for a given patient_id
GET /api/v1/rh/current-residence?patient_id={patientId}

// Response
{
  episode_id: string;
  residence_id: string;
  residence_name: string;
  facility_type: 'recovery_housing' | 'psychiatric_residential' | 'inpatient_unit';
  bed_label: string;
  room_number: string | null;
  unit_label: string | null;   // non-null for inpatient
  admission_date: string;
}
```

***

## Integration Matrix

| From            | To                    | Pattern                                                                                   | Doc      |
| --------------- | --------------------- | ----------------------------------------------------------------------------------------- | -------- |
| RH (RH-01)      | FA                    | Event — `rh_resident_admitted`, `rh_resident_discharged`, `rh_invoice_creation_requested` | This doc |
| RH (RH-01)      | HR                    | Event — `bed_assigned`, `bed_released`                                                    | This doc |
| RH (RH-01)      | PM                    | Events include `facility_type` for POS derivation                                         | This doc |
| RH (RH-01)      | Platform Census Layer | Data source — `rh_beds`, `rh_residences` with `facility_type`                             | This doc |
| Platform Census | HR                    | Platform Layer — census by facility\_type                                                 | This doc |
| Platform Census | PM                    | Platform Layer — bed-day census for billing                                               | This doc |
| RH (RH-01)      | CL                    | Platform Integration Layer / API — current residence/bed (optional)                       | This doc |

***

## Facility Type → POS Mapping (PM-07)

PM derives place of service from `facility_type` in event payloads. No direct RH → PM import.

| facility\_type            | POS Code | Description                        |
| ------------------------- | -------- | ---------------------------------- |
| `recovery_housing`        | 55       | Residential SUD                    |
| `psychiatric_residential` | 56       | Psychiatric residential (RTC/BHRF) |
| `inpatient_unit`          | 51       | Inpatient psychiatric              |

PM-10 prior authorization: the BHRF 5-day urgent rule applies to `psychiatric_residential`; standard inpatient PA rules apply to `inpatient_unit`.

***

## References

* [RH-01 Spec](../../../specs/rh/specs/RH-01-census-beds-episodes.md)
* [RH-01.1 Spec (Bed Board & Facility Types)](../../../specs/rh/specs/RH-01.1-bed-board-facility-types.md)
* [EVENT\_CONTRACTS.md](./EVENT_CONTRACTS.md) — RH-01 event sections
* [CROSS\_CORE\_INTEGRATIONS.md](./CROSS_CORE_INTEGRATIONS.md) — Integration matrix
* [API\_CONTRACTS.md](./API_CONTRACTS.md) — FA Episode Balance Query
* [Platform Census](../../../src/platform/census/README.md)
* [PM-07 Charge Capture](../../../specs/pm/specs/PM-07-charge-capture-fee-schedules.md)
* [PM-10 Prior Authorization](../../../specs/pm/specs/PM-10-prior-authorization-management.md)
