> ## 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 Management & Submission — Integration

> Version: 2.0.0 Status: ✅ Implemented Last Updated: 2026-02-22 Last Verified: 2026-02-22 Spec: PM-08 Claims Management & Submission Constitution Reference: Sect…

**Version:** 2.0.0\
**Status:** ✅ Implemented\
**Last Updated:** 2026-02-22\
**Last Verified:** 2026-02-22\
**Spec:** [PM-08 Claims Management & Submission](../../../specs/pm/specs/PM-08-claims-management-submission.md)\
**Constitution Reference:** Section 1.2 (Core Independence), Section 1.3 (Integration Patterns)

***

## Overview

PM-08 owns claim generation from charges (837P/837I), pre-submission scrubbing, submission via clearinghouse or direct payer, status tracking, denial management (CARC/RARC), and secondary/tertiary and void/replacement claims.

**Key tables:** `pm_claims`, `pm_claim_lines`\
**RLS:** Full CRUD policies on both tables (tenant-isolated via `organization_id`). DELETE restricted to `org_admin`.\
**Scrubbing engine:** `src/cores/pm/utils/claim-scrubbing.ts` — validates NPI, diagnosis codes, service dates, filing deadline, line-level CPT/units/POS.\
**Event publisher:** `src/cores/pm/hooks/useClaimMutation.ts`

***

## Integration Points

| Dependency | Pattern             | Status        | Purpose                                                                               |
| ---------- | ------------------- | ------------- | ------------------------------------------------------------------------------------- |
| **PM-07**  | Data (FK)           | ✅ Implemented | Approved charges → claim lines; `pm_claim_lines.charge_id` → `pm_charges.id`          |
| **PM-09**  | Data (FK, mutation) | ✅ Implemented | ERA payments posted against claims; status updated to `paid`/`denied`                 |
| **PM-15**  | Data / API          | 📋 Planned    | Clearinghouse transmission; `clearinghouse_trace_id` round-trip                       |
| **PM-02**  | Data (query)        | ✅ Implemented | Eligibility check before submission; latest `pm_eligibility_checks` for patient+payer |
| **PM-10**  | Data (query)        | ✅ Implemented | Authorization verification in scrubbing; active auth for service type                 |
| **PF-70**  | Platform            | ✅ Implemented | Code library (CPT/ICD-10/HCPCS) for validation via `@/platform/codes`                 |

***

## Event Contracts

### `claim_submitted` (PM-08 → PM-15, PF-10, PF-04)

**Status:** ✅ Implemented\
**Last Verified:** 2026-02-22\
**Channel:** `cl_pm_events`\
**Publisher:** `src/cores/pm/hooks/useClaimMutation.ts` (via `publishEvent`)\
**DB registration:** `fw_workflow_events` row exists (owning\_core: `pm`, category: `operational`)

Published when a claim transitions to `submitted` status.

```typescript theme={null}
interface ClaimSubmittedPayload {
  event_name: 'claim_submitted';
  organization_id: string;           // UUID — tenant
  payload: {
    claim_id: string;                 // UUID — pm_claims.id
    claim_number: string;             // Generated claim number (e.g., "CLM-20260222-001")
    patient_id: string;               // UUID — pm_patients.id
    payer_id: string;                 // UUID — pm_payers.id
    claim_type: 'professional_837p' | 'institutional_837i';
    total_charge: number;             // Sum of line charges (USD cents)
    line_count: number;               // Count of pm_claim_lines for this claim
    submitted_by: string;             // UUID — auth.uid() of submitting user
  };
}
```

**Consumers:**

| Consumer | Pattern            | Status        | Behavior                                    |
| -------- | ------------------ | ------------- | ------------------------------------------- |
| PM-15    | Event subscription | 📋 Planned    | Initiates clearinghouse 837P/I transmission |
| PF-10    | Notification       | ✅ Implemented | Notifies billing manager of submission      |
| PF-04    | Audit              | ✅ Implemented | Audit log entry with claim\_id and user     |

### `claim_status_changed` (PM-08 → PM-11, PF-10, FA)

**Status:** ✅ Implemented\
**Last Verified:** 2026-02-22\
**Channel:** `cl_pm_events`\
**Publisher:** `src/cores/pm/hooks/useClaimMutation.ts` (via `publishEvent`)\
**DB registration:** `fw_workflow_events` row exists (owning\_core: `pm`, category: `operational`)

Published on any claim status transition.

