healthcare: two-tier (standard paper / expedited surrogate) filing model
- Verified Standard(no-login)/Expedited(surrogate) matrix from official CMS-855 PDFs (docs/healthcare-filing-tiers-verified.md): reactivation+revalidation are 855I paper-to-MAC reasons, original-signature, routed by state; sig may not be delegated; 855B needs PECOS app fee. - Add scripts/workers/mac_routing.py: state->MAC routing (all 56 jurisdictions, 12 destinations) for envelope addressing + daily batch grouping. Addresses marked VERIFY before live mail. - npi_provider.py: fix access strings to two-tier framing; NPPES update/reactivation no longer 'online-only'; note 855B fee. - checkout.ts + service pages: strip client-facing mechanics & the paper-vs-tier choice; surrogate is the only optional, positively-framed ask (faster, never required, never share password).
This commit is contained in:
parent
74c1259c9a
commit
258d23bdc6
7 changed files with 417 additions and 289 deletions
|
|
@ -2152,49 +2152,35 @@ export async function sendComplianceIntakeEmail(
|
||||||
</p>
|
</p>
|
||||||
</div>` : "";
|
</div>` : "";
|
||||||
|
|
||||||
// CMS filing-method section for PECOS / NPPES orders. We offer two service
|
// CMS filing for PECOS / NPPES orders. We file everything for the provider;
|
||||||
// tiers and let the provider pick the one that's easiest for them:
|
// the ONLY client-facing choice is the optional surrogate question, framed
|
||||||
// (1) Standard filing — they review + sign one certification, we submit to
|
// positively. We NEVER expose the mechanics (paper, CMS-855/10114, MAC, Fargo)
|
||||||
// their MAC. Zero account setup. Default for reval/enrollment.
|
// and we NEVER tell them "the alternative is paper". If they grant I&A
|
||||||
// (2) Expedited filing — faster/same-day-trackable via CMS I&A surrogate access.
|
// Surrogate access we file online same-day; if not, we file it for them via our
|
||||||
// NPPES-only services (reactivation, update) are web-only, so surrogate access
|
// Standard path silently. Same price either way — surrogate is just faster for
|
||||||
// is the only path for those. We never ask for the provider's password.
|
// us (fewer steps, lets us bulk-file). We never ask for their password.
|
||||||
const npiConfirmUrl = `${SITE_DOMAIN}/order/success?action=ia_surrogacy&order_id=${orderId}`;
|
const npiConfirmUrl = `${SITE_DOMAIN}/order/success?action=ia_surrogacy&order_id=${orderId}`;
|
||||||
// Which ordered services support the standard (no-account) filing path
|
|
||||||
// vs. are NPPES-web-only (surrogate access required).
|
|
||||||
const STANDARD_FILING_SLUGS = new Set<string>(["npi-revalidation", "medicare-enrollment", "provider-compliance-bundle"]);
|
|
||||||
const NPPES_ONLY_SLUGS = new Set<string>(["npi-reactivation", "nppes-update"]);
|
|
||||||
const hasStandardFiling = npiAccessOrders.some(o => STANDARD_FILING_SLUGS.has(o.service_slug as string));
|
|
||||||
const hasNppesOnly = npiAccessOrders.some(o => NPPES_ONLY_SLUGS.has(o.service_slug as string));
|
|
||||||
|
|
||||||
const standardFilingBlock = hasStandardFiling ? `
|
|
||||||
<p style="margin:0 0 6px;font-size:13px;font-weight:700;color:#115e59;">Standard filing — no account needed</p>
|
|
||||||
<p style="margin:0 0 12px;font-size:13px;color:#134e4a;line-height:1.5;">
|
|
||||||
We complete the correct CMS-855 for you. You review and sign the certification
|
|
||||||
from a secure link we send (takes about a minute), and we submit it to your
|
|
||||||
Medicare Administrative Contractor (MAC) and track it to confirmation. Nothing
|
|
||||||
for you to set up.
|
|
||||||
</p>` : "";
|
|
||||||
|
|
||||||
const surrogacyHeading = hasStandardFiling
|
|
||||||
? `Expedited filing — CMS I&A surrogate access`
|
|
||||||
: `Grant CMS I&A surrogate access`;
|
|
||||||
|
|
||||||
const npiSection = hasNpiAccess ? `
|
const npiSection = hasNpiAccess ? `
|
||||||
<div style="background:#ccfbf1;border:1px solid #5eead4;border-radius:8px;padding:16px 20px;margin:20px 0;">
|
<div style="background:#ccfbf1;border:1px solid #5eead4;border-radius:8px;padding:16px 20px;margin:20px 0;">
|
||||||
<p style="margin:0 0 10px;font-size:14px;font-weight:700;color:#115e59;">Action Required: Choose How We File</p>
|
<p style="margin:0 0 10px;font-size:14px;font-weight:700;color:#115e59;">We're handling your filing</p>
|
||||||
${standardFilingBlock}
|
|
||||||
<p style="margin:0 0 6px;font-size:13px;font-weight:700;color:#115e59;">${surrogacyHeading}</p>
|
|
||||||
<p style="margin:0 0 12px;font-size:13px;color:#134e4a;line-height:1.5;">
|
<p style="margin:0 0 12px;font-size:13px;color:#134e4a;line-height:1.5;">
|
||||||
${hasNppesOnly ? "NPPES updates and reactivations are online-only, so this is required for those. " : ""}You add us as a
|
You're all set — we prepare and submit your filing and track it to
|
||||||
<strong>Surrogate</strong> in CMS Identity & Access (I&A) — you never share your password.
|
confirmation. The only thing we may need from you is a quick signature on
|
||||||
We then file in PECOS / NPPES under our own credentials and capture the tracking ID the same day.
|
a secure link we'll send. Nothing to set up.
|
||||||
|
</p>
|
||||||
|
<p style="margin:0 0 6px;font-size:13px;font-weight:700;color:#115e59;">Optional: speed it up</p>
|
||||||
|
<p style="margin:0 0 12px;font-size:13px;color:#134e4a;line-height:1.5;">
|
||||||
|
If you can <strong>electronically grant us CMS I&A Surrogate access</strong>,
|
||||||
|
we can file faster — it cuts steps on our end and lets us process your
|
||||||
|
filing right away. You never share your password; you simply authorize us
|
||||||
|
as a Surrogate for your NPI.
|
||||||
</p>
|
</p>
|
||||||
<ol style="margin:0 0 12px;padding-left:20px;font-size:13px;color:#134e4a;line-height:1.7;">
|
<ol style="margin:0 0 12px;padding-left:20px;font-size:13px;color:#134e4a;line-height:1.7;">
|
||||||
<li>Log in to <a href="https://nppes.cms.hhs.gov/IAWeb/login.do" style="color:#0f766e;">CMS I&A (I&A System)</a></li>
|
<li>Log in to <a href="https://nppes.cms.hhs.gov/IAWeb/login.do" style="color:#0f766e;">CMS Identity & Access (I&A)</a></li>
|
||||||
<li>Go to <strong>My Connections → Add Surrogate</strong></li>
|
<li>Go to <strong>My Connections → Add Surrogate</strong></li>
|
||||||
<li>Add surrogate organization: <strong>Performance West Inc.</strong> (email <strong>filings@performancewest.net</strong>)</li>
|
<li>Add surrogate organization: <strong>Performance West Inc.</strong> (email <strong>filings@performancewest.net</strong>)</li>
|
||||||
<li>Grant access to <strong>PECOS</strong> and <strong>NPPES</strong> for your NPI, then approve our request</li>
|
<li>Grant access for your NPI, then approve our request</li>
|
||||||
</ol>
|
</ol>
|
||||||
<p style="margin:12px 0;text-align:center;">
|
<p style="margin:12px 0;text-align:center;">
|
||||||
<a href="${npiConfirmUrl}" style="display:inline-block;background:#0f766e;color:#ffffff;font-weight:700;padding:12px 28px;border-radius:8px;text-decoration:none;font-size:14px;">
|
<a href="${npiConfirmUrl}" style="display:inline-block;background:#0f766e;color:#ffffff;font-weight:700;padding:12px 28px;border-radius:8px;text-decoration:none;font-size:14px;">
|
||||||
|
|
@ -2202,7 +2188,8 @@ export async function sendComplianceIntakeEmail(
|
||||||
</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<p style="margin:8px 0 0;font-size:12px;color:#115e59;text-align:center;">
|
<p style="margin:8px 0 0;font-size:12px;color:#115e59;text-align:center;">
|
||||||
${hasStandardFiling ? "Prefer standard filing? Just reply to this email and we'll send your CMS-855 to sign — no further action needed from you here." : "Clicking this notifies our team so we can begin your filing."}
|
Can't do this step? No problem — we'll handle your filing without it.
|
||||||
|
There's nothing else you need to do.
|
||||||
</p>
|
</p>
|
||||||
</div>` : "";
|
</div>` : "";
|
||||||
|
|
||||||
|
|
|
||||||
99
docs/healthcare-filing-tiers-verified.md
Normal file
99
docs/healthcare-filing-tiers-verified.md
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
# Healthcare filing: Standard (no-login) vs Expedited (surrogate) — VERIFIED matrix
|
||||||
|
|
||||||
|
Internal capability map. Confirms how each healthcare service is fulfilled with
|
||||||
|
**no client login and no credential sharing**, and where the optional
|
||||||
|
**Expedited (CMS I&A Surrogate)** path applies.
|
||||||
|
|
||||||
|
> **Client-facing rule (do not break):** never expose mechanics to the client.
|
||||||
|
> No "paper", "CMS-855", "CMS-10114", "MAC", "Fargo", or form numbers in any
|
||||||
|
> client copy. The only client-visible choice is the positive surrogate question
|
||||||
|
> ("electronically granting us I&A Surrogate access lets us bulk-file faster /
|
||||||
|
> fewer steps on our end"). Declining is silent; we just "file it for you."
|
||||||
|
> Same price either way — Expedited is NOT a paid tier.
|
||||||
|
|
||||||
|
## Two service tiers (internal)
|
||||||
|
- **Standard (default):** we complete the official form, client signs ONE
|
||||||
|
certification (e-sign link), we submit + track. For CMS-855s the signed form is
|
||||||
|
mailed to the provider's MAC; for NPPES-only changes via the NPI Enumerator
|
||||||
|
paper path. Daily batched mailing (see §Daily batch).
|
||||||
|
- **Expedited (if client grants I&A Surrogate):** we file online in PECOS/NPPES
|
||||||
|
under our own login (surrogate), same-day tracking. Surrogacy is a delegation,
|
||||||
|
NOT a password handover.
|
||||||
|
|
||||||
|
## VERIFIED from the official CMS form PDFs in `docs/` (primary source)
|
||||||
|
|
||||||
|
### CMS-855I (05/23) — individual practitioner [CONFIRMED, quoted]
|
||||||
|
- Valid reasons include: **revalidation**, **reactivation** ("reactivate your
|
||||||
|
Medicare billing number to resume billing"), **changes to enrollment info**,
|
||||||
|
and enrolling with another MAC. → revalidation/reactivation/enrollment all
|
||||||
|
ride the 855I paper path.
|
||||||
|
- Paper submission: *"Send this completed application with **original signatures**
|
||||||
|
and all required documentation to your **designated MAC**. The MAC that services
|
||||||
|
your State is responsible for processing your enrollment application."*
|
||||||
|
→ **no login required; routed by STATE.**
|
||||||
|
- Signature caveat: *"As an individual practitioner, you are the only person who
|
||||||
|
can sign this application. The authority to sign the application on your behalf
|
||||||
|
**may not be delegated** to any other person."* → client must personally sign
|
||||||
|
(pen/e-sign), but that is NOT a login. A surrogate **cannot** sign the 855 for
|
||||||
|
them — surrogacy speeds the *online filing*, the cert signature is still theirs.
|
||||||
|
|
||||||
|
### CMS-855B (12/2025) — clinic/group/supplier [CONFIRMED, quoted]
|
||||||
|
- Same paper-to-MAC, original-signatures, routed-by-State rule.
|
||||||
|
- Org signer: a **delegated/authorized official** signs §15B/15D (not the
|
||||||
|
individual) — still a signature, no login.
|
||||||
|
- **Application FEE** required (paid via PECOS feePaymentWelcome) on initial
|
||||||
|
enrollment, new location, and revalidation BEFORE mailing. → org standard path
|
||||||
|
has a fee-payment step we must handle/route; individual 855I does not.
|
||||||
|
|
||||||
|
### CMS-855O (09/23) — ordering/referring only [CONFIRMED, quoted]
|
||||||
|
- Paper-to-MAC, original signatures, routed by state. "Sign and date section 8
|
||||||
|
using ink."
|
||||||
|
|
||||||
|
### NPPES data update / NPI reactivation (CMS-10114 paper path) [PARTIAL]
|
||||||
|
- 855I confirms NPI is obtained/changed via NPPES and "you may apply **online** at
|
||||||
|
NPPES.cms.hhs.gov" — implies the online path; the paper CMS-10114 to the NPI
|
||||||
|
Enumerator (PO Box 6059, Fargo ND 58108-6059) is the documented paper
|
||||||
|
alternative per the existing `healthcare-no-login-value-add.md` (NPI Enumerator
|
||||||
|
800-465-3203).
|
||||||
|
- **UNCERTAIN (verify before relying on it as the sole standard path):** whether
|
||||||
|
CMS still accepts paper CMS-10114 for *updates/reactivation* (vs initial
|
||||||
|
enumeration only) today. Could not reach the live CMS-10114 instruction from
|
||||||
|
this host (search engines blocked, direct URLs 404).
|
||||||
|
- **Decision:** for NPPES-only services, offer Expedited (surrogate → file in
|
||||||
|
NPPES online) as the primary fast path, and the CMS-10114 paper path as the
|
||||||
|
Standard fallback. Confirm the CMS-10114-for-changes acceptance + obtain the
|
||||||
|
current form PDF before building `cms10114_pdf_filler.py`. Until confirmed, the
|
||||||
|
honest Standard fallback for a declined-surrogate NPPES update may be "we
|
||||||
|
prepare it and guide the one-step online submission" — TBD on verification.
|
||||||
|
|
||||||
|
## CMS I&A Surrogate (Expedited path)
|
||||||
|
- Provider adds Performance West as a **Surrogate** in CMS I&A; we then file in
|
||||||
|
PECOS/NPPES under our own credentials. No password shared.
|
||||||
|
- Scope nuance to verify in copy: confirm a single surrogacy grant covers the
|
||||||
|
PECOS and NPPES functions we need (the checkout copy currently asks for both).
|
||||||
|
|
||||||
|
## Per-service tier table
|
||||||
|
| Service | Standard (no-login) | Expedited (surrogate) | Fee? |
|
||||||
|
|---|---|---|---|
|
||||||
|
| Medicare revalidation | 855I/B → MAC, client signs | file in PECOS | 855B yes |
|
||||||
|
| Medicare enrollment | 855I/B/O → MAC, client signs | file in PECOS | 855B yes |
|
||||||
|
| NPI reactivation | 855I → MAC (reactivation reason) | PECOS/NPPES | no |
|
||||||
|
| NPPES data update | CMS-10114 → Fargo *(verify)* | NPPES online | no |
|
||||||
|
| OIG/SAM screening | public DBs, **zero client action** | n/a (no portal) | no |
|
||||||
|
| Provider compliance bundle | spawns reval + screening + NPPES | mixed | per-piece |
|
||||||
|
|
||||||
|
## Daily batch (Standard-path mailing)
|
||||||
|
Each **postal working day morning** (skip weekends + USPS/federal holidays — use
|
||||||
|
`scripts/workers/business_days.py` calendar): gather all signed+pending paper
|
||||||
|
filings, **group by destination agency** (each MAC; NPI Enumerator Fargo; each
|
||||||
|
state agency), merge each group into ONE print job + a cover sheet (PW sender,
|
||||||
|
destination, date, enclosed count, per-item order#/provider/NPI/form), one
|
||||||
|
**Priority Mail** envelope per agency. Mark each order mailed with batch date +
|
||||||
|
tracking. Phase 1: generate per-agency batched PDF + cover sheet + manifest for a
|
||||||
|
human to print & drop. Phase 2: wire a print-mail API (Lob/Click2Mail).
|
||||||
|
|
||||||
|
## MAC routing
|
||||||
|
855s route by the provider's **State** (855I/B/O all say "the MAC that services
|
||||||
|
your State"). Mailing addresses: CMS.gov/Medicare/Provider-Enrollment-and-
|
||||||
|
Certification. Need a **state → MAC → mailing-address** table to address envelopes
|
||||||
|
+ to group the daily batch. `practice_state` intake field drives this.
|
||||||
|
|
@ -1,252 +1,164 @@
|
||||||
# Plan
|
# Plan
|
||||||
|
|
||||||
## Status: COMPLETE (all phases implemented + validated 2026-06-02)
|
Offer healthcare regulatory filings as a **two-tier model** (internal mechanics;
|
||||||
|
the "paper" alternative is NEVER surfaced to the client):
|
||||||
|
|
||||||
| Phase | What | Status |
|
- **Standard service (default):** we handle the filing end-to-end. Client signs
|
||||||
|-------|------|--------|
|
ONE certification and we submit + track to confirmation. (Internally this is the
|
||||||
| 1 | Hazmat/PHMSA handler + product (`hazmat-phmsa`, $149) | ✅ |
|
paper path — 855 to the MAC, CMS-10114 to the NPI Enumerator in Fargo — but we
|
||||||
| 1.5 | Order-form bundle/mutual-exclusion enforcement (server-side) | ✅ |
|
never say "paper" to the client; it's just "we file it for you.")
|
||||||
| 2 | State-trucking intake form (slug-gated) + REQUIRED_FIELDS + admin-todo fields | ✅ |
|
- **Expedited (faster, framed positively at intake):** we ask if they can
|
||||||
| 2.5 | BOC-3 authority-aware (active/pending/revoked/none) + upsell-approve follow-ups | ✅ |
|
**electronically grant us CMS I&A Surrogate access**. We position this as
|
||||||
| 2.6 | Pipeline activation gating (`require_active` edges, FMCSA poll, waiting_on_activation) | ✅ |
|
*reducing the number of steps on our end so we can bulk-file faster* — never as
|
||||||
| 3 | State emissions (non-CA) product `state-emissions` ($199) | ✅ |
|
"the alternative is paper." If yes, we file online same-day. If no, we silently
|
||||||
| 4 | Order landing pages for all state/hazmat/emissions slugs (48 pages build) | ✅ |
|
fall back to Standard. Same price either way; surrogacy is a delegation, not
|
||||||
| Adv | Prerequisite-aware DOT lookup + state recommendations | ✅ |
|
password sharing.
|
||||||
| 5 | Campaign builder deficiency segments + LP routing + --list-segments | ✅ |
|
|
||||||
| Val | Consistency checker (24/24) + campaign segment test (synthetic) | ✅ |
|
|
||||||
|
|
||||||
**Remaining ops (not code):** create the 6 Listmonk source-campaign templates and
|
This pass verifies the no-login paper path per service, reconciles the doc/code
|
||||||
set their `CAMPAIGN_*_ID` envs (`CAMPAIGN_FOR_HIRE_ID`, `CAMPAIGN_IRP_IFTA_ID`,
|
contradiction, and makes "standard = paper / expedited = surrogate" consistent
|
||||||
`CAMPAIGN_INTRASTATE_ID`, `CAMPAIGN_WEIGHT_TAX_ID`, `CAMPAIGN_EMISSIONS_ID`,
|
everywhere it's surfaced.
|
||||||
`CAMPAIGN_HAZMAT_ID`). Until set, those segments are reported by
|
|
||||||
`--list-segments` but skipped by the scheduled run. Optional follow-up: a
|
|
||||||
client-side incompatibility UX hint in the order form (server already enforces).
|
|
||||||
|
|
||||||
## Goal
|
## Goal
|
||||||
|
Every healthcare service (federal sold + state/adjacent to add) has a verified
|
||||||
Make every trucker deficiency type we flag actually *fulfillable*: each flagged
|
**Standard (paper, no-login)** path and, where a CMS/portal exists, an
|
||||||
deficiency must have (1) a service handler that can complete the work, (2) a
|
**Expedited (surrogate/delegated)** upsell. No surface should ever present
|
||||||
checkout/order path, and (3) an intake form that collects **all** information
|
surrogate as *required* when a paper path exists; paper is always the default.
|
||||||
that handler needs before the job runs. Only after fulfillment is complete and
|
|
||||||
verified do we extend the campaign builder to email those deficiency segments.
|
|
||||||
|
|
||||||
## Scope / affected areas
|
## Scope / affected areas
|
||||||
|
- `api/src/routes/checkout.ts` (~L2155-2207) — already has the two-tier copy, BUT
|
||||||
|
treats NPPES update/reactivation as **"online-only, surrogate required"** with
|
||||||
|
NO standard fallback (`NPPES_ONLY_SLUGS`, `hasNppesOnly`). The directive says:
|
||||||
|
give those a Standard paper path too (CMS-10114 to Fargo) and make surrogate the
|
||||||
|
*expedited* option, not the only option.
|
||||||
|
- `scripts/workers/services/npi_provider.py` — `access` strings call NPPES
|
||||||
|
update/reactivation "NPPES via CMS I&A surrogate access (online-only)". Must
|
||||||
|
become "Standard: CMS-10114 paper to NPI Enumerator (Fargo), client signs;
|
||||||
|
Expedited: NPPES via I&A surrogate." Also `_STANDARD_FILING_SLUGS` currently
|
||||||
|
excludes `nppes-update` (it has no 855) — needs a CMS-10114 paper path instead.
|
||||||
|
- `scripts/document_gen/templates/cms855_pdf_filler.py` — working 855 paper path
|
||||||
|
(fills 855I/B/O/A + cert-page signature anchor). **Gap:** no CMS-10114 filler
|
||||||
|
for the NPPES standard path → likely a small new `cms10114_pdf_filler.py`.
|
||||||
|
- `docs/healthcare-no-login-value-add.md` — already documents the CMS-10114 paper
|
||||||
|
path; promote it to the canonical "Standard vs Expedited" matrix.
|
||||||
|
- `site/src/pages/services/healthcare/{npi-revalidation,medicare-enrollment}.astro`
|
||||||
|
— already describe expedited/surrogate; npi-reactivation/nppes-update order
|
||||||
|
pages need the same two-tier framing.
|
||||||
|
- `site/src/components/intake/steps/NpiIntakeStep.astro` + intake manifest — add
|
||||||
|
the surrogate-access question framed positively: "Can you electronically grant
|
||||||
|
us CMS I&A Surrogate access? It lets us bulk-file faster and cuts steps on our
|
||||||
|
end." Optional; declining is fine and never mentions paper. The captured answer
|
||||||
|
routes fulfillment internally (surrogate vs our Standard path).
|
||||||
|
- `docs/state-healthcare-compliance-opportunities.md` + `new-sector-compliance-
|
||||||
|
targets.md` — extend the two-tier classification to state/adjacent services.
|
||||||
|
|
||||||
Deficiency flags in play (live counts):
|
Out of scope this pass: building the actual surrogate Playwright automation
|
||||||
for_hire (19,811), interstate_irp_ifta (19,761), intrastate_authority (14,081),
|
(expedited fulfillment can stay human-in-PECOS for now), email-stream machinery,
|
||||||
state_emissions (12,424), state_weight_tax (6,289), state_permit (3,418),
|
pricing changes.
|
||||||
mcs150_overdue (4,539), hazmat (514), zero_fleet (134).
|
|
||||||
|
|
||||||
Files / systems:
|
|
||||||
- `scripts/workers/services/__init__.py` — handler registry
|
|
||||||
- `scripts/workers/services/state_trucking.py` — IRP/IFTA/weight-tax/permit/intrastate handler (admin-todo only today)
|
|
||||||
- `scripts/workers/services/mcs150_update.py` — MCS-150 + reactivation (real FMCSA filing)
|
|
||||||
- `scripts/workers/services/boc3_filing.py` — BOC-3 (Playwright)
|
|
||||||
- **NEW** `scripts/workers/services/hazmat_phmsa.py` — only fully-missing fulfillment path
|
|
||||||
- `site/src/lib/intake_manifest.ts` — per-service intake steps + pricing/meta
|
|
||||||
- `site/src/components/intake/steps/DOTIntakeStep.astro` — unified DOT intake (no state-trucking sections today)
|
|
||||||
- **NEW** `site/src/components/intake/steps/StateTruckingIntakeStep.astro` — state filing fields
|
|
||||||
- `api/src/routes/compliance-orders.ts` — `COMPLIANCE_SERVICES` (products) + `REQUIRED_FIELDS` (validation; **none defined for any DOT/state-trucking slug today**)
|
|
||||||
- `api/src/routes/checkout.ts` — slug allowlist
|
|
||||||
- `api/src/routes/dot-lookup.ts` — recommended-services mapping
|
|
||||||
- **NEW** `site/src/pages/order/*.astro` — landing pages for state-trucking + hazmat (none exist)
|
|
||||||
- `scripts/build_trucking_campaigns.py` — campaign builder (extend last)
|
|
||||||
|
|
||||||
## Key findings (grounding)
|
|
||||||
|
|
||||||
1. **Fulfillment handlers already exist** for ~98% of flags. The single fully
|
|
||||||
missing path is **hazmat / PHMSA registration** (no handler, product, page).
|
|
||||||
2. **State-trucking intake collects nothing.** All 13 state slugs map to
|
|
||||||
`["review"]` in `intake_manifest.ts` with a comment "info collected at
|
|
||||||
checkout" — but checkout collects no per-filing fields. So IRP has no
|
|
||||||
vehicle/weight/jurisdiction data, IFTA has no fleet/base-state, NY HUT has no
|
|
||||||
vehicle list, intrastate-authority has no insurance/authority-type, etc. The
|
|
||||||
handler's admin todo is therefore incomplete and an admin must chase the
|
|
||||||
customer for data.
|
|
||||||
3. **`REQUIRED_FIELDS` has zero entries** for any DOT or state-trucking slug, so
|
|
||||||
the API performs no intake validation for these orders.
|
|
||||||
4. **No dedicated order landing pages** for IRP/IFTA/state-tax/permit/intrastate
|
|
||||||
or hazmat. Checkout works by slug, but campaign emails have no clean LP to
|
|
||||||
drive conversions.
|
|
||||||
5. **State emissions** flags (NY/CO/MD/NJ/MA/etc., 12,424) only map to a product
|
|
||||||
for CA (CARB via `ca-mcp-carb`). Non-CA emissions have no product — decide
|
|
||||||
whether to build or fold into existing state DOT/permit service.
|
|
||||||
|
|
||||||
## Approach (concrete ordered steps)
|
## Approach (concrete ordered steps)
|
||||||
|
1. **Confirm the CMS-10114 paper path** for NPPES data updates AND NPI
|
||||||
### Phase 1 — Close the hazmat fulfillment gap (only fully-missing path)
|
reactivation (not just initial enumeration): paper CMS-10114 mailed to NPI
|
||||||
1. Add `HazmatPHMSAHandler` in `scripts/workers/services/hazmat_phmsa.py`
|
Enumerator (PO Box 6059, Fargo ND), client signature only, no I&A login.
|
||||||
(admin-assisted, mirrors `state_trucking.py`: creates admin_todo with PHMSA
|
Cite the official source. This is what makes NPPES services "Standard, no
|
||||||
registration steps, sends status email). Slug `hazmat-phmsa`.
|
login" instead of surrogate-required. (We currently have no CMS-10114 PDF.)
|
||||||
2. Register `"hazmat-phmsa": HazmatPHMSAHandler` in `services/__init__.py`.
|
2. **Lock the two-tier matrix for the 6 federal services.** For each slug record:
|
||||||
3. Add product to `COMPLIANCE_SERVICES`, meta to `intake_manifest.ts`, slug to
|
Standard path (form, mail destination, client's only action = sign / nothing),
|
||||||
checkout allowlist.
|
Expedited path (surrogate scope: PECOS and/or NPPES; what client grants),
|
||||||
|
and whether expedited is even applicable (screening = public, no portal, so
|
||||||
### Phase 1.5 — Order-form incompatibility enforcement (bundles vs components, dupes)
|
no expedited tier). Confirm the 855 wet-signature-cannot-be-delegated caveat
|
||||||
Today the batch endpoint (`compliance-orders.ts` POST `/batch`) only dedupes and
|
applies to Standard; surrogate covers Expedited.
|
||||||
hard-codes one case (drop standalone `fcc-499a` when `fcc-499a-499q` present).
|
3. **Reconcile checkout.ts.** Plan the edit so:
|
||||||
There is no general rule preventing a customer from selecting a **bundle plus its
|
- NPPES update/reactivation no longer present surrogate as *required* — remove
|
||||||
own components** (e.g. `dot-full-compliance` + `mcs150-update` + `boc3-filing`, or
|
the "online-only / required for those" language.
|
||||||
`state-trucking-bundle` + `irp-registration`), or other incompatible combos. This
|
- The surrogate ask is framed as the **faster, fewer-steps** option, never
|
||||||
double-charges and creates duplicate filings.
|
against a "paper" alternative. Audit/strip the existing copy that leaks
|
||||||
|
mechanics to the client (e.g. "we'll send your CMS-855 to sign", "submit it
|
||||||
Build a single source of truth for service relationships and enforce it:
|
to your MAC") — replace with neutral "we file it and track it for you."
|
||||||
- Add `BUNDLE_COMPONENTS` map (bundle slug -> component slugs) covering
|
- Declining surrogate silently routes to our Standard path; no client-facing
|
||||||
`dot-full-compliance`, `state-trucking-bundle`, `new-carrier-bundle`,
|
mention of paper/MAC/Fargo/form numbers.
|
||||||
`fcc-full-compliance`, plus the DB `service_bundles` rows.
|
4. **Reconcile npi_provider.py.** Update `access` strings + `_STANDARD_FILING_SLUGS`
|
||||||
- Add `INCOMPATIBLE_PAIRS` / mutually-exclusive groups (e.g. `usdot-reactivation`
|
so nppes-update/reactivation generate the CMS-10114 (or 855 reactivation)
|
||||||
vs `carrier-closeout`; `fcc-499a` vs `fcc-499a-499q`; emergency-temp-authority
|
paper + e-sign, and the admin todo reflects Standard-default / Expedited-if-
|
||||||
vs mc-authority where applicable).
|
surrogate-granted. Mirror the existing 855 generate→upload→esign flow.
|
||||||
- Server-side (authoritative) in `/batch`: when a bundle is present, **drop any of
|
5. **MAC + Fargo routing rule.** Document which Standard filings go where
|
||||||
its components** from the cart (keep the bundle), reject hard-incompatible pairs
|
(855 → provider's MAC by state/jurisdiction; CMS-10114 → Fargo). Confirm
|
||||||
with a clear error, and keep dedup. Generalize the existing 499a special-case
|
`practice_state` intake field drives MAC envelope addressing.
|
||||||
into this map.
|
7. **Daily batched-mail fulfillment (Standard path).** Design the operational
|
||||||
- Client-side (order form / cart UI): disable/grey out a component when its parent
|
flow for paper filings that are signed + pending submission:
|
||||||
bundle is selected (and vice-versa: selecting all components suggests the bundle),
|
- On each **postal working day morning** (skip weekends + federal/USPS
|
||||||
and prevent selecting mutually-exclusive options, with an inline explanation.
|
holidays), gather ALL signed-and-pending paper filings, **group by
|
||||||
Mirror the server map so UX matches enforcement.
|
destination agency/address** (each MAC, the NPI Enumerator in Fargo, each
|
||||||
|
state Medicaid/CLIA agency).
|
||||||
### Phase 2 — Make state-trucking intake actually collect required data
|
- For each destination, **merge all that day's documents into one print job**
|
||||||
4. Build `StateTruckingIntakeStep.astro` (one shared step, sections shown by
|
plus a **cover sheet** (Performance West sender, destination agency, date,
|
||||||
slug, mirroring `DOTIntakeStep.astro`'s section-gating pattern):
|
enclosed-count, per-item list of order# / provider / NPI / form). One
|
||||||
- Carrier identity: legal name, DOT#, MC#, base state, contact (prefill from DOT lookup).
|
**Priority Mail envelope per agency** → saves postage + handling.
|
||||||
- IRP/IFTA: power units w/ VIN+plate+gross-weight rows, operating jurisdictions, fuel type.
|
- Mark each included order as "mailed" with the batch date + tracking #.
|
||||||
- Weight-distance (OR/NY/KY/NM/CT): vehicle list + gross weights + (OR) declared combined weight.
|
- Build this as a worker (a `daily_paper_batch` job + a cover-sheet generator
|
||||||
- CA MCP+CARB: fleet engine model-years for CARB Clean Truck Check, CA# if any.
|
in document_gen), mirroring existing worker/cron patterns
|
||||||
- Intrastate authority: authority type, insurance carrier + policy#, cargo, BOC-3 on file?
|
(`infra/cron/*`, `business_days.py` for the working-day calendar). Decide:
|
||||||
- State DOT / OSOW: as needed.
|
fully-automated print-to-PDF batch that a human prints + drops, vs.
|
||||||
5. Update `intake_manifest.ts`: replace `["review"]` with
|
print-API (Lob/Click2Mail) auto-mail. **Recommend phase 1 = generate the
|
||||||
`["state-trucking", "review"]` for the 13 slugs; wire the step into the Wizard.
|
per-agency batched PDF + cover sheet + manifest for a human to print & mail;
|
||||||
6. Add `REQUIRED_FIELDS` entries in `compliance-orders.ts` for each state-trucking
|
phase 2 = wire a print-mail API.**
|
||||||
slug + the DOT slugs (mcs150, ucr, boc3, dot-registration, mc-authority, etc.)
|
8. **Extend two-tier to state/adjacent services.** For each (State Medicaid
|
||||||
so intake is validated server-side. Mirror handler "Intake data needed" docstrings.
|
enroll/reval, CAQH re-attest, payer credentialing, DEA renewal, state CSR,
|
||||||
7. Update `state_trucking.py` handler to read + surface the new intake fields in
|
PDMP, CLIA, license renewal+CME) classify:
|
||||||
the admin todo (so admins get vehicle lists, jurisdictions, insurance, etc.).
|
- **Standard (no-login):** paper/mail-in form + one client signature?
|
||||||
|
(e.g. CLIA = CMS-116 paper to state; Medicaid varies — some paper.) These
|
||||||
### Phase 2.5 — Make BOC-3 authority-aware (preexisting authority handling)
|
feed the same daily batched-mail flow, grouped by their state agency.
|
||||||
The BOC-3 attaches to a carrier's operating authority (MC/FF/MX docket). Today
|
- **Expedited (delegated):** the lightest legitimate delegation that avoids a
|
||||||
`boc3_filing.py` only reads `commonAuthorityStatus`/`contractAuthorityStatus`/
|
client *login* — e.g. CAQH "authorized administrator/org" grant, Medicaid
|
||||||
`brokerAuthorityStatus` to print a status string and otherwise always files a
|
"delegated official" on the app, payer EDI/CAQH attestation rights, an LOA.
|
||||||
fresh BOC-3. That can be wrong/wasteful depending on the preexisting authority.
|
Distinguish "client signs one authorization once" (acceptable, still
|
||||||
Add branching off the live FMCSA authority state:
|
no-login) from "client must log in / share credentials" (never).
|
||||||
- **Active authority:** file/refresh BOC-3 only. (current behavior)
|
- Flag services that are genuinely portal-only with NO paper standard so
|
||||||
- **Pending authority:** file BOC-3 + flag that active insurance must be on file
|
marketing never claims "no logins" for them.
|
||||||
for the authority to activate; create follow-up todo.
|
9. **Sequence the rollout** by (Standard-feasibility first) × revenue, and write
|
||||||
- **Revoked/inactive authority:** file BOC-3 **and** flag/upsell reinstatement
|
the two doc updates + the small code edits (checkout.ts, npi_provider.py,
|
||||||
(OP-1 reinstatement + $80 gov fee, route via `usdot-reactivation`/`mc-authority`
|
optional cms10114_pdf_filler.py, and the daily batch worker + cover sheet).
|
||||||
reinstatement branch). BOC-3 alone does not reinstate.
|
All gated on approval.
|
||||||
- **No authority (USDOT only):** BOC-3 has nothing to attach to — flag that MC
|
|
||||||
authority (`mc-authority`) is likely needed first; do not silently file.
|
|
||||||
Implementation: have `process()/handle()` read full authority status (reuse
|
|
||||||
`_check_boc3_status`, expanded to return structured fields), select the branch,
|
|
||||||
adjust the admin-todo + customer email, and emit a `recommended_followups` list
|
|
||||||
the order timeline / upsell can surface. No automatic charge for the follow-up —
|
|
||||||
surface it for the customer/admin to approve.
|
|
||||||
|
|
||||||
### Phase 2.6 — Prerequisite/activation gating (wait for FMCSA "active", not just "submitted")
|
|
||||||
There are real FMCSA dependency chains where a downstream filing must wait for an
|
|
||||||
upstream item to be **active at the agency**, not merely submitted by us. The
|
|
||||||
existing `pipeline_orchestrator.py` models ordering via `wait_for`, but a step is
|
|
||||||
treated as satisfied when `pipeline_step_status == "completed"` (= our handler
|
|
||||||
finished), which is NOT the same as FMCSA showing it active.
|
|
||||||
|
|
||||||
True prerequisites to enforce:
|
|
||||||
- **MC Authority (OP-1)** requires an **active USDOT**.
|
|
||||||
- **Authority activation** requires **BOC-3 on file + insurance (BMC-91) on file**,
|
|
||||||
then a **mandatory ~21-day vetting/protest period** before it goes active.
|
|
||||||
BOC-3 + insurance CAN be filed while authority is pending (parallel OK).
|
|
||||||
- **IRP / IFTA / intrastate-authority / UCR** that depend on *active* authority
|
|
||||||
(or active USDOT) must wait for that activation, not just for the prior order to
|
|
||||||
be submitted.
|
|
||||||
|
|
||||||
Implementation:
|
|
||||||
- Add an "activation gate" to the orchestrator: for dependency edges flagged
|
|
||||||
`require_active: true`, poll FMCSA (mobile QC API for USDOT status; L&I for
|
|
||||||
authority/BOC-3/insurance) and only mark the dependency satisfied when the
|
|
||||||
agency reports active. Until then, hold the downstream step in a
|
|
||||||
`waiting_on_activation` state with a next-poll timestamp.
|
|
||||||
- Encode the 21-day authority vetting window as an expected-activation estimate so
|
|
||||||
the timeline/customer comms set correct expectations.
|
|
||||||
- Expand `PIPELINES` edges with `require_active` flags (USDOT→MC, USDOT→IRP/IFTA/
|
|
||||||
UCR/intrastate, authority-active→IRP-for-hire/intrastate).
|
|
||||||
- Standalone (non-bundle) orders: when a single service is ordered whose
|
|
||||||
prerequisite isn't active yet, surface a clear "blocked until X is active"
|
|
||||||
status + recommended prerequisite order rather than filing prematurely.
|
|
||||||
|
|
||||||
### Phase 3 — Decide + handle state emissions (non-CA)
|
|
||||||
8. Either: (a) add a generic `state-emissions` service handler+product covering
|
|
||||||
NY/CO/MD/NJ/MA clean-truck/ACT programs, or (b) map those flags to
|
|
||||||
`state-dot-registration` / advisory-only. (Open question — see below.)
|
|
||||||
|
|
||||||
### Phase 4 — Order landing pages
|
|
||||||
9. Create `site/src/pages/order/*.astro` for: irp-ifta (combined), state weight
|
|
||||||
taxes (one templated page per state or a single state-aware page),
|
|
||||||
ca-mcp-carb, intrastate-authority, hazmat-phmsa. Reuse existing order-page
|
|
||||||
layout (e.g. `boc3-filing.astro`, `ucr-registration.astro` as templates).
|
|
||||||
|
|
||||||
### Phase 5 — Extend campaign builder (only after 1-4 verified)
|
|
||||||
10. Add new campaign segments to `build_trucking_campaigns.py` keyed off
|
|
||||||
`deficiency_flags`: for-hire/BOC-3+UCR, IRP/IFTA, intrastate-authority,
|
|
||||||
state weight-tax (per-state), CA MCP/CARB, hazmat. Each links to its LP.
|
|
||||||
11. Create the corresponding Listmonk source campaigns (templates) and wire IDs.
|
|
||||||
|
|
||||||
## Validation (how each part is verified)
|
## Validation (how each part is verified)
|
||||||
|
- **Source-grounded:** every Standard (paper) and Expedited (delegation) claim
|
||||||
- **Handlers:** unit-invoke each handler with a synthetic `order_data` dict in a
|
cites the official instruction (CMS-855 instr, CMS-10114 instr, CMS-116 for
|
||||||
throwaway script; assert an `admin_todos` row is created with the expected
|
CLIA, state Medicaid enrollment page, CAQH/payer docs). No unsourced claim.
|
||||||
fields and (dev mode) no live filing fires. Confirm `SERVICE_HANDLERS` resolves
|
- **Consistency sweep:** after edits, `grep` for "online-only" / "required" /
|
||||||
every new slug.
|
"surrogate" / "no login" across checkout.ts, npi_provider.py, and the service
|
||||||
- **Intake completeness (the core ask):** write a check that, for every slug,
|
pages — confirm none present surrogate as *required* where a paper path exists,
|
||||||
cross-references `REQUIRED_FIELDS[slug]` against the fields the intake step
|
and Standard is the default on every surface.
|
||||||
emits and against the keys the handler reads — fail if a handler-needed field
|
- **Standard path mechanism check:** `cms855_pdf_filler.fill_cms855("855i",...)`
|
||||||
is never collected. This is the verifiable "we collect all needed info" metric.
|
still yields filled PDF + cert anchor (read-only smoke render). If CMS-10114
|
||||||
- **Checkout/products:** assert every flagged slug exists in `COMPLIANCE_SERVICES`,
|
filler is built, same smoke render proves a signable Fargo-bound PDF.
|
||||||
`SERVICE_META`, checkout allowlist, and `SERVICE_HANDLERS` (one consistency test).
|
- **Expedited path check:** confirm the surrogate-grant CTA + `ia_surrogacy`
|
||||||
- **Order pages:** build site (`astro build` / existing build script) and confirm
|
success action + admin todo together let a human file in PECOS/NPPES same-day;
|
||||||
each new `/order/<slug>` route renders; smoke-load locally.
|
surrogate scope wording matches what CMS I&A actually grants (PECOS vs NPPES).
|
||||||
- **Campaign builder:** run `build_trucking_campaigns.py --dry-run` and assert
|
- **Matrix completeness:** every service (federal + state) has Standard + (where
|
||||||
each new segment selects a nonzero, deduped audience pointing at a valid LP.
|
applicable) Expedited rows with a definite client-action column and source;
|
||||||
- **End-to-end:** place a test order per new slug through checkout in dev, verify
|
no "unknown" and no service that's portal-only-but-marketed-as-no-login.
|
||||||
intake validation blocks missing fields, and the handler produces a complete
|
|
||||||
admin todo.
|
|
||||||
|
|
||||||
## Open questions / decisions
|
## Open questions / decisions
|
||||||
|
1. **NPPES update/reactivation Standard path:** is CMS-10114 paper-to-Fargo
|
||||||
**RESOLVED (per user 2026-06-02):**
|
accepted for *changes/reactivation* today (RESOLVE in step 1)? If yes, both
|
||||||
1. **BOC-3 follow-ups + prerequisite blockers → upsell-approve, advise pre-order
|
become Standard-default + surrogate-expedited. If CMS has gone online-only,
|
||||||
where possible.** Two layers:
|
they stay surrogate-required and we say so honestly. (Directive assumes paper
|
||||||
- *Pre-order advisory (preferred):* extend the existing DOT Compliance Check
|
works as Standard; step 1 verifies.)
|
||||||
tool (`site/public/tools/dot-compliance-check/`) + `dot-lookup` recommended
|
2. **Build `cms10114_pdf_filler.py` this pass?** Needed for a real NPPES Standard
|
||||||
services to be **prerequisite-aware**. When a recommended service needs an
|
path. Recommend: yes if step 1 confirms paper, mirroring the 855 filler;
|
||||||
active prerequisite (e.g. IRP needs active authority), show the dependency,
|
otherwise defer.
|
||||||
pre-select the prerequisite, order the cart correctly, and state the ~21-day
|
3. **State Medicaid scope:** classify the mechanism generically + verify top ~5
|
||||||
authority activation expectation — all before payment.
|
states by our lead density now; template the rest. (50-state research is a
|
||||||
- *Post-order upsell-approve:* when a handler discovers a blocker mid-fulfillment
|
separate effort.)
|
||||||
(e.g. BOC-3 ordered but authority revoked → needs reinstatement), write a
|
4. **CAQH / payer credentialing tier:** almost certainly Expedited = "client
|
||||||
`recommended_followups` entry on the order and render a one-click, pre-filled
|
signs one authorization, no login" (category C). Confirm we market that as
|
||||||
"Add this service" card on the order timeline/portal. Customer confirms + pays
|
"no logins for you" with precise wording.
|
||||||
via the existing checkout. **No auto-charge.**
|
5. **Expedited pricing/positioning:** RESOLVED — expedited is **not** a paid
|
||||||
- *Standalone checkout guard:* if a service is bought directly and its prereq
|
tier and we never expose "paper" as the alternative. It's an intake question
|
||||||
isn't active at FMCSA, warn + offer to add the prereq rather than filing
|
framed positively ("electronically granting surrogate access lets us bulk-file
|
||||||
something unfulfillable.
|
faster / fewer steps on our end"). If yes → online; if no → silent Standard
|
||||||
2. **State emissions (non-CA): build a real product.** Add a `state-emissions`
|
fallback. Same price. No price delta, no separate product, no mention of paper.
|
||||||
service (handler + product + intake + page) covering NY/CO/MD/NJ/MA clean-truck
|
6. **Client-facing messaging rule:** never surface mechanics to the client —
|
||||||
/ Advanced Clean Trucks programs (CA stays on `ca-mcp-carb`).
|
no "paper", "CMS-855", "CMS-10114", "MAC", or "Fargo" in any client copy
|
||||||
3. **Pre-order advisory: yes.** Covered by 1 above — reuse the compliance-check
|
(cold email, order page, checkout, intake). The only client-visible choice is
|
||||||
tool as the advisory surface.
|
the positive surrogate question; everything else is "we file it for you." This
|
||||||
|
applies to the checkout copy audit in step 3.
|
||||||
**STILL OPEN:**
|
|
||||||
4. Pricing for `hazmat-phmsa` and `state-emissions`.
|
|
||||||
**DEFAULT:** `hazmat-phmsa` = $149 (admin-assisted PHMSA registration; gov fee
|
|
||||||
$25 placardable-hazmat reg billed at cost). `state-emissions` = $199
|
|
||||||
(NY/CO/MD/NJ/MA clean-truck / ACT advisory + registration assist).
|
|
||||||
5. Vehicle-list intake fidelity.
|
|
||||||
**DEFAULT:** lightweight up front — collect fleet count + base/operating states
|
|
||||||
+ fuel type + gross-weight bracket at intake; collect full per-vehicle
|
|
||||||
VIN/plate/weight rows via a post-order follow-up form only when the specific
|
|
||||||
filing requires it (IRP, weight-distance taxes). Keeps conversion high.
|
|
||||||
6. Standalone-order prereq guard.
|
|
||||||
**DEFAULT:** warn + offer to add the prerequisite (pre-selected), allow override
|
|
||||||
("file anyway"). Never a hard block.
|
|
||||||
7. Long-term home for the reviewable plan (`docs/plans/` used here; no
|
|
||||||
`side_panel` tool in this harness).
|
|
||||||
|
|
|
||||||
118
scripts/workers/mac_routing.py
Normal file
118
scripts/workers/mac_routing.py
Normal file
|
|
@ -0,0 +1,118 @@
|
||||||
|
"""State -> Medicare Administrative Contractor (MAC) routing for CMS-855 mailing.
|
||||||
|
|
||||||
|
CMS-855 paper applications are mailed to the provider's *designated MAC*, which is
|
||||||
|
determined by the provider's STATE/jurisdiction (per the official 855I/855B/855O
|
||||||
|
instructions: "The MAC that services your State is responsible for processing your
|
||||||
|
enrollment application").
|
||||||
|
|
||||||
|
This module maps each US state/territory -> its A/B MAC name + provider-enrollment
|
||||||
|
mailing address. It is used to:
|
||||||
|
1. Address the outgoing envelope for the Standard (paper) filing path.
|
||||||
|
2. Group the daily batched mailing by destination agency (one Priority Mail
|
||||||
|
envelope per MAC address).
|
||||||
|
|
||||||
|
IMPORTANT — verify before first live mail run: MAC jurisdiction assignments and
|
||||||
|
(especially) the provider-enrollment PO Box addresses change when CMS re-competes
|
||||||
|
a jurisdiction. Confirm each MAC's current enrollment mailing address against the
|
||||||
|
MAC's website / CMS.gov/Medicare/Provider-Enrollment-and-Certification right
|
||||||
|
before the first batch, then keep this table the single source of truth.
|
||||||
|
|
||||||
|
Jurisdiction assignments below reflect the long-standing A/B MAC map. Addresses
|
||||||
|
are marked TODO where they must be filled from the MAC's current enrollment page.
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(frozen=True)
|
||||||
|
class MAC:
|
||||||
|
key: str # short stable id (used for batch grouping)
|
||||||
|
name: str # MAC contractor + jurisdiction
|
||||||
|
# Provider-enrollment mailing address lines. VERIFY before live use.
|
||||||
|
address_lines: tuple[str, ...]
|
||||||
|
|
||||||
|
|
||||||
|
# A/B MAC jurisdictions (long-standing assignments). Addresses TODO-verify.
|
||||||
|
NORIDIAN_JE = MAC("noridian_je", "Noridian Healthcare Solutions — Jurisdiction E",
|
||||||
|
("Noridian Healthcare Solutions", "Provider Enrollment (JE)",
|
||||||
|
"P.O. Box — VERIFY", "Fargo, ND — VERIFY"))
|
||||||
|
NORIDIAN_JF = MAC("noridian_jf", "Noridian Healthcare Solutions — Jurisdiction F",
|
||||||
|
("Noridian Healthcare Solutions", "Provider Enrollment (JF)",
|
||||||
|
"P.O. Box — VERIFY", "Fargo, ND — VERIFY"))
|
||||||
|
NOVITAS_JH = MAC("novitas_jh", "Novitas Solutions — Jurisdiction H",
|
||||||
|
("Novitas Solutions", "Provider Enrollment (JH)",
|
||||||
|
"P.O. Box — VERIFY", "Mechanicsburg, PA — VERIFY"))
|
||||||
|
NOVITAS_JL = MAC("novitas_jl", "Novitas Solutions — Jurisdiction L",
|
||||||
|
("Novitas Solutions", "Provider Enrollment (JL)",
|
||||||
|
"P.O. Box — VERIFY", "Mechanicsburg, PA — VERIFY"))
|
||||||
|
FCSO_JN = MAC("fcso_jn", "First Coast Service Options — Jurisdiction N",
|
||||||
|
("First Coast Service Options", "Provider Enrollment (JN)",
|
||||||
|
"P.O. Box — VERIFY", "Jacksonville, FL — VERIFY"))
|
||||||
|
PALMETTO_JJ = MAC("palmetto_jj", "Palmetto GBA — Jurisdiction J",
|
||||||
|
("Palmetto GBA", "Provider Enrollment (JJ)",
|
||||||
|
"P.O. Box — VERIFY", "Columbia, SC — VERIFY"))
|
||||||
|
PALMETTO_JM = MAC("palmetto_jm", "Palmetto GBA — Jurisdiction M",
|
||||||
|
("Palmetto GBA", "Provider Enrollment (JM)",
|
||||||
|
"P.O. Box — VERIFY", "Columbia, SC — VERIFY"))
|
||||||
|
CGS_J15 = MAC("cgs_j15", "CGS Administrators — Jurisdiction 15",
|
||||||
|
("CGS Administrators", "Provider Enrollment (J15)",
|
||||||
|
"P.O. Box — VERIFY", "Nashville, TN — VERIFY"))
|
||||||
|
WPS_J5 = MAC("wps_j5", "WPS Government Health Administrators — Jurisdiction 5",
|
||||||
|
("WPS GHA", "Provider Enrollment (J5)",
|
||||||
|
"P.O. Box — VERIFY", "Madison, WI — VERIFY"))
|
||||||
|
WPS_J8 = MAC("wps_j8", "WPS Government Health Administrators — Jurisdiction 8",
|
||||||
|
("WPS GHA", "Provider Enrollment (J8)",
|
||||||
|
"P.O. Box — VERIFY", "Madison, WI — VERIFY"))
|
||||||
|
NGS_J6 = MAC("ngs_j6", "National Government Services — Jurisdiction 6",
|
||||||
|
("National Government Services", "Provider Enrollment (J6)",
|
||||||
|
"P.O. Box — VERIFY", "VERIFY"))
|
||||||
|
NGS_JK = MAC("ngs_jk", "National Government Services — Jurisdiction K",
|
||||||
|
("National Government Services", "Provider Enrollment (JK)",
|
||||||
|
"P.O. Box — VERIFY", "VERIFY"))
|
||||||
|
|
||||||
|
# State (USPS) -> MAC. Based on the established A/B MAC jurisdiction map.
|
||||||
|
STATE_TO_MAC: dict[str, MAC] = {
|
||||||
|
# Noridian JE
|
||||||
|
"CA": NORIDIAN_JE, "HI": NORIDIAN_JE, "NV": NORIDIAN_JE,
|
||||||
|
"AS": NORIDIAN_JE, "GU": NORIDIAN_JE, "MP": NORIDIAN_JE,
|
||||||
|
# Noridian JF
|
||||||
|
"AK": NORIDIAN_JF, "AZ": NORIDIAN_JF, "ID": NORIDIAN_JF, "MT": NORIDIAN_JF,
|
||||||
|
"ND": NORIDIAN_JF, "OR": NORIDIAN_JF, "SD": NORIDIAN_JF, "UT": NORIDIAN_JF,
|
||||||
|
"WA": NORIDIAN_JF, "WY": NORIDIAN_JF,
|
||||||
|
# Novitas JH
|
||||||
|
"AR": NOVITAS_JH, "CO": NOVITAS_JH, "LA": NOVITAS_JH, "MS": NOVITAS_JH,
|
||||||
|
"NM": NOVITAS_JH, "OK": NOVITAS_JH, "TX": NOVITAS_JH,
|
||||||
|
# Novitas JL
|
||||||
|
"DE": NOVITAS_JL, "DC": NOVITAS_JL, "MD": NOVITAS_JL, "NJ": NOVITAS_JL,
|
||||||
|
"PA": NOVITAS_JL,
|
||||||
|
# First Coast JN
|
||||||
|
"FL": FCSO_JN, "PR": FCSO_JN, "VI": FCSO_JN,
|
||||||
|
# Palmetto JJ
|
||||||
|
"AL": PALMETTO_JJ, "GA": PALMETTO_JJ, "TN": PALMETTO_JJ,
|
||||||
|
# Palmetto JM
|
||||||
|
"NC": PALMETTO_JM, "SC": PALMETTO_JM, "VA": PALMETTO_JM, "WV": PALMETTO_JM,
|
||||||
|
# CGS J15
|
||||||
|
"KY": CGS_J15, "OH": CGS_J15,
|
||||||
|
# WPS J5
|
||||||
|
"IA": WPS_J5, "KS": WPS_J5, "MO": WPS_J5, "NE": WPS_J5,
|
||||||
|
# WPS J8
|
||||||
|
"IN": WPS_J8, "MI": WPS_J8,
|
||||||
|
# NGS J6
|
||||||
|
"IL": NGS_J6, "MN": NGS_J6, "WI": NGS_J6,
|
||||||
|
# NGS JK
|
||||||
|
"CT": NGS_JK, "ME": NGS_JK, "MA": NGS_JK, "NH": NGS_JK,
|
||||||
|
"NY": NGS_JK, "RI": NGS_JK, "VT": NGS_JK,
|
||||||
|
}
|
||||||
|
|
||||||
|
# NPI Enumerator paper address (NPPES / CMS-10114 paper path) — not a MAC, but a
|
||||||
|
# destination the daily batch groups by, same as a MAC.
|
||||||
|
NPI_ENUMERATOR = MAC(
|
||||||
|
"npi_enumerator", "NPI Enumerator (NPPES / CMS-10114 paper)",
|
||||||
|
("NPI Enumerator", "P.O. Box 6059", "Fargo, ND 58108-6059"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def mac_for_state(state: str) -> MAC | None:
|
||||||
|
"""Return the designated MAC for a USPS state code, or None if unknown."""
|
||||||
|
return STATE_TO_MAC.get((state or "").strip().upper())
|
||||||
|
|
@ -46,7 +46,8 @@ _SLUG_META = {
|
||||||
"enrollment record, and submit. Capture the PECOS tracking ID."
|
"enrollment record, and submit. Capture the PECOS tracking ID."
|
||||||
),
|
),
|
||||||
"access": (
|
"access": (
|
||||||
"Standard: prepare CMS-855I/B/R, provider signs cert, submit to MAC. Expedited: file in PECOS via CMS I&A surrogate access."
|
"Standard (default): prepare CMS-855I/B, provider e-signs cert, mail to MAC (daily batch). "
|
||||||
|
"Expedited (if surrogate granted at intake): file in PECOS via CMS I&A surrogate access, same-day tracking."
|
||||||
),
|
),
|
||||||
"priority": "high",
|
"priority": "high",
|
||||||
},
|
},
|
||||||
|
|
@ -54,11 +55,12 @@ _SLUG_META = {
|
||||||
"name": "NPI Reactivation",
|
"name": "NPI Reactivation",
|
||||||
"portal": "https://nppes.cms.hhs.gov/",
|
"portal": "https://nppes.cms.hhs.gov/",
|
||||||
"action": (
|
"action": (
|
||||||
"Reactivate the deactivated NPI in NPPES. Verify the deactivation "
|
"Reactivate the deactivated NPI. Verify the deactivation "
|
||||||
"reason, correct any stale data, and re-certify the record."
|
"reason, correct any stale data, and re-certify the record."
|
||||||
),
|
),
|
||||||
"access": (
|
"access": (
|
||||||
"NPPES via CMS I&A surrogate access (online-only)."
|
"Standard (default): prepare CMS-855I (reactivation reason), provider e-signs, mail to MAC (daily batch). "
|
||||||
|
"Expedited (if surrogate granted): reactivate online in PECOS/NPPES via I&A surrogate access."
|
||||||
),
|
),
|
||||||
"priority": "high",
|
"priority": "high",
|
||||||
},
|
},
|
||||||
|
|
@ -71,7 +73,8 @@ _SLUG_META = {
|
||||||
"changes and certify."
|
"changes and certify."
|
||||||
),
|
),
|
||||||
"access": (
|
"access": (
|
||||||
"NPPES via CMS I&A surrogate access (online-only)."
|
"Standard (default): prepare CMS-10114 NPPES update, provider e-signs, mail to NPI Enumerator (Fargo, daily batch). "
|
||||||
|
"Expedited (if surrogate granted): update online in NPPES via I&A surrogate access."
|
||||||
),
|
),
|
||||||
"priority": "normal",
|
"priority": "normal",
|
||||||
},
|
},
|
||||||
|
|
@ -83,7 +86,9 @@ _SLUG_META = {
|
||||||
"Confirm taxonomy, practice location, and authorized official."
|
"Confirm taxonomy, practice location, and authorized official."
|
||||||
),
|
),
|
||||||
"access": (
|
"access": (
|
||||||
"Standard: prepare CMS-855, provider signs cert, submit to MAC. Expedited: file in PECOS via CMS I&A surrogate access."
|
"Standard (default): prepare CMS-855, provider e-signs cert, mail to MAC (daily batch). "
|
||||||
|
"Expedited (if surrogate granted): file in PECOS via CMS I&A surrogate access, same-day tracking. "
|
||||||
|
"NOTE: org (855B) enrollment/revalidation requires the CMS application fee paid via PECOS before submission."
|
||||||
),
|
),
|
||||||
"priority": "high",
|
"priority": "high",
|
||||||
},
|
},
|
||||||
|
|
@ -109,16 +114,22 @@ _SLUG_META = {
|
||||||
"record. Set the next revalidation reminder."
|
"record. Set the next revalidation reminder."
|
||||||
),
|
),
|
||||||
"access": (
|
"access": (
|
||||||
"Standard CMS-855 filing for the enrollment/revalidation piece; NPPES + PECOS via CMS I&A surrogate access; screening is public."
|
"Standard (default): CMS-855 paper filing for the enrollment/revalidation piece, mailed to MAC (daily batch); screening is public (no client action). "
|
||||||
|
"Expedited (if surrogate granted): NPPES + PECOS pieces filed online via CMS I&A surrogate access."
|
||||||
),
|
),
|
||||||
"priority": "high",
|
"priority": "high",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# Slugs whose fulfilment includes a CMS-855 (auto-filled official form, signed
|
# Slugs whose fulfilment includes a CMS-855 (auto-filled official form, signed
|
||||||
# via the secure e-sign link, then submitted to the provider's MAC). The
|
# via the secure e-sign link, then submitted to the provider's MAC via the daily
|
||||||
# bundle's revalidation piece is handled by the dedicated revalidation order it
|
# batched mailing). The bundle's revalidation piece is handled by the dedicated
|
||||||
# spawns, so it is not listed here.
|
# revalidation order it spawns, so it is not listed here.
|
||||||
|
#
|
||||||
|
# nppes-update is intentionally NOT here: its Standard path is the CMS-10114 (NPPES
|
||||||
|
# update mailed to the NPI Enumerator in Fargo), handled by a separate filler when
|
||||||
|
# built. Until then, nppes-update falls to the admin todo (Expedited if surrogate
|
||||||
|
# granted, otherwise manual CMS-10114 prep).
|
||||||
_STANDARD_FILING_SLUGS = {
|
_STANDARD_FILING_SLUGS = {
|
||||||
"npi-revalidation",
|
"npi-revalidation",
|
||||||
"npi-reactivation",
|
"npi-reactivation",
|
||||||
|
|
|
||||||
|
|
@ -51,10 +51,10 @@ const description = "New to Medicare or adding a practice location? We assemble
|
||||||
<li>We submit it to your Medicare Administrative Contractor (MAC) and track it through to approval.</li>
|
<li>We submit it to your Medicare Administrative Contractor (MAC) and track it through to approval.</li>
|
||||||
</ol>
|
</ol>
|
||||||
<div class="pw-callout">
|
<div class="pw-callout">
|
||||||
<strong>Need it filed faster?</strong> Choose <strong>expedited</strong> at
|
<strong>Want it filed faster?</strong> If you can electronically grant us
|
||||||
checkout and add us as a <strong>Surrogate</strong> in CMS Identity &
|
<strong>Surrogate</strong> access in CMS Identity & Access, we can file
|
||||||
Access. We then file directly in PECOS under our own credentials and
|
even faster — it cuts steps on our end. You never share your login,
|
||||||
capture the tracking ID the same day. You never share your login.
|
and it's never required; we'll file it for you either way.
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,12 +69,13 @@ const description = "CMS requires every enrolled provider and supplier to revali
|
||||||
<section>
|
<section>
|
||||||
<h2>How we file for you</h2>
|
<h2>How we file for you</h2>
|
||||||
<p>
|
<p>
|
||||||
You pick whichever path is easiest. <strong>You never share your CMS
|
We handle the whole filing and track it to confirmation. The only thing
|
||||||
password.</strong>
|
we may need from you is a one-minute signature on a secure link.
|
||||||
|
<strong>You never share your CMS password.</strong>
|
||||||
</p>
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li><strong>Standard filing (nothing to set up).</strong> We complete the correct CMS-855, you approve and sign the certification from a secure link in about a minute, and we submit it to your Medicare Administrative Contractor (MAC) and track it to confirmation.</li>
|
<li><strong>We do the work.</strong> We complete the correct CMS-855 (855I for individuals, 855B for groups), you approve and e-sign the certification from a secure link, and we submit and track it to confirmation.</li>
|
||||||
<li><strong>Expedited filing (needs a CMS account).</strong> You add us as a <strong>Surrogate</strong> in the CMS Identity & Access (I&A) system; we then file directly in PECOS under our own credentials and capture the tracking ID the same day.</li>
|
<li><strong>Optional: speed it up.</strong> If you can electronically grant us <strong>Surrogate</strong> access in the CMS Identity & Access (I&A) system, we can file even faster — it cuts steps on our end. You never share your password, and it's never required.</li>
|
||||||
</ul>
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue