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

# Provider Schedule & Availability — Admin Guide

> Module: Practice Management (PM) Feature: PM-05 Provider Schedule & Availability Last Updated: 2026-02-20

**Module:** Practice Management (PM)\
**Feature:** PM-05 Provider Schedule & Availability\
**Last Updated:** 2026-02-20

***

## Overview

This guide covers permission configuration, default role assignments, and administrative workflows for the PM-05 Provider Schedule & Availability feature.

***

## 1. Permission Keys (9 Granular)

| Permission Key        | Category | Description                             |
| --------------------- | -------- | --------------------------------------- |
| `pm.schedule.view`    | view     | View provider schedule blocks           |
| `pm.schedule.create`  | create   | Create new schedule blocks              |
| `pm.schedule.edit`    | edit     | Edit existing schedule blocks           |
| `pm.schedule.delete`  | delete   | Delete schedule blocks                  |
| `pm.time_off.view`    | view     | View time-off requests                  |
| `pm.time_off.create`  | create   | Submit time-off requests                |
| `pm.time_off.edit`    | edit     | Edit pending time-off requests          |
| `pm.time_off.approve` | approve  | Approve or deny time-off requests       |
| `pm.caseload.view`    | view     | View provider caseload and panel status |

***

## 2. Default Role Assignments

| Role           | Permissions Granted                                                                                                                                                                       |
| -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **org\_admin** | All 9 permissions (auto-granted by `pf_auto_grant_org_admin` trigger)                                                                                                                     |
| **manager**    | `pm.schedule.view`, `pm.schedule.create`, `pm.schedule.edit`, `pm.time_off.view`, `pm.time_off.create`, `pm.time_off.edit`, `pm.time_off.approve`, `pm.caseload.view` (8 of 9; no delete) |
| **staff**      | `pm.schedule.view`, `pm.time_off.view`, `pm.caseload.view` (3 view-only permissions)                                                                                                      |

Custom roles can be configured via **Settings → Permissions** to grant any combination of these 9 keys.

***

## 3. Database Tables

### pm\_provider\_schedules

Stores recurring weekly availability blocks.

| Column            | Type    | Description                                                                                        |
| ----------------- | ------- | -------------------------------------------------------------------------------------------------- |
| `id`              | UUID    | Primary key                                                                                        |
| `organization_id` | UUID    | Tenant isolation                                                                                   |
| `provider_id`     | UUID    | References `pf_profiles`                                                                           |
| `location_id`     | UUID    | Optional, references `pf_sites`                                                                    |
| `day_of_week`     | INTEGER | 0=Sunday through 6=Saturday                                                                        |
| `start_time`      | TIME    | Block start time                                                                                   |
| `end_time`        | TIME    | Block end time                                                                                     |
| `block_type`      | TEXT    | `appointments`, `telehealth`, `documentation`, `supervision`, `group`, `administrative`, `on_call` |
| `effective_date`  | DATE    | When this block becomes active                                                                     |
| `end_date`        | DATE    | When this block expires (NULL = indefinite)                                                        |

### pm\_provider\_time\_off

Stores time-off requests with approval workflow.

| Column                 | Type | Description                                           |
| ---------------------- | ---- | ----------------------------------------------------- |
| `id`                   | UUID | Primary key                                           |
| `organization_id`      | UUID | Tenant isolation                                      |
| `provider_id`          | UUID | Requesting provider                                   |
| `start_date`           | DATE | Time-off start                                        |
| `end_date`             | DATE | Time-off end                                          |
| `time_off_type`        | TEXT | `vacation`, `sick`, `personal`, `conference`, `other` |
| `status`               | TEXT | `pending`, `approved`, `denied`                       |
| `coverage_provider_id` | UUID | Who covers patients during absence                    |
| `approved_by`          | UUID | User who approved/denied                              |
| `notes`                | TEXT | Request notes                                         |

### pm\_provider\_caseloads

One row per provider tracking patient capacity.

| Column                 | Type    | Description                 |
| ---------------------- | ------- | --------------------------- |
| `id`                   | UUID    | Primary key                 |
| `organization_id`      | UUID    | Tenant isolation            |
| `provider_id`          | UUID    | Unique per org+provider     |
| `active_patient_count` | INTEGER | Current active patients     |
| `max_caseload`         | INTEGER | Maximum capacity            |
| `panel_status`         | TEXT    | `open`, `limited`, `closed` |

***

## 4. RLS Policies

All three tables enforce:

* **FORCE ROW LEVEL SECURITY** — Even table owners cannot bypass RLS
* **SELECT/INSERT/UPDATE/DELETE** policies using `pm_has_org_access(organization_id, auth.uid())`
* **UPDATE WITH CHECK** — Prevents reassigning `organization_id` across tenants

***

## 5. Domain Events

| Event                   | Trigger                   | Payload                                                                              |
| ----------------------- | ------------------------- | ------------------------------------------------------------------------------------ |
| `pm_time_off_requested` | Provider submits time-off | `{ organization_id, provider_id, time_off_id, start_date, end_date, time_off_type }` |
| `pm_time_off_approved`  | Manager approves request  | `{ organization_id, provider_id, time_off_id, approved_by, coverage_provider_id }`   |
| `pm_time_off_denied`    | Manager denies request    | `{ organization_id, provider_id, time_off_id, denied_by }`                           |

These events can be consumed by the Forms & Workflow (FW) engine for automated notifications and task creation.

***

## 6. Integration with Scheduling (PM-03/PM-04)

The availability resolution utility (`src/cores/pm/utils/availability.ts`) is consumed by:

* **PM-03 Appointment Scheduling**: Warns when booking outside provider availability
* **PM-04 Group Session Scheduling**: Validates facilitator availability

The `useDoubleBookingCheck` hook includes an `outsideAvailability` flag when the proposed time does not fall within any `appointments` or `telehealth` schedule block.

***

## 7. Troubleshooting

| Issue                                 | Resolution                                                                                               |
| ------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| Provider not showing in schedule page | Verify the provider has a `pf_profiles` record and `pf_organization_members` membership                  |
| Time-off not blocking appointments    | Ensure the time-off status is `approved` (pending requests do not block availability)                    |
| Caseload shows 0 patients             | Caseload records are created/updated as patients are assigned; verify patient-provider assignments exist |
| Permission denied errors              | Check that the user's role has the required `pm.schedule.*` or `pm.time_off.*` permissions               |

***

**See Also:**

* [User Guide](./provider-schedule-availability-user-guide.md)
* [PM-05 Spec](../../specs/pm/specs/PM-05-provider-schedule-availability.md)
* [Integration Doc](../architecture/integrations/provider-schedule-availability-integration.md)
