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

# Integration Documentation: PM-49 — Revenue Cycle Automation Rules Engine

> Created: 2026-04-07 Status: \U0001F4DD Planned

**Spec:** [PM-49](../../../specs/pm/specs/PM-49-revenue-cycle-automation-rules-engine.md)
**Created:** 2026-04-07
**Status:** 📝 Planned

***

## Overview

PM-49 provides a configurable rules engine for automating routine revenue cycle decisions with pre-built behavioral health rule templates. It builds on PM-19's general business rule automation framework with RCM-specific templates, actions, and work queue prioritization.

***

## Platform Foundation Dependencies

| PF Feature                    | Integration Type           | Usage                                                                             |
| ----------------------------- | -------------------------- | --------------------------------------------------------------------------------- |
| PF-01 (Organizations & Sites) | Direct dependency          | Organization and site context for rules and queue scoping                         |
| PF-02 (RBAC)                  | Direct dependency          | Permission checks: `pm.rcm-rules.*`, `pm.rcm-queue.*`, `pm.rcm-log.*`             |
| PF-10 (Notifications)         | Platform Integration Layer | Alert billing managers on circuit breaker trips, batch completions, rule failures |
| PF-29 (Tasks)                 | Platform Integration Layer | Create tasks from rule actions (e.g., manual review needed)                       |
| PF-96 (Jurisdiction Profiles) | Platform Integration Layer | Filing deadline resolution for automated resubmissions                            |

***

## Internal PM Dependencies

| PM Feature                       | Integration Pattern    | Usage                                                                                                                                                                   |
| -------------------------------- | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| PM-19 (Business Rule Automation) | Extends                | PM-49 extends PM-19's rule framework with RCM-specific templates, actions, and execution patterns                                                                       |
| PM-29 (Denial Management)        | API/Event              | PM-49 triggers denial re-submissions through PM-29 workflows when denial rules match (see [API contracts](./API_CONTRACTS.md#pm-49-api-contracts))                      |
| PM-09 (Payment Posting)          | Event (consumed) / API | PM-49 posts adjustments through PM-09 posting hooks; consumes `pm_era_posted`, `pm_payment_posted` events (see [API contracts](./API_CONTRACTS.md#pm-49-api-contracts)) |
| PM-45 (Collections)              | API                    | PM-49 transfers accounts to PM-45 collections tiers based on aging rules (see [API contracts](./API_CONTRACTS.md#pm-49-api-contracts))                                  |
| PM-11 (Revenue Cycle Dashboard)  | Event (published)      | PM-49 publishes `pm_rcm_rule_executed` for PM-11 dashboard metrics                                                                                                      |

***

## API Contracts

**Full contract details:** See [API\_CONTRACTS.md](./API_CONTRACTS.md#pm-49-api-contracts)

### PM-49 → PM-09 (Payment Posting)

**Purpose:** Auto-post small balance adjustments and contractual adjustments

**Endpoint pattern:** Edge function or SECURITY DEFINER RPC
**Request Schema:**

```typescript theme={null}
{
  organization_id: string;      // UUID
  claim_id: string;             // UUID
  adjustment_code: string;      // e.g., "SB-WRITEOFF", "CONTR-ADJ"
  adjustment_amount: number;    // Decimal
  reason_text: string;          // Human-readable reason
  rule_execution_id?: string;   // UUID (for audit trail)
}
```

**Response Schema:**

```typescript theme={null}
{
  success: boolean;
  adjustment_id?: string;       // UUID if success
  error_code?: string;          // e.g., "CLAIM_NOT_FOUND", "INSUFFICIENT_BALANCE"
  error_message?: string;
}
```

**Error Codes:**

* `CLAIM_NOT_FOUND`: Claim ID does not exist
* `INSUFFICIENT_BALANCE`: Balance lower than adjustment amount
* `INVALID_ADJUSTMENT_CODE`: Unrecognized code
* `ORG_MISMATCH`: Claim does not belong to organization

**Idempotency:** Use `rule_execution_id` as idempotency key; duplicate requests return existing `adjustment_id`

***

### PM-49 → PM-29 (Denial Management)

**Purpose:** Auto-trigger denial re-submissions for correctable denial codes

**Endpoint pattern:** Edge function or SECURITY DEFINER RPC
**Request Schema:**

```typescript theme={null}
{
  organization_id: string;      // UUID
  denial_id: string;            // UUID
  resubmission_reason: string;  // e.g., "auto-resubmit CO-4 modifier"
  correction_notes?: string;    // Optional correction instructions
  rule_execution_id?: string;   // UUID (for audit trail)
}
```

**Response Schema:**

```typescript theme={null}
{
  success: boolean;
  resubmission_id?: string;     // UUID if success
  error_code?: string;          // e.g., "DENIAL_NOT_FOUND", "FILING_DEADLINE_PASSED"
  error_message?: string;
}
```

**Error Codes:**

* `DENIAL_NOT_FOUND`: Denial ID does not exist
* `FILING_DEADLINE_PASSED`: Resubmission past filing deadline (resolved via PF-96)
* `ALREADY_RESUBMITTED`: Denial already has pending resubmission
* `ORG_MISMATCH`: Denial does not belong to organization

**Idempotency:** Use `rule_execution_id` as idempotency key

**Filing Deadline Resolution:** Uses PF-96 jurisdiction profile to validate resubmission window (see PF-96 API contracts)

***

### PM-49 → PM-45 (Collections)

**Purpose:** Auto-transfer accounts to collections tiers based on aging rules

**Endpoint pattern:** Edge function or SECURITY DEFINER RPC
**Request Schema:**

```typescript theme={null}
{
  organization_id: string;      // UUID
  account_id: string;           // UUID or claim_id
  collections_tier: string;     // e.g., "early", "standard", "final"
  transfer_reason: string;      // Human-readable reason
  rule_execution_id?: string;   // UUID (for audit trail)
}
```

**Response Schema:**

```typescript theme={null}
{
  success: boolean;
  collections_entry_id?: string; // UUID if success
  error_code?: string;           // e.g., "ACCOUNT_NOT_FOUND", "ALREADY_IN_COLLECTIONS"
  error_message?: string;
}
```

**Error Codes:**

* `ACCOUNT_NOT_FOUND`: Account/claim ID does not exist
* `ALREADY_IN_COLLECTIONS`: Account already assigned to collections tier
* `INELIGIBLE_PAYER`: Payer type excluded from collections (e.g., Medicaid in some states)
* `ORG_MISMATCH`: Account does not belong to organization

**Idempotency:** Use `rule_execution_id` as idempotency key

***

## Event Contracts

### Events Consumed

| Event                | Source | Purpose                                                             |
| -------------------- | ------ | ------------------------------------------------------------------- |
| `pm_era_posted`      | PM-09  | Triggers event-based rules for auto-posting contractual adjustments |
| `pm_denial_received` | PM-29  | Triggers denial re-submission rules                                 |
| `pm_payment_posted`  | PM-09  | Triggers zero-balance close rules                                   |

### Events Published

| Event                  | Subscribers | Payload Schema                                                                                                                             |
| ---------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `pm_rcm_rule_executed` | PM-11       | `{ rule_id: string; rule_type: string; action_taken: string; target_entity_id: string; dollar_amount?: number; organization_id: string; }` |

***

## Scheduled Processing

| Job Name               | Schedule                                  | Edge Function          | Purpose                                                          |
| ---------------------- | ----------------------------------------- | ---------------------- | ---------------------------------------------------------------- |
| `pm-rcm-rule-batch`    | Hourly dispatcher (tenant-timezone aware) | `rcm-execute-rules`    | Nightly batch rule evaluation (target: 2 AM org/site local time) |
| `pm-rcm-queue-scoring` | Hourly dispatcher (tenant-timezone aware) | `rcm-score-work-queue` | Nightly work queue re-scoring (target: 3 AM org/site local time) |

**Tenant-Timezone Execution Strategy:**

Both `pm-rcm-rule-batch` and `pm-rcm-queue-scoring` use a dispatcher pattern to execute at tenant-local time (2 AM and 3 AM respectively):

1. **Fixed hourly cron:** `0 * * * *` — runs every hour
2. **Dispatcher logic:**
   * For each organization, resolve effective timezone (site timezone if available, otherwise org default)
   * Calculate current local time in that timezone
   * If local time matches target hour (02:00 for rules, 03:00 for scoring), enqueue/execute for that organization
   * Skip organizations already processed in current day window
3. **Job targets:**
   * `pm-rcm-rule-batch` invokes `rcm-execute-rules` with `organization_id` when tenant-local time is 02:00
   * `pm-rcm-queue-scoring` invokes `rcm-score-work-queue` with `organization_id` when tenant-local time is 03:00
4. **Metadata:** Batch execution persists timezone used for audit reproducibility (see spec §Scope clarification table)

**Alternative:** Per-tenant scheduled jobs can be configured if the dispatcher approach does not meet scaling requirements.

***

## Security Considerations

* All tables enforce organization-scoped RLS
* Execution records are immutable (no UPDATE/DELETE policies)
* Rule activation requires segregation of duties (creator != activator, except Director override)
* No PHI in rule definitions — rules reference account properties only
* Jurisdiction-aware filing deadlines via PF-96

***

## Validation Checklist

* [ ] Event contracts match EVENT\_CONTRACTS.md entries
* [x] API contracts documented for PM-09/PM-29/PM-45 interactions (see [API\_CONTRACTS.md](./API_CONTRACTS.md#pm-49-api-contracts) and [API Contracts](#api-contracts) section above)
* [ ] Platform layer usage aligned with PLATFORM\_INTEGRATION\_LAYERS.md
* [ ] Integration matrix entry in CROSS\_CORE\_INTEGRATIONS.md

***

**Last Updated:** 2026-04-07