```typescript theme={null}
interface ClaimStatusChangedPayload {
  event_name: 'claim_status_changed';
  organization_id: string;           // UUID — tenant
  payload: {
    claim_id: string;                 // UUID — pm_claims.id
    claim_number: string;             // Claim number
    patient_id: string;               // UUID — pm_patients.id
    payer_id: string;                 // UUID — pm_payers.id
    previous_status: ClaimStatus;
    new_status: ClaimStatus;
    denial_codes?: DenialCode[];      // Present when new_status is 'denied'
    paid_amount?: number;             // Present when new_status is 'paid' (USD cents)
    changed_by: string;               // UUID — auth.uid()
  };
}

type ClaimStatus =
  | 'draft'
  | 'scrubbed'
  | 'submitted'
  | 'accepted'
  | 'rejected'
  | 'paid'
  | 'denied'
  | 'appealed'
  | 'adjusted';

interface DenialCode {
  carc: string;                       // Claim Adjustment Reason Code (e.g., "CO-45")
  rarc?: string;                      // Remittance Advice Remark Code
  group_code: 'CO' | 'PR' | 'OA' | 'PI'; // CARC group
  amount?: number;                    // Adjustment amount (USD cents)
}
```

**Consumers:**

| Consumer | Pattern         | Status        | Behavior                                              |
| -------- | --------------- | ------------- | ----------------------------------------------------- |
| PM-11    | Dashboard query | ✅ Implemented | Revenue cycle metrics (denial rate, clean claim %)    |
| PF-10    | Notification    | ✅ Implemented | Denial notifications to assigned biller               |
| FA       | GL posting      | 📋 Planned    | Journal entries on `paid` status (future integration) |

**Valid State Transitions:**

```
draft → scrubbed
scrubbed → submitted | draft
submitted → accepted | rejected
accepted → paid | denied
rejected → draft
paid → adjusted
denied → appealed | draft
appealed → paid | denied
adjusted → (terminal)
```

***

## Data Contracts

### PM-07 → PM-08: Approved Charges Query

**Status:** ✅ Implemented\
**Last Verified:** 2026-02-22

PM-08 generates claims from approved, unlinked charges:

```sql theme={null}
SELECT id, organization_id, patient_id, provider_id, service_date,
       cpt_code, units, modifiers, place_of_service,
       diagnosis_codes, fee_schedule_id, amount
FROM pm_charges
WHERE organization_id = :org_id
  AND status = 'approved'
  AND claim_id IS NULL           -- not yet linked to a claim
  AND deleted_at IS NULL
ORDER BY service_date, patient_id;
```

**Mapping:** Each charge maps to one `pm_claim_lines` row:

| pm\_charges column      | pm\_claim\_lines column                |
| ----------------------- | -------------------------------------- |
| `id`                    | `charge_id` (FK)                       |
| `cpt_code`              | `cpt_code`                             |
| `units`                 | `units`                                |
| `modifiers`             | `modifiers`                            |
| `place_of_service`      | `place_of_service`                     |
| `amount`                | `charge_amount`                        |
| `service_date`          | `service_date`                         |
| `diagnosis_codes[0..3]` | `diagnosis_pointers` (1-indexed array) |

After claim creation, the source charge's `claim_id` is back-populated.

### PM-08 → PM-09: Claims for Payment Posting

**Status:** ✅ Implemented\
**Last Verified:** 2026-02-22

PM-09 reads claims and lines to post ERA payments:

```sql theme={null}
SELECT c.id, c.claim_number, c.patient_id, c.payer_id, c.total_charge,
       c.status, c.paid_amount, c.adjustment_amount, c.patient_responsibility,
       cl.id AS line_id, cl.line_number, cl.cpt_code, cl.charge_amount,
       cl.paid_amount AS line_paid, cl.adjustment_amount AS line_adjustment
FROM pm_claims c
JOIN pm_claim_lines cl ON cl.claim_id = c.id AND cl.organization_id = c.organization_id
WHERE c.organization_id = :org_id
  AND c.status IN ('submitted', 'accepted')
  AND c.claim_number = :claim_number   -- matched from ERA/835
  AND c.deleted_at IS NULL;
```

**Mutation contract:** PM-09 updates these `pm_claims` columns via `.update()`:

| Column                   | Type        | Description                                         |
| ------------------------ | ----------- | --------------------------------------------------- |
| `status`                 | text        | → `paid`, `denied`, or stays `accepted` for partial |
| `paid_amount`            | numeric     | Total paid by payer                                 |
| `adjustment_amount`      | numeric     | Contractual adjustments (CO group)                  |
| `patient_responsibility` | numeric     | Patient balance (PR group)                          |
| `denial_codes`           | jsonb       | Array of `DenialCode` objects                       |
| `adjudicated_at`         | timestamptz | Date of adjudication                                |

### PM-08 Scrubbing: Pre-Submission Validation

**Status:** ✅ Implemented\
**Last Verified:** 2026-02-22\
**Location:** `src/cores/pm/utils/claim-scrubbing.ts`

