Skip to main content

Commercial payer onboarding (bulk seed)

Outcome

A new tenant has UHC / Anthem / Aetna / Cigna / Humana provisioned with realistic contracts, fee schedules, and program configs in one transaction.

Prerequisites

  • A new tenant DB (post-provisioning) that needs to bill commercial.
  • Master payer rows already seeded by master migration 043 + modifier rules by 045.
  • Tenant has at least one billing_entity and one BH outpatient canonical_program.

What the seed installs per tenant

For each of the five commercial payers, the module upserts:

TableWhatIdempotent on
billing.payer_contractOne contract per payer anchored to the tenant's billing entity (e.g., UHC-BH-2026, effective from 2026-01-01).(payer_id, billing_entity_id, contract_number)
billing.fee_scheduleOne contract-owned schedule per contract (<SHORT> BH outpatient schedule). CodeResolver prefers this over catalogue.Schedule name
billing.fee_schedule_entryThree BH-friendly codes per schedule: H0004, 99213, 90837. Rates diverge per payer.(schedule_id, procedure_code)
config.payer_program_configOne row per payer with the right auth_workflow, billing_npi_type, timely_filing_days.(payer_id, canonical_program_id, effective_from)
PayerAuth workflowBilling NPITFD
UnitedHealthcarePORTALGROUP90
AnthemPORTALGROUP120
AetnaPORTALGROUP120
CignaEDI_278GROUP90
HumanaMANUALINDIVIDUAL180

Run the seed

Two invocation paths:

# Path A — Knex seed runner. Auto-discovers org / billing entity /
# canonical program; skips gracefully when any anchor is absent.
SEED_COMMERCIAL_PAYERS=1 \
DATABASE_URL=postgres://user:pw@host:5432/tenant_acme \
pnpm --filter @rcm/database seed:tenant
// Path B — direct programmatic call from provisioning scripts or tests
import { seedCommercialPayerTenant } from '@rcm/database/seeds/tenant/001_rm12_commercial_payers';

await seedCommercialPayerTenant({
db: tenantKnex,
billingEntityId: '<group-NPI billing entity>',
canonicalProgramId: '<BH outpatient canonical program>',
effectiveFrom: '2026-01-01',
});

The Knex path is a no-op unless SEED_COMMERCIAL_PAYERS=1 is set — the env var keeps the seed file from firing in environments that don't want the commercial roster (e.g., a Medicaid-only tenant).

Smoke-test after onboarding

-- Five commercial contracts, one per payer
SELECT p.short_name, c.contract_number, c.effective_from
FROM billing.payer_contract c
JOIN rcm_master.payer p ON p.payer_id = c.payer_id
WHERE p.payer_type = 'COMMERCIAL'
ORDER BY p.short_name;

-- Contract-tier resolution should win against catalogue fallbacks
SELECT fs.name, fs.contract_id IS NOT NULL AS is_contract,
e.procedure_code, e.rate_amount_cents
FROM billing.fee_schedule fs
JOIN billing.fee_schedule_entry e
ON e.fee_schedule_id = fs.fee_schedule_id
WHERE fs.name LIKE '%BH outpatient schedule'
ORDER BY fs.name, e.procedure_code;

Then run a single pricing call through CodeResolver.resolveCodes against a UHC charge for H0004 and confirm rate_source_ref begins with CONTRACT: — that's the end-to-end proof that the contract tier is lit up.

Add a new commercial payer to the seed

  1. Add the payer to rcm_master.payer (and payer_submission_capability) via a new master migration — follow the pattern in 043_seed_commercial_payers.ts.

  2. Add a roster entry to packages/database/src/seeds/tenant/001_rm12_commercial_payers.ts with the negotiated rates and auth workflow.

  3. Re-run the seed against each tenant that bills the new payer. The seed is idempotent — existing UHC / Anthem / Aetna / Cigna / Humana rows are left alone.

  4. If the payer needs payer-scoped modifier overrides, add them to a new master migration alongside 045_seed_commercial_modifier_rules.ts. See Payer-scoped modifier overrides.

Validation

CheckExpected
Five commercial contracts, one per payerYes
Each contract has a fee schedule with three entriesYes
payer_program_config.auth_workflow matches the table aboveYes
Pricing call for UHC H0004rate_source_ref starts with CONTRACT:

Regression guardrail

tests/integration-pg/src/rm12-s05-commercial-vs-medicaid-diff.int.test.ts bills the same H0004 service under Ohio Medicaid vs UHC and asserts every RM-12 branch fires on the correct side (contract rate vs state rate, payer-scoped modifier vs state-scoped modifier, 90-day vs 365-day filing window, GROUP NPI rejection, CO-45 COMMERCIAL_CONTRACT tag). A green run is the regression guardrail.

Cross-references

Next

4.5 — Managing fee schedules