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

# Claims Denial Management & Appeals — Integration Document

> Status: \U0001F4DD Planned Last Updated: 2026-03-02 Owner: PM Core

**Spec:** [PM-29](../../../specs/pm/specs/PM-29-claims-denial-management-appeals.md)\
**Status:** 📝 Planned\
**Last Updated:** 2026-03-02\
**Owner:** PM Core

***

## Overview

PM-29 introduces the denial management and appeals workflow. It integrates with multiple PM specs (claim status, ERA, prior auth, analytics, scrubbing), PF-29 (tasks), and PF-70 (code library). All integrations are within the PM core or via the Platform Integration Layer; no direct cross-core imports.

***

## Integration Points

### PM-08 — Claims Management & Submission

**Pattern:** Data (same core)\
**Direction:** PM-29 → PM-08 (reads claim data; triggers resubmission)

| Interaction                           | Details                                                                                                                                           |
| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| Claim status update on appeal outcome | When appeal status transitions to `won` or `lost`, PM-29 updates `pm_claims.status` via internal hook; no cross-core import needed (same PM core) |
| Bulk re-submit trigger                | Bulk re-submit action calls PM-08 resubmission function; batch size governed by org PM-28 setting (default 100, max 500)                          |
| Claim data read                       | Denial queue reads `pm_claims` (claim\_number, payer, provider, dates) for display and merge fields                                               |

**Contract:** Internal same-core data access. No event contract needed.

***

### PM-09 — Payment Posting & ERA Processing

**Pattern:** Data (same core)\
**Direction:** PM-09 → PM-29 (denial intake from ERA)

| Interaction            | Details                                                                                                                                                                                                                                                                                  |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| ERA denial auto-intake | During ERA posting, PM-09 auto-creates `pm_claim_denials` rows for all CO/PR/OA adjustment reason codes. Fields populated: `claim_id`, `denial_reason_code`, `denial_category` (mapped from CARC), `denial_date`, `amount_denied`, `payer_appeal_deadline` (calculated), `remittance_id` |
| CARC/RARC mapping      | PM-09 maps CARC/RARC codes to `denial_category` enum (auth, eligibility, coding, medical\_necessity, other) during ERA processing                                                                                                                                                        |

**Contract:** Internal same-core function call. `pm_claim_denials` insert triggered by PM-09 ERA posting logic.

***

### PM-10 — Prior Authorization Management

**Pattern:** Data (same core)\
**Direction:** PM-29 reads PM-10 data for auth-denial linking

| Interaction      | Details                                                                                                                                                                                          |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Auth denial link | When `denial_category = 'auth'` and ERA REF segment contains authorization reference, PM-09 populates `prior_authorization_id` FK on `pm_claim_denials` pointing to `pm_prior_authorizations.id` |
| Appeal context   | Appeal workflow may surface prior auth details (auth number, expiration, requested units) from `pm_prior_authorizations` for inclusion in appeal letter merge fields                             |

**Contract:** Internal same-core FK read. No event contract needed.

***

### PM-11 — Revenue Cycle Dashboard & Analytics

**Pattern:** Data / Platform Layer (same core)\
**Direction:** PM-29 → PM-11 (denial metrics feed)

| Interaction                                       | Details                                                                                                                                 |
| ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| First-pass acceptance rate                        | PM-11 KPI widget reads from `pm_claim_denials` to compute: `(adjudicated_paid_without_denial ÷ total_adjudicated) × 100`                |
| Denial rate by payer/reason/provider/service type | PM-11 analytics pull aggregated denial data from `pm_claim_denials` grouped by payer, denial\_category, assigned provider, service date |
| Dashboard link                                    | PM-11 RCM dashboard widgets link to `/pm/denials` pre-filtered by dimension                                                             |

**Contract:** Internal same-core data reads. Queries defined in PM-29 analytics hooks; consumed by PM-11 dashboard.

***

### PM-18 — Configurable Claim Scrubbing (Phase 2)

**Pattern:** Data (same core) — Deferred to Phase 2\
**Direction:** PM-29 → PM-18 (denial pattern → scrub rule suggestions)

| Interaction                    | Details                                                                                                                                                                                            |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Denial-driven rule suggestions | Phase 2: PM-18 rule-suggestion engine reads denial history from `pm_claim_denials` to surface patterns (e.g. "47 denials for missing auth from Payer X → suggest adding auth-required scrub rule") |

**Status:** Deferred to Phase 2. No contract defined at PM-29 MVP. See `specs/DEFERRED_DASHBOARD.md` for tracking.

***

### PF-29 — Tasks

**Pattern:** Platform Layer\
**Direction:** PM-29 → PF-29 (auto-creates follow-up task on appeal submission)\
**Status:** ✅ Contract resolved — PF-29 is Complete; `@/platform/tasks` `TaskInsert` type is canonical.

| Interaction                | Details                                                                                                                                |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Auto-task on appeal submit | When `pm_appeal_submissions` is inserted with `status = 'submitted'`, PM-29 calls `useTaskMutation().create()` from `@/platform/tasks` |
| Manual task creation       | Denial detail view renders `<TaskFormDialog>` from `@/platform/tasks`; pre-populated with denial context                               |
| Phase 2: deadline alerts   | Cron-triggered follow-up N days before deadline (deferred — see DEFERRED\_DASHBOARD.md)                                                |

**Payload (auto-task on appeal submit):**

```typescript theme={null}
import { useTaskMutation } from '@/platform/tasks';

// Called from PM-29 appeal submit handler
const { create } = useTaskMutation();

create({
  organization_id: organizationId,
  title: `Follow up: appeal for claim ${claimNumber}`,
  description: `Appeal submitted for denial on ${denialDate}. Payer: ${payerName}. Category: ${denialCategory}.`,
  status: 'open',
  priority: 'high',             // Overdue risk: missed deadline = lost revenue
  assigned_to: assignedTo,      // Defaults to current user; reassignable
  due_date: payerAppealDeadline, // DATE string from pm_claim_denials.payer_appeal_deadline
  source_type: 'pm_appeal',     // PM-29 source type; extend TaskSourceType union
  source_id: appealSubmissionId, // pm_appeal_submissions.id
  custom_fields: {
    denial_id: denialId,
    claim_id: claimId,
    denial_category: denialCategory,
  },
});
```

**`source_type` registration:** Add `'pm_appeal'` to the `TaskSourceType` union in `src/platform/tasks/types.ts`. This extends the existing `string` open union; add it as a named literal for type safety and filtering.

**`due_date` conversion note:** `payer_appeal_deadline` is stored as `TIMESTAMPTZ`. Convert to `DATE` string (YYYY-MM-DD in org timezone) before passing to `due_date: DATE` on `pf_tasks`. Use `formatInUserTimeZone(deadline, 'yyyy-MM-dd')` from `@/platform/forms`.

***

### PF-70 — Medical Terminology Code Libraries

**Pattern:** Platform Layer\
**Direction:** PM-29 reads PF-70 for CARC/RARC code descriptions

| Interaction                  | Details                                                                                                                                                                   |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CARC/RARC description lookup | Denial reason code display resolves CARC/RARC descriptions from PF-70 when available. Fallback: local seeded lookup table in PM-29 migrations (CMS-published static list) |
| Fallback strategy            | PM-29 migrations include seed for CMS CARC/RARC codes. Replace with PF-70 query when CARC/RARC is confirmed in PF-70 scope                                                |

**Contract:** Read-only platform layer query. See [PF-70 Integration](./medical-terminology-code-libraries-integration.md).

***

## Platform Layer Usage

| Layer                            | Used By                         | Purpose                                       |
| -------------------------------- | ------------------------------- | --------------------------------------------- |
| `@/platform/tasks` (PF-29)       | PM-29 appeal submission         | Auto-create follow-up task                    |
| `@/platform/permissions` (PF-30) | PM-29 UI                        | Permission-gate denial queue, appeal creation |
| `@/platform/table-v2`            | PM-29 denial queue              | DataTable with sort/filter/virtual scroll     |
| `@/platform/forms`               | PM-29 denial entry, appeal form | Form management                               |
| Sonner (toast)                   | PM-29 actions                   | Bulk assign, submit, status update toasts     |

***

## Events

PM-29 does not publish events at MVP. Potential future events (Phase 2+):

| Event                        | Publisher | Consumers                                 | Status           |
| ---------------------------- | --------- | ----------------------------------------- | ---------------- |
| `pm_denial_created`          | PM-29     | PM-18 (rule suggestions)                  | Deferred Phase 2 |
| `pm_appeal_submitted`        | PM-29     | PF-10 (deadline notification)             | Deferred Phase 2 |
| `pm_appeal_outcome_recorded` | PM-29     | PM-11 (KPI refresh), PM-08 (claim status) | Deferred Phase 2 |

***

## Security & Tenancy

* All tables RLS-protected with `pm_has_org_access(organization_id, auth.uid())`.
* No PHI in logs or event payloads.
* Permission keys: `pm.denials.view`, `pm.denials.manage`, `pm.appeals.submit`.
* Template letter HTML: merge fields HTML-escaped before insertion (XSS prevention).

***

## Pending Contracts

| Item                               | Blocking On                      | Status                | Notes                                                                                                                                                                                                     |
| ---------------------------------- | -------------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| PF-29 task creation payload schema | PF-29 task creation API contract | ✅ Resolved 2026-03-02 | PF-29 is Complete; `useTaskMutation().create()` from `@/platform/tasks`; `source_type: 'pm_appeal'`; add to `TaskSourceType` union in `src/platform/tasks/types.ts`. Full payload in PF-29 section above. |
| PM-18 Phase 2 denial-pattern feed  | PM-18 Phase 2 implementation     | ⏳ Deferred            | Denial history query design and suggestion-surface API TBD when PM-18 Phase 2 is scheduled. Tracked in DEFERRED\_DASHBOARD.md.                                                                            |