```typescript theme={null}
interface ScrubResult {
  passed: boolean;                    // true if zero errors
  errors: ScrubError[];               // blocking — must fix before submission
  warnings: ScrubError[];             // advisory — can submit with warnings
}

interface ScrubError {
  code: string;                       // e.g., "MISSING_NPI", "EXPIRED_AUTH"
  field: string;                      // e.g., "billing_provider_npi"
  message: string;                    // Human-readable description
  line_number?: number;               // Specific claim line, if applicable
}
```

**Validations performed:**

| Code                   | Field                       | Rule                                                    |
| ---------------------- | --------------------------- | ------------------------------------------------------- |
| `MISSING_NPI`          | `billing_provider_npi`      | NPI must be present (sourced from `pm_module_settings`) |
| `MISSING_DIAGNOSIS`    | `primary_diagnosis_code`    | At least one ICD-10-CM required                         |
| `MISSING_SERVICE_DATE` | `service_date_from`         | Service date range required                             |
| `PAST_FILING_DEADLINE` | `filing_deadline`           | Must be within 365-day AHCCCS deadline                  |
| `MISSING_CPT`          | `cpt_code` (line)           | Each line must have a valid CPT/HCPCS                   |
| `MISSING_UNITS`        | `units` (line)              | Units must be > 0                                       |
| `MISSING_POS`          | `place_of_service` (line)   | Place of service required per line                      |
| `MISSING_DIAG_POINTER` | `diagnosis_pointers` (line) | At least one diagnosis pointer required                 |

***

## Database Schema (pm\_claims)

**Last Verified:** 2026-02-22

| Column                   | Type        | Nullable | Description                                   |
| ------------------------ | ----------- | -------- | --------------------------------------------- |
| `id`                     | uuid        | NO       | PK                                            |
| `organization_id`        | uuid        | NO       | Tenant FK → `pf_organizations`                |
| `patient_id`             | uuid        | NO       | FK → `pm_patients`                            |
| `claim_number`           | text        | NO       | Generated claim number                        |
| `claim_type`             | text        | NO       | `professional_837p` or `institutional_837i`   |
| `payer_id`               | uuid        | NO       | FK → `pm_payers`                              |
| `policy_id`              | uuid        | YES      | FK → `pm_insurance_policies`                  |
| `billing_provider_npi`   | text        | YES      | From `pm_module_settings`                     |
| `rendering_provider_npi` | text        | YES      | Provider NPI                                  |
| `facility_id`            | uuid        | YES      | FK → `pf_sites`                               |
| `service_date_from`      | date        | YES      | DOS range start                               |
| `service_date_to`        | date        | YES      | DOS range end                                 |
| `primary_diagnosis_code` | text        | YES      | ICD-10-CM                                     |
| `total_charge`           | numeric     | YES      | Sum of line charges                           |
| `status`                 | text        | YES      | Claim lifecycle status                        |
| `submitted_at`           | timestamptz | YES      | Submission timestamp                          |
| `adjudicated_at`         | timestamptz | YES      | Adjudication timestamp                        |
| `paid_amount`            | numeric     | YES      | Payer paid amount                             |
| `adjustment_amount`      | numeric     | YES      | Contractual adjustments                       |
| `patient_responsibility` | numeric     | YES      | Patient balance                               |
| `denial_codes`           | jsonb       | YES      | Array of DenialCode objects                   |
| `frequency_code`         | text        | YES      | `1` (original), `7` (replacement), `8` (void) |
| `original_claim_id`      | uuid        | YES      | Self-FK for replacement/void claims           |
| `filing_deadline`        | date        | YES      | 365-day AHCCCS deadline                       |
| `clearinghouse_trace_id` | text        | YES      | Returned by PM-15                             |
| `custom_fields`          | jsonb       | NO       | Default `{}`                                  |
| `deleted_at`             | timestamptz | YES      | Soft delete                                   |
| `created_at`             | timestamptz | NO       | Auto                                          |
| `updated_at`             | timestamptz | NO       | Auto                                          |
| `created_by`             | uuid        | YES      | FK → `pf_profiles`                            |
| `updated_by`             | uuid        | YES      | FK → `pf_profiles`                            |

## Database Schema (pm\_claim\_lines)

**Last Verified:** 2026-02-22

| Column                   | Type        | Nullable | Description                             |
| ------------------------ | ----------- | -------- | --------------------------------------- |
| `id`                     | uuid        | NO       | PK                                      |
| `organization_id`        | uuid        | NO       | Tenant FK                               |
| `claim_id`               | uuid        | NO       | FK → `pm_claims`                        |
| `charge_id`              | uuid        | YES      | FK → `pm_charges` (source charge)       |
| `line_number`            | int         | NO       | Sequence within claim                   |
| `service_date`           | date        | YES      | Line-level DOS                          |
| `cpt_code`               | text        | YES      | CPT/HCPCS code                          |
| `modifiers`              | text\[]     | YES      | Up to 4 modifiers                       |
| `units`                  | numeric     | YES      | Service units                           |
| `diagnosis_pointers`     | int\[]      | YES      | 1-indexed references to claim diagnoses |
| `charge_amount`          | numeric     | YES      | Billed amount                           |
| `paid_amount`            | numeric     | YES      | Paid by payer                           |
| `adjustment_amount`      | numeric     | YES      | Adjustments                             |
| `adjustment_reason`      | text        | YES      | CARC code                               |
| `denial_reason`          | text        | YES      | Denial reason                           |
| `rendering_provider_npi` | text        | YES      | Line-level provider                     |
| `place_of_service`       | text        | YES      | POS code                                |
| `revenue_code`           | text        | YES      | For institutional claims                |
| `custom_fields`          | jsonb       | YES      | Default `{}`                            |
| `deleted_at`             | timestamptz | YES      | Soft delete                             |
| `created_at`             | timestamptz | NO       | Auto                                    |
| `updated_at`             | timestamptz | NO       | Auto                                    |
| `created_by`             | uuid        | YES      | FK → `pf_profiles`                      |
| `updated_by`             | uuid        | YES      | FK → `pf_profiles`                      |

***

## RLS Policies

**Last Verified:** 2026-02-22

| Table            | Policy                  | Command | Rule                                               |
| ---------------- | ----------------------- | ------- | -------------------------------------------------- |
| `pm_claims`      | `pm_claims_select`      | SELECT  | `organization_id` tenant match                     |
| `pm_claims`      | `pm_claims_insert`      | INSERT  | `organization_id` tenant match                     |
| `pm_claims`      | `pm_claims_update`      | UPDATE  | `organization_id` tenant match (with `WITH CHECK`) |
| `pm_claims`      | `pm_claims_delete`      | DELETE  | `org_admin` role only                              |
| `pm_claim_lines` | `pm_claim_lines_select` | SELECT  | `organization_id` tenant match                     |
| `pm_claim_lines` | `pm_claim_lines_insert` | INSERT  | `organization_id` tenant match                     |
| `pm_claim_lines` | `pm_claim_lines_update` | UPDATE  | `organization_id` tenant match (with `WITH CHECK`) |
| `pm_claim_lines` | `pm_claim_lines_delete` | DELETE  | `org_admin` role only                              |

***

## Integration Matrix

| From       | To    | Pattern                           | Status        | Last Verified | Doc                                                                      |
| ---------- | ----- | --------------------------------- | ------------- | ------------- | ------------------------------------------------------------------------ |
| PM (PM-08) | PM-07 | Data (charges → claims)           | ✅ Implemented | 2026-02-22    | This doc                                                                 |
| PM (PM-08) | PM-09 | Data (claims for payment posting) | ✅ Implemented | 2026-02-22    | [PM-09 Integration](./payment-posting-era-processing-integration.md)     |
| PM (PM-08) | PM-15 | Data / API (clearinghouse)        | 📋 Planned    | —             | TBD in PM-15 integration                                                 |
| PM (PM-08) | PM-02 | Data (eligibility query)          | ✅ Implemented | 2026-02-22    | This doc                                                                 |
| PM (PM-08) | PM-10 | Data (auth verification)          | ✅ Implemented | 2026-02-22    | [PM-10 Integration](./prior-authorization-management-integration.md)     |
| PM (PM-08) | PF-70 | Platform (code library)           | ✅ Implemented | 2026-02-22    | [PF-70 Integration](./medical-terminology-code-libraries-integration.md) |
| PM (PM-08) | PF-10 | Platform (notifications)          | ✅ Implemented | 2026-02-22    | Event consumers above                                                    |
| PM (PM-08) | PF-04 | Platform (audit)                  | ✅ Implemented | 2026-02-22    | Event consumers above                                                    |

***

## References

* [PM-08 Spec](../../../specs/pm/specs/PM-08-claims-management-submission.md)
* [CROSS\_CORE\_INTEGRATIONS](./CROSS_CORE_INTEGRATIONS.md)
* [EVENT\_CONTRACTS](./EVENT_CONTRACTS.md)
* [PM-09 Payment Posting Integration](./payment-posting-era-processing-integration.md)
* [PM-10 Prior Auth Integration](./prior-authorization-management-integration.md)
* [PF-70 Code Library Integration](./medical-terminology-code-libraries-integration.md)
