feat(npi): wire 6 healthcare services into catalog, intake, items, handlers, portal

This commit is contained in:
justin 2026-06-05 01:25:05 -05:00
parent 8748c0a141
commit e67db156e8
6 changed files with 345 additions and 0 deletions

View file

@ -464,6 +464,48 @@ const COMPLIANCE_SERVICES: Record<
erpnext_item: "ENTITY-UPGRADE-BUNDLE",
discountable: true,
},
// ── Healthcare / NPI compliance ──────────────────────────────────────
// CMS/NPPES provider compliance. Handlers are review-staged (a human
// files in PECOS/NPPES) — same safety default as the FCC auto-filing
// toggle. HIPAA is intentionally out of scope (separate specialty).
// Flagship = npi-revalidation (CMS 5-yr Medicare revalidation, dateable
// overdue signal from the free CMS revalidation list).
"npi-revalidation": {
name: "Medicare PECOS Revalidation Filing",
price_cents: 39900,
erpnext_item: "NPI-REVALIDATION",
discountable: true,
},
"npi-reactivation": {
name: "NPI Reactivation",
price_cents: 24900,
erpnext_item: "NPI-REACTIVATION",
discountable: true,
},
"nppes-update": {
name: "NPPES Data Update / Attestation",
price_cents: 14900,
erpnext_item: "NPPES-UPDATE",
discountable: true,
},
"medicare-enrollment": {
name: "Medicare Enrollment (PECOS)",
price_cents: 49900,
erpnext_item: "MEDICARE-ENROLLMENT",
discountable: true,
},
"oig-sam-screening": {
name: "OIG/SAM Exclusion Screening (Annual)",
price_cents: 9900,
erpnext_item: "OIG-SAM-SCREENING",
discountable: false,
},
"provider-compliance-bundle": {
name: "Provider Compliance Bundle (Annual)",
price_cents: 69900,
erpnext_item: "PROVIDER-COMPLIANCE-BUNDLE",
discountable: true,
},
};
// ── Intake validation map ─────────────────────────────────────────────
@ -643,6 +685,14 @@ const REQUIRED_FIELDS: Record<string, FieldSpec> = {
// ── Hazmat / Emissions ───────────────────────────────────────────────
"hazmat-phmsa": { required: ["dot_number", "legal_name", "email", "hazmat_classes"], soft: ["bulk_packaging", "small_business", "ein"] },
"state-emissions": { required: ["dot_number", "legal_name", "base_state", "email"], soft: ["engine_model_years", "power_units"] },
// ── Healthcare / NPI ─────────────────────────────────────────────────
"npi-revalidation": { required: ["npi", "provider_name", "email"], soft: ["pecos_enrollment_id", "specialty", "practice_state"] },
"npi-reactivation": { required: ["npi", "provider_name", "email"], soft: ["deactivation_reason", "specialty"] },
"nppes-update": { required: ["npi", "provider_name", "email"], soft: ["fields_to_update", "practice_state"] },
"medicare-enrollment": { required: ["npi", "provider_name", "email", "practice_state"], soft: ["pecos_enrollment_id", "specialty", "entity_type"] },
"oig-sam-screening": { required: ["npi", "provider_name", "email"], soft: ["organization_name", "staff_count"] },
"provider-compliance-bundle": { required: ["npi", "provider_name", "email"], soft: ["pecos_enrollment_id", "specialty", "practice_state"] },
};
// ── Bundle composition + incompatibility (single source of truth) ──────────

View file

