Telegram notifications:
- Add shared scripts/workers/telegram_notify.py (send_telegram, notify_fulfillment_todo,
create_admin_todo) so every worker alerts the operator the same way; fire-and-forget.
- Fire notify_fulfillment_todo after each admin_todos insert across all 8 service
handlers (9 sites) so no fulfillment task waits unseen.
(Orders + quotes + tickets already notified via checkout/quotes/tickets routes.)
Client portal order progress:
- order-timeline: derive real per-step status from live signals (payment paid,
e-signature signed, fulfillment_status) instead of a static template; add
current_step to the response.
- Extract pure applyLiveStatus into order-timeline-status.ts (DB-free) + unit test
(api/test/test_timeline_status.ts, 8 cases).
- portal /me now returns compliance_orders.fulfillment_status.
- Dashboard renders a client-safe Progress badge (In progress / Action needed /
Filed-awaiting-confirmation / Completed); batches show the most actionable status.
No back-office mechanics exposed.
ERPNext sync parity:
- Create a Sales Order for formation and fcc_carrier_registration orders (previously
only canada_crtc + compliance synced); write erpnext_sales_order back to each table.
Non-blocking, matches existing pattern.
Verified: API tsc clean, timeline unit tests 8/8, Astro build 58 pages,
cms10114/ink/paper_batch Python tests still green, no mechanics leaks.
- 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).
Copy: drop paper/electronic/fax framing across the revalidation + enrollment
marketing pages and the order-confirmation email; present two service tiers:
- Standard filing (no CMS account; we prepare CMS-855, you sign, we submit to MAC)
- Expedited filing (CMS I&A surrogate access; same-day PECOS filing + tracking)
Internal worker todos + the _STANDARD_FILING_SLUGS identifier updated to match.
New scripts/test_healthcare_e2e.py validates the whole order line (slug
consistency x6 places, price agreement, intake field collection+enforcement,
worker dispatch, handler execution producing CMS-855 PDF+anchor, free-tool
action_urls). 45 checks.
Bugs found + fixed by the test:
- medicare-enrollment requires practice_state server-side but the wizard never
enforced it -> orders could be paid then stall. Wizard now requires it.
- determine_form_type defaulted org NPIs to the individual 855I because
enumeration_type is never collected -> wrong form, CMS rejection. Now does a
live NPPES lookup (safe 855I fallback).
- order-confirmation email presents both filing methods: paper CMS-855 (no
account needed, client e-signs one page, we print+mail to their MAC) and
I&A surrogacy (faster, needs CMS account). NPPES-only services note that
surrogacy is required (web-only).
- npi_provider handlers record the access model per service in admin todos.
- marketing copy leads with the lowest-friction paper option.
Root cause of customers being unable to log in: ERPNext (portal.performancewest.net)
is the intended single portal and already surfaces compliance/trucking orders
(performancewest_erpnext/www/orders.py reads compliance_orders by email). But
only the Stripe checkout path provisioned the ERPNext Website User up-front
(findOrCreateCustomer). PayPal / crypto / remediation-pipeline orders go straight
to handlePaymentComplete, which created NO portal user and never set
portal_user_created -> no login + no set-password invite (exactly what happened
to the Paul Wilson / Compound Technologies PayPal order).
- handlePaymentComplete: add ensureCompliancePortalUser() in the shared
post-payment path so EVERY paid compliance order (any payment method) gets an
ERPNext portal account + the set-password invite. Idempotent.
- Guard against placeholder emails (synthetic@/pipeline.com etc): skip portal
provisioning and the set-password invite for non-deliverable addresses.
- compliance-orders API: validate email format AND reject placeholder addresses
at order creation (was: presence-only, so synthetic@pipeline.com passed).
- delivery_worker: never email a set-password invite to a placeholder address.
Note: the legacy PG-customers login (api/routes/portal-auth.ts, /account/*) is
CRTC/formation-era and only backfills canada_crtc_orders/orders, never
compliance_orders. ERPNext is now the consistent portal for compliance.
ROOT CAUSE of orders never fulfilling: the batch Sales Order used the service
SLUG as item_code (e.g. 'mcs150-update') but ERPNext items use the catalog
erpnext_item codes ('MCS150-UPDATE'), so SO creation threw 'Item not found' ->
no SO -> no portal -> no fulfillment. Now maps slug -> erpnext_item (falls back
to COMPLIANCE-SERVICE). DOT ERPNext items were also missing — created them.
Notification: show Subtotal / Discount / Card surcharge / Total so totals like
$35.54 (= $34.50 + $1.04 surcharge) are transparent instead of looking wrong.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Federal DOT services (MCS-150, BOC-3, UCR, authority, D&A, audit, full-compliance,
reactivation, ETA, closeout) now have customer intake pages, so they get an
intake-form link like FCC services instead of the old 'admin-assisted / we're
working on it' message. Only form-less state-level filings stay admin-assisted.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Was reading only updated.rows[0] -> reported a single line item's net as the
'Total' and showed just one service for multi-service batches (e.g. Paul Wilson's
3-service $218 PayPal batch showed as 'mcs150-update $34.50'). Now sums
service_fee - discount + surcharge + gov_fee across all rows and lists every
service.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reads dot_number or frn from intake_data and includes in the
notification. DOT orders show DOT#, FCC orders show FRN.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Was showing service_fee_cents ($69) instead of actual charge ($35.54).
Now subtracts discount_cents and adds surcharge_cents. Also shows
discount line in notification when a promo code was used.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The confirmation email now includes a prominent blue box with
direct links to the intake form for each ordered service. Subject
changed to "Action Required" to prompt the customer to complete it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Free orders bypass Stripe, so the Stripe webhook never fires and the
intake/confirmation email never gets sent. Now trigger
sendComplianceIntakeEmail directly in the $0 bypass flow.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When create-session is called for an order that's already paid (e.g.
free order with page refresh, duplicate submit, or browser retry),
return a success redirect instead of 404. Prevents confusing
"Payment Not Confirmed" errors on the success page.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- discount_codes.allowed_emails: when set, code only valid for listed emails
- Flat discounts now replace bundle discount (don't stack)
- $0 orders skip all payment gateways, mark paid immediately, redirect to success
- FREEDOM249: $249 flat off restricted to 4+ deficiency carriers
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Compliance batch orders now create commission ledger entries when
a discount code (agent referral) is used. Tracks total order amount,
discount applied, and links to the agent for payout processing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Created /js/pw-analytics.js with conversion funnel events
- Added to Base.astro layout (all Astro pages) + 6 static HTML pages
- Events tracked: compliance-check-start, compliance-check-complete,
order-cta-click, checkout-page-view, checkout-start, esign-opened,
esign-submitted, campaign-click (UTM attribution), contact-form-submit
- Server-side payment-complete event from checkout webhook via Umami API
- Auto-tracks any element with data-track="event-name" attribute
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sends to the monitoring bot immediately when payment is confirmed:
- Customer name and email
- Service/slug ordered
- Total amount (includes all fees: service + formation + state + addons)
- Payment method
- Order number and type
Fire-and-forget — never blocks the payment flow.
Requires TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID env vars on API container.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Phase 3-5:
- API: POST /api/v1/fcc-carrier-registration (order creation with pricing)
- API: GET /api/v1/fcc-carrier-registration/:id (status)
- API: GET /api/v1/fcc-carrier-registration/state-fees (formation fees)
- Checkout: fcc_carrier_registration order type with Stripe line items
- Payment handler: dispatch worker + send confirmation email
- Pipeline handler: 8-step CRTC-style pipeline (formation → CORES → 499 →
DC Agent → State PUC → RMD/CPNI/CALEA/BDC → add-ons → final review)
- Job server dispatch map entry
- Service page CTA updated to link to order page
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
set_value doesn't work for child tables like portal_users. Use
updateResource (PUT /api/resource/Customer) which handles it correctly.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Batch invoice creation now calculates actual total from line items
- Fixed JS syntax error: `className = "..." style="..."` was invalid JS
(style= outside string literal caused Unexpected identifier 'style')
- Portal menu: set hide_standard_menu=1 to remove duplicate sidebar items
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Intake email now has "I've completed the delegation →" button
instead of "reply to this email"
- Button links to order success page with action=usac_delegation
- New API: POST /api/v1/compliance-orders/:id/usac-delegation
Records confirmation timestamp in intake_data and logs it
- Removed "reply to this email" from intake email
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds financial_connections with balances permission and prefetch
to Stripe Checkout sessions when payment_method is ACH. This uses
Plaid to verify the customer's bank account balance before accepting
payment, reducing ACH return risk.
- permissions: ["payment_method", "balances"]
- prefetch: ["balances"]
- verification_method: "instant"
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. BDC Yes/No buttons now have "Change answer" undo — clicking
Yes or No is reversible without re-running the check
2. intake_data JSON.parse wrapped in try/catch with error logging
instead of silently returning empty object
3. All CTA price displays use .toFixed(2) for consistent formatting
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. CRITICAL: Add compliance_batch to stripe session tableMap —
session IDs weren't being stored for batch orders
2. CRITICAL: Fix batch orders using order_number instead of batch_id
when storing stripe_session_id
3. MAJOR: Tax deductibility note only shows for compliance orders,
not CRTC/formation/bundles
4. MAJOR: Identity verification fallback changed from localhost:4321
to performancewest.net with warning log
5. MEDIUM: Fix discount rounding — last service absorbs remainder
to prevent cent loss across batch orders
6. LOW: Validate at least one paid service in batch orders
7. Standardize support email to info@performancewest.net everywhere
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sends next-steps email with services list, USAC delegation
instructions for 499-A, and multi-year catch-up note.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>