Skip to main content

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.

Spec: PM-49 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 FeatureIntegration TypeUsage
PF-01 (Organizations & Sites)Direct dependencyOrganization and site context for rules and queue scoping
PF-02 (RBAC)Direct dependencyPermission checks: pm.rcm-rules.*, pm.rcm-queue.*, pm.rcm-log.*
PF-10 (Notifications)Platform Integration LayerAlert billing managers on circuit breaker trips, batch completions, rule failures
PF-29 (Tasks)Platform Integration LayerCreate tasks from rule actions (e.g., manual review needed)
PF-96 (Jurisdiction Profiles)Platform Integration LayerFiling deadline resolution for automated resubmissions

Internal PM Dependencies

PM FeatureIntegration PatternUsage
PM-19 (Business Rule Automation)ExtendsPM-49 extends PM-19’s rule framework with RCM-specific templates, actions, and execution patterns
PM-29 (Denial Management)API/EventPM-49 triggers denial re-submissions through PM-29 workflows when denial rules match (see API contracts)
PM-09 (Payment Posting)Event (consumed) / APIPM-49 posts adjustments through PM-09 posting hooks; consumes pm_era_posted, pm_payment_posted events (see API contracts)
PM-45 (Collections)APIPM-49 transfers accounts to PM-45 collections tiers based on aging rules (see 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

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:
{
  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:
{
  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:
{
  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:
{
  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:
{
  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:
{
  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

EventSourcePurpose
pm_era_postedPM-09Triggers event-based rules for auto-posting contractual adjustments
pm_denial_receivedPM-29Triggers denial re-submission rules
pm_payment_postedPM-09Triggers zero-balance close rules

Events Published

EventSubscribersPayload Schema
pm_rcm_rule_executedPM-11{ rule_id: string; rule_type: string; action_taken: string; target_entity_id: string; dollar_amount?: number; organization_id: string; }

Scheduled Processing

Job NameScheduleEdge FunctionPurpose
pm-rcm-rule-batchHourly dispatcher (tenant-timezone aware)rcm-execute-rulesNightly batch rule evaluation (target: 2 AM org/site local time)
pm-rcm-queue-scoringHourly dispatcher (tenant-timezone aware)rcm-score-work-queueNightly 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
  • API contracts documented for PM-09/PM-29/PM-45 interactions (see API_CONTRACTS.md and 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