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

# Insurance & Eligibility Verification — Admin Guide

> Permissions are managed via Platform Foundation → Role Permissions (pf_role_permissions). Custom roles can be configured via the admin UI.

## Permission Reference

| Permission Key        | Description                        | Default Roles                            |
| --------------------- | ---------------------------------- | ---------------------------------------- |
| `pm.insurance.view`   | View patient insurance policies    | org\_admin, site\_admin, staff, readonly |
| `pm.insurance.manage` | Create / edit / terminate policies | org\_admin, site\_admin, staff           |
| `pm.eligibility.run`  | Record eligibility check results   | org\_admin, site\_admin, staff           |
| `pm.payers.view`      | View payer directory               | org\_admin, site\_admin, staff, readonly |
| `pm.payers.manage`    | Create / edit / deactivate payers  | org\_admin, site\_admin, staff           |

Permissions are managed via **Platform Foundation → Role Permissions** (`pf_role_permissions`). Custom roles can be configured via the admin UI.

***

## Payer Directory Setup

### Required Fields

| Field                    | Required                    | Notes                                                              |
| ------------------------ | --------------------------- | ------------------------------------------------------------------ |
| `payer_name`             | ✅                           | Display name shown in dropdowns                                    |
| `payer_type`             | Optional                    | commercial / medicaid / medicare / tricare / workers\_comp / other |
| `electronic_payer_id`    | Optional (needed for PM-15) | X12 payer ID for 270/271 eligibility                               |
| `clearinghouse_payer_id` | Optional (needed for PM-15) | Routing ID for claim submission                                    |
| `phone`                  | Optional                    | Payer provider services line                                       |
| `website`                | Optional                    | Payer portal URL                                                   |
| `is_active`              | Auto                        | Defaults to true; false hides from dropdowns                       |

### Soft Delete vs. Deactivate

| Action                               | Effect                                                           | Reversible           |
| ------------------------------------ | ---------------------------------------------------------------- | -------------------- |
| **Deactivate** (`is_active = false`) | Hidden from dropdowns; historical records intact                 | Yes — click Activate |
| **Remove** (`deleted_at` set)        | Fully hidden from all UI; historical policies still reference it | Admin SQL only       |

> **Recommendation:** Use **Deactivate** for payers that are no longer contracted. Use **Remove** only for payers added by mistake with no associated policies.

***

## Insurance Policy Data Model

### `pm_insurance_policies` Schema

| Column             | Type        | Notes                                  |
| ------------------ | ----------- | -------------------------------------- |
| `organization_id`  | UUID        | Tenant key — required                  |
| `patient_id`       | UUID        | FK → `pm_patients.id`                  |
| `payer_id`         | UUID        | FK → `pm_payers.id`                    |
| `policy_number`    | TEXT        | Required; unique per org+patient+payer |
| `priority_order`   | INTEGER     | 1 = primary; COB ordering              |
| `status`           | TEXT        | active / inactive / terminated         |
| `effective_date`   | DATE        | Required                               |
| `termination_date` | DATE        | Set when policy terminated             |
| `custom_fields`    | JSONB       | Org-configurable extensions            |
| `deleted_at`       | TIMESTAMPTZ | Soft delete — null = active            |

### Unique Constraint

A composite unique constraint prevents duplicate policies:

```sql theme={null}
UNIQUE (organization_id, patient_id, payer_id, policy_number)
```

If staff try to add the same policy twice, they will see a validation error.

***

## Eligibility Check Data Model

### `pm_eligibility_checks` Schema

| Column             | Type        | Notes                                                      |
| ------------------ | ----------- | ---------------------------------------------------------- |
| `check_type`       | TEXT        | real\_time / batch / manual                                |
| `response_status`  | TEXT        | active\_coverage / inactive / not\_found / error / pending |
| `eligible`         | BOOLEAN     | Final determination                                        |
| `benefit_details`  | JSONB       | Structured benefit data (see BenefitDetails type)          |
| `next_check_due`   | TIMESTAMPTZ | When to re-verify                                          |
| `request_trace_id` | TEXT        | Clearinghouse reference (PM-15)                            |
| `checked_by`       | UUID        | User who recorded the check                                |

Eligibility checks are **append-only** in practice — no delete RLS policy exists. Historical checks are retained for audit.

***

## RLS Security Model

All three tables use `FORCE ROW LEVEL SECURITY` with `SECURITY DEFINER` helper functions to prevent RLS recursion:

| Helper Function                                      | Purpose                                             |
| ---------------------------------------------------- | --------------------------------------------------- |
| `pm_has_org_access(org_id, user_id)`                 | Delegates to `pf_has_org_access` — tenant isolation |
| `pm_can_access_insurance_policy(user_id, policy_id)` | Policy-scoped SELECT check                          |
| `pm_can_modify_insurance_policy(user_id, policy_id)` | Policy-scoped UPDATE check                          |

### Policy Summary

| Table                   | SELECT      | INSERT      | UPDATE                   | DELETE             |
| ----------------------- | ----------- | ----------- | ------------------------ | ------------------ |
| `pm_payers`             | org members | org members | org members (WITH CHECK) | org\_admin only    |
| `pm_insurance_policies` | org members | org members | org members (WITH CHECK) | org members        |
| `pm_eligibility_checks` | org members | org members | org members (WITH CHECK) | — (no hard delete) |

***

## Phase 2: Real-Time Eligibility (PM-15)

Phase 1 supports **manual eligibility entry only**. Real-time 270/271 transactions require:

1. **PM-15: Clearinghouse Integration** — SFTP/API connectivity to Availity, Change Healthcare, or Trizetto
2. **AHCCCS Online configuration** — organization-level AHCCCS provider credentials stored as secrets
3. **Electronic Payer IDs** configured on all payers in the directory

Once PM-15 is implemented, the `check_type = 'real_time'` flow will:

1. Send a 270 inquiry to the clearinghouse
2. Parse the 271 response into `benefit_details` JSONB
3. Record the check automatically with `request_trace_id` from the clearinghouse

***

## AHCCCS-Specific Configuration (Deferred to PM-15)

* AHCCCS member ID is stored on `pm_patients.ahcccs_member_id` (PM-01)
* AHCCCS payer type = `medicaid` in the payer directory
* AHCCCS is always the **payer of last resort** (highest `priority_order` number)
* AHCCCS Online eligibility portal: [https://www.healthearizonaplus.gov](https://www.healthearizonaplus.gov)

***

## Domain Events

### `pm_eligibility_verified`

Published to the platform event bus after every eligibility check insert.

**Payload schema:**

```json theme={null}
{
  "check_id": "string",
  "patient_id": "string",
  "policy_id": "string | null",
  "organization_id": "string",
  "eligible": "boolean",
  "response_status": "string",
  "check_type": "string",
  "next_check_due": "string | null",
  "timestamp": "string"
}
```

**Downstream consumers (planned):**

* **CL-01**: Update patient chart coverage indicator
* **PM-08**: Gate claim submission on eligibility status