@ -58,5 +58,77 @@
"include_item_in_manufacturing": 0,
"standard_rate": 0.0,
"currency": "USD"
},
{
"doctype": "Item",
"item_code": "NPI-REVALIDATION",
"item_name": "Medicare PECOS Revalidation Filing",
"description": "Prepare and file the provider's Medicare revalidation in PECOS (5-year cycle).",
"item_group": "Services",
"stock_uom": "Nos",
"is_stock_item": 0,
"include_item_in_manufacturing": 0,
"standard_rate": 399.0,
"currency": "USD"
},
{
"doctype": "Item",
"item_code": "NPI-REACTIVATION",
"item_name": "NPI Reactivation",
"description": "Reactivate a deactivated NPI in NPPES and re-certify the provider record.",
"item_group": "Services",
"stock_uom": "Nos",
"is_stock_item": 0,
"include_item_in_manufacturing": 0,
"standard_rate": 249.0,
"currency": "USD"
},
{
"doctype": "Item",
"item_code": "NPPES-UPDATE",
"item_name": "NPPES Data Update / Attestation",
"description": "Update and re-attest a provider's NPPES record (CMS requires updates within 30 days of changes).",
"item_group": "Services",
"stock_uom": "Nos",
"is_stock_item": 0,
"include_item_in_manufacturing": 0,
"standard_rate": 149.0,
"currency": "USD"
},
{
"doctype": "Item",
"item_code": "MEDICARE-ENROLLMENT",
"item_name": "Medicare Enrollment (PECOS)",
"description": "Complete a provider's Medicare enrollment via PECOS (CMS-855).",
"item_group": "Services",
"stock_uom": "Nos",
"is_stock_item": 0,
"include_item_in_manufacturing": 0,
"standard_rate": 499.0,
"currency": "USD"
},
{
"doctype": "Item",
"item_code": "OIG-SAM-SCREENING",
"item_name": "OIG/SAM Exclusion Screening (Annual)",
"description": "Annual OIG LEIE + SAM exclusion screening for a provider and listed staff, with certificate.",
"item_group": "Services",
"stock_uom": "Nos",
"is_stock_item": 0,
"include_item_in_manufacturing": 0,
"standard_rate": 99.0,
"currency": "USD"
},
{
"doctype": "Item",
"item_code": "PROVIDER-COMPLIANCE-BUNDLE",
"item_name": "Provider Compliance Bundle (Annual)",
"description": "Annual provider compliance bundle: revalidation watch, OIG/SAM screening, and NPPES upkeep.",
"item_group": "Services",
"stock_uom": "Nos",
"is_stock_item": 0,
"include_item_in_manufacturing": 0,
"standard_rate": 699.0,
"currency": "USD"
}
]

View file

@ -27,6 +27,13 @@ COMPLIANCE_SERVICE_LABELS = {
"stir-shaken": "STIR/SHAKEN Implementation Assistance",
"dc-agent": "D.C. Registered Agent (Annual)",
"bdc-filing": "BDC / Form 477 Filing",
# Healthcare / NPI
"npi-revalidation": "Medicare PECOS Revalidation Filing",
"npi-reactivation": "NPI Reactivation",
"nppes-update": "NPPES Data Update / Attestation",
"medicare-enrollment": "Medicare Enrollment (PECOS)",
"oig-sam-screening": "OIG/SAM Exclusion Screening (Annual)",
"provider-compliance-bundle": "Provider Compliance Bundle (Annual)",
}
# Map the per-filing timestamp columns on telecom_entities → the slugs that

View file

@ -58,6 +58,15 @@ from .mailbox_setup import MailboxSetupHandler
from .carrier_closeout import CarrierCloseoutHandler
# PHMSA hazmat registration (admin-assisted, 49 CFR Part 107)
from .hazmat_phmsa import HazmatPHMSAHandler
# Healthcare / NPI provider compliance (review-staged PECOS/NPPES filings)
from .npi_provider import (
NPIRevalidationHandler,
NPIReactivationHandler,
NPPESUpdateHandler,
MedicareEnrollmentHandler,
OIGSAMScreeningHandler,
ProviderComplianceBundleHandler,
)
SERVICE_HANDLERS: dict[str, type] = {
"flsa-audit": FLSAAuditHandler,
@ -141,6 +150,13 @@ SERVICE_HANDLERS: dict[str, type] = {
"hazmat-phmsa": HazmatPHMSAHandler,
# ── State emissions / clean-truck (admin-assisted) ────────────────
"state-emissions": StateTruckingHandler,
# ── Healthcare / NPI (review-staged) ──────────────────────────────
"npi-revalidation": NPIRevalidationHandler,
"npi-reactivation": NPIReactivationHandler,
"nppes-update": NPPESUpdateHandler,
"medicare-enrollment": MedicareEnrollmentHandler,
"oig-sam-screening": OIGSAMScreeningHandler,
"provider-compliance-bundle": ProviderComplianceBundleHandler,
}
# Service slugs that operate on a telecom entity — used by job_server.py

View file

@ -0,0 +1,184 @@
"""Healthcare / NPI provider compliance handlers.
Review-staged: each NPI service generates an admin todo with the provider's
NPI + intake details for a human to file in CMS PECOS / NPPES. This mirrors the
FCC auto-filing-off safety default no automated submission to government
portals until the Playwright flows are proven.
Covers slugs:
npi-revalidation Medicare PECOS revalidation (5-yr cycle)
npi-reactivation reactivate a deactivated NPI
nppes-update NPPES data update / attestation
medicare-enrollment new Medicare enrollment via PECOS
oig-sam-screening OIG LEIE + SAM exclusion screening (annual)
provider-compliance-bundle revalidation watch + screening + NPPES upkeep
Intake data needed (collected by the npi-intake wizard step):
- npi provider's 10-digit NPI
- provider_name legal/provider name
- email contact email
- pecos_enrollment_id (optional) PECOS enrollment ID
- specialty (optional) taxonomy/specialty
- practice_state (optional) practice location state
"""
from __future__ import annotations
import json
import logging
import os
LOG = logging.getLogger("workers.services.npi_provider")
# Per-slug admin todo metadata: human-readable action + the portal a human uses.
_SLUG_META = {
"npi-revalidation": {
"name": "Medicare PECOS Revalidation Filing",
"portal": "https://pecos.cms.hhs.gov/",
"action": (
"File the Medicare revalidation in PECOS for this provider. Confirm "
"the revalidation due date on the CMS revalidation list, update the "
"enrollment record, and submit. Capture the PECOS tracking ID."
),
"priority": "high",
},
"npi-reactivation": {
"name": "NPI Reactivation",
"portal": "https://nppes.cms.hhs.gov/",
"action": (
"Reactivate the deactivated NPI in NPPES. Verify the deactivation "
"reason, correct any stale data, and re-certify the record."
),
"priority": "high",
},
"nppes-update": {
"name": "NPPES Data Update / Attestation",
"portal": "https://nppes.cms.hhs.gov/",
"action": (
"Update + re-attest the provider's NPPES record (CMS requires "
"updates within 30 days of any change). Apply the requested field "
"changes and certify."
),
"priority": "normal",
},
"medicare-enrollment": {
"name": "Medicare Enrollment (PECOS)",
"portal": "https://pecos.cms.hhs.gov/",
"action": (
"Complete the provider's Medicare enrollment in PECOS (CMS-855). "
"Confirm taxonomy, practice location, and authorized official."
),
"priority": "high",
},
"oig-sam-screening": {
"name": "OIG/SAM Exclusion Screening (Annual)",
"portal": "https://oig.hhs.gov/exclusions/ + https://sam.gov/",
"action": (
"Run the provider (and any listed staff) against the OIG LEIE and "
"SAM exclusion lists. Produce the screening certificate and flag any "
"matches for escalation."
),
"priority": "normal",
},
"provider-compliance-bundle": {
"name": "Provider Compliance Bundle (Annual)",
"portal": "https://pecos.cms.hhs.gov/ + https://nppes.cms.hhs.gov/",
"action": (
"Onboard the provider into the annual compliance bundle: enroll in "
"revalidation watch, run OIG/SAM screening, and refresh the NPPES "
"record. Set the next revalidation reminder."
),
"priority": "high",
},
}
class _BaseNPIHandler:
"""Shared review-staged behaviour for all NPI services."""
SERVICE_SLUG = ""
async def process(self, order_data: dict) -> list[str]:
order_number = order_data.get("order_number", order_data.get("name", ""))
return await self.handle(order_data, order_number)
async def handle(self, order_data: dict, order_number: str) -> list[str]:
meta = _SLUG_META[self.SERVICE_SLUG]
LOG.info("[%s] Processing %s", order_number, self.SERVICE_SLUG)
intake = order_data.get("intake_data") or {}
if isinstance(intake, str):
intake = json.loads(intake)
npi = intake.get("npi", "N/A")
provider = intake.get("provider_name", order_data.get("customer_name", "Unknown"))
specialty = intake.get("specialty", "")
practice_state = intake.get("practice_state", "")
pecos_id = intake.get("pecos_enrollment_id", "")
description = (
f"{meta['action']}\n\n"
f"Provider: {provider}\n"
f"NPI: {npi}\n"
f"PECOS Enrollment ID: {pecos_id or 'not provided'}\n"
f"Specialty: {specialty or 'not provided'}\n"
f"Practice state: {practice_state or 'not provided'}\n"
f"Portal: {meta['portal']}\n\n"
f"Review-staged: file manually, then mark this order complete."
)
self._create_todo(
order_number,
intake,
title=f"{meta['name']}{provider} (NPI {npi})",
description=description,
priority=meta["priority"],
)
return []
def _create_todo(self, order_number, intake, title, description, priority="normal"):
try:
import psycopg2
conn = psycopg2.connect(os.environ.get("DATABASE_URL", ""))
with conn.cursor() as cur:
cur.execute(
"""
INSERT INTO admin_todos (
title, category, priority, order_number, service_slug,
description, data, status
) VALUES (%s, %s, %s, %s, %s, %s, %s, 'pending')
""",
(
title, "filing", priority, order_number,
self.SERVICE_SLUG, description, json.dumps(intake),
),
)
conn.commit()
conn.close()
except Exception as exc:
LOG.error("[%s] Failed to create NPI todo: %s", order_number, exc)
class NPIRevalidationHandler(_BaseNPIHandler):
SERVICE_SLUG = "npi-revalidation"
class NPIReactivationHandler(_BaseNPIHandler):
SERVICE_SLUG = "npi-reactivation"
class NPPESUpdateHandler(_BaseNPIHandler):
SERVICE_SLUG = "nppes-update"
class MedicareEnrollmentHandler(_BaseNPIHandler):
SERVICE_SLUG = "medicare-enrollment"
class OIGSAMScreeningHandler(_BaseNPIHandler):
SERVICE_SLUG = "oig-sam-screening"
class ProviderComplianceBundleHandler(_BaseNPIHandler):
SERVICE_SLUG = "provider-compliance-bundle"

View file

@ -38,6 +38,7 @@ export type IntakeStep =
| "mcs150" // MCS-150 biennial update form fields (standalone)
| "dot-intake" // Unified DOT intake — shows sections based on services ordered
| "state-trucking" // State-level trucking + hazmat/emissions intake (slug-gated sections)
| "npi-intake" // Healthcare / NPI provider intake (NPI, PECOS, practice)
| "review"
| "payment";
@ -143,6 +144,14 @@ export const INTAKE_MANIFEST: Record<string, IntakeStep[]> = {
// ── Entity / Corporate Upgrade ─────────────────────────────────────
"entity-upgrade-bundle": ["dot-intake", "review", "payment"],
// ── Healthcare / NPI ───────────────────────────────────────────────
"npi-revalidation": ["npi-intake", "review", "payment"],
"npi-reactivation": ["npi-intake", "review", "payment"],
"nppes-update": ["npi-intake", "review", "payment"],
"medicare-enrollment": ["npi-intake", "review", "payment"],
"oig-sam-screening": ["npi-intake", "review", "payment"],
"provider-compliance-bundle": ["npi-intake", "review", "payment"],
};
// Category-gated dynamic steps. The Wizard inserts these after the `category`
@ -204,6 +213,13 @@ export const SERVICE_META: Record<string, { name: string; price_cents: number; g
// Hazmat / emissions
"hazmat-phmsa": { name: "PHMSA Hazmat Registration", price_cents: 14900, gov_fee_label: "PHMSA registration fee, by business size" },
"state-emissions": { name: "State Clean-Truck / Emissions Compliance", price_cents: 10900 },
// Healthcare / NPI
"npi-revalidation": { name: "Medicare PECOS Revalidation Filing", price_cents: 39900 },
"npi-reactivation": { name: "NPI Reactivation", price_cents: 24900 },
"nppes-update": { name: "NPPES Data Update / Attestation", price_cents: 14900 },
"medicare-enrollment": { name: "Medicare Enrollment (PECOS)", price_cents: 49900 },
"oig-sam-screening": { name: "OIG/SAM Exclusion Screening (Annual)", price_cents: 9900 },
"provider-compliance-bundle": { name: "Provider Compliance Bundle (Annual)", price_cents: 69900 },
};
export function formatUSD(cents: number): string {