From 41df4d9553b3963790a24e4d731d77dd97b2a02f Mon Sep 17 00:00:00 2001 From: justin Date: Sun, 7 Jun 2026 02:56:41 -0500 Subject: [PATCH] healthcare: go live with wet-signature filings + 2-day ETA buffer Adds explicit order timelines for the 5 CMS provider filings (nppes-update, npi-reactivation, npi-revalidation, medicare-enrollment, provider-compliance- bundle) and a +2 business-day buffer applied from the signature step onward, giving us time to produce + mail the original ink signature while the plotter station is brought online. - Buffer only affects post-signature steps; pre-signature steps and all non-wet-signature services are unchanged (verified with date math). - Single source of truth: order-timeline route (consumed by the order success page), so the buffer flows through to the customer-facing ETA. - Remove WET_SIGNATURE_BUFFER_DAYS once the ink-signature station is in steady-state (see docs/plans/plotter-plan.md). API tsc clean; buffer compiled into dist. --- api/src/routes/order-timeline.ts | 76 ++++++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/api/src/routes/order-timeline.ts b/api/src/routes/order-timeline.ts index fbdf18b..14801f7 100644 --- a/api/src/routes/order-timeline.ts +++ b/api/src/routes/order-timeline.ts @@ -98,6 +98,45 @@ const SERVICE_TIMELINES: Record = { { name: "BOC-3 Update", description: "Updating process agent filing", business_days: 8, status: "pending" }, { name: "Complete", description: "All filings updated under your new entity", business_days: 10, status: "pending" }, ], + // ── Healthcare / CMS provider filings ──────────────────────────────────── + // These submit a signed form to CMS; the WET_SIGNATURE_BUFFER is applied to + // the post-signature steps (see the buffer logic below). + "nppes-update": [ + { name: "Order Received", description: "Payment confirmed, order in queue", business_days: 0, status: "completed" }, + { name: "Document Preparation", description: "Preparing your NPI update for filing", business_days: 1, status: "pending" }, + { name: "Signature Required", description: "Review and sign the certification", business_days: 1, status: "pending" }, + { name: "Filed with CMS", description: "Your signed update is submitted to CMS", business_days: 2, status: "pending" }, + { name: "CMS Confirmation", description: "CMS processes the update (typically 1-2 weeks)", business_days: 10, status: "pending" }, + ], + "npi-reactivation": [ + { name: "Order Received", description: "Payment confirmed, order in queue", business_days: 0, status: "completed" }, + { name: "Document Preparation", description: "Preparing your NPI reactivation", business_days: 1, status: "pending" }, + { name: "Signature Required", description: "Review and sign the certification", business_days: 1, status: "pending" }, + { name: "Filed with CMS", description: "Your signed reactivation is submitted to CMS", business_days: 2, status: "pending" }, + { name: "CMS Confirmation", description: "CMS processes the reactivation (typically 1-2 weeks)", business_days: 10, status: "pending" }, + ], + "npi-revalidation": [ + { name: "Order Received", description: "Payment confirmed, order in queue", business_days: 0, status: "completed" }, + { name: "Document Preparation", description: "Preparing your Medicare revalidation", business_days: 1, status: "pending" }, + { name: "Signature Required", description: "Review and sign the certification", business_days: 1, status: "pending" }, + { name: "Filed with CMS", description: "Your signed revalidation is submitted to CMS", business_days: 2, status: "pending" }, + { name: "CMS Confirmation", description: "CMS/MAC processes the revalidation", business_days: 15, status: "pending" }, + ], + "medicare-enrollment": [ + { name: "Order Received", description: "Payment confirmed, order in queue", business_days: 0, status: "completed" }, + { name: "Document Preparation", description: "Preparing your Medicare enrollment", business_days: 1, status: "pending" }, + { name: "Signature Required", description: "Review and sign the certification", business_days: 1, status: "pending" }, + { name: "Filed with CMS", description: "Your signed enrollment is submitted to CMS", business_days: 2, status: "pending" }, + { name: "CMS Confirmation", description: "CMS/MAC processes the enrollment", business_days: 15, status: "pending" }, + ], + "provider-compliance-bundle": [ + { name: "Order Received", description: "Payment confirmed, order in queue", business_days: 0, status: "completed" }, + { name: "Document Preparation", description: "Preparing your provider compliance filings", business_days: 1, status: "pending" }, + { name: "Signature Required", description: "Review and sign the certification(s)", business_days: 1, status: "pending" }, + { name: "Filed with CMS", description: "Your signed filings are submitted to CMS", business_days: 2, status: "pending" }, + { name: "Screening Complete", description: "OIG/SAM screening completed (no action needed from you)", business_days: 2, status: "pending" }, + { name: "CMS Confirmation", description: "CMS/MAC processes your filings", business_days: 15, status: "pending" }, + ], }; // Default timeline for services without a specific definition @@ -107,6 +146,23 @@ const DEFAULT_TIMELINE: TimelineStep[] = [ { name: "Complete", description: "Filing completed and delivered", business_days: 5, status: "pending" }, ]; +// Services whose Standard path requires an ORIGINAL ink signature on a mailed +// CMS form (verified against the forms: CMS-855I/B/O "original signatures" and +// CMS-10114 "original and signed in ink"). While the ink-signature station is +// being brought online we add a buffer to these services' ETAs so we always +// have time to produce + mail the signed original. Remove the buffer once the +// plotter station is calibrated and in steady-state. +// See docs/state-healthcare-compliance-opportunities.md (wet-signature check) +// and docs/plans/plotter-plan.md. +const WET_SIGNATURE_BUFFER_DAYS = 2; +const WET_SIGNATURE_SLUGS = new Set([ + "nppes-update", + "npi-reactivation", + "npi-revalidation", + "medicare-enrollment", + "provider-compliance-bundle", +]); + router.get("/api/v1/order-timeline/:order_id", async (req: Request, res: Response) => { try { const orderId = req.params.order_id; @@ -136,10 +192,22 @@ router.get("/api/v1/order-timeline/:order_id", async (req: Request, res: Respons const timelines = orders.map((order) => { const slug = order.service_slug as string; const startDate = new Date(order.created_at as string); - const steps = (SERVICE_TIMELINES[slug] || DEFAULT_TIMELINE).map((step) => ({ - ...step, - estimated_date: addBusinessDays(startDate, step.business_days).toISOString().split("T")[0], - })); + // Wet-signature services get a buffer on every step from the signature + // onward, so we always have time to produce + mail the original ink form. + const isWetSig = WET_SIGNATURE_SLUGS.has(slug); + let pastSignature = false; + const steps = (SERVICE_TIMELINES[slug] || DEFAULT_TIMELINE).map((step) => { + if (isWetSig && /signature/i.test(step.name)) { + pastSignature = true; + } + const buffer = isWetSig && pastSignature ? WET_SIGNATURE_BUFFER_DAYS : 0; + return { + ...step, + estimated_date: addBusinessDays(startDate, step.business_days + buffer) + .toISOString() + .split("T")[0], + }; + }); return { order_number: order.order_number,