Don't send users to FMCSA portal or state agency sites — keep them
on our site to order services through us. Removed all action_url
from API responses and "Fix this" / "Learn more" links from frontend.
Co-Authored-By: Claude Opus 4.6 (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>
Non-discountable services: BOC-3 ($25 vendor), D&A (~$100 provider),
MC Authority ($300 gov fee). All other DOT services are pure labor.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FMCSA census carrier_operation is single-letter: A=Interstate,
B=Intrastate Hazmat, C=Intrastate Non-Hazmat. Previous code searched
for "interstate" in text which never matched. Now 22,089 interstate
carriers will be properly flagged for IRP/IFTA.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Footer subscribe modal: new "I'm interested in" dropdown with 3 options
- Hoisted JS: reads interest field, validates selection, passes to API
- Subscribe API: routes to different Listmonk lists by interest
(telecom→list 3, trucking→list 8, formation→list 9)
- Interest stored as subscriber attribute for campaign segmentation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Order page: insurance referral checkbox (pre-checked) shown when
?ins=1 from checker or carrier has insurance gap. Flag stored
in intake_data.insurance_referral_requested.
- Checker CTA passes &ins=1 when insurance issues found.
- MCS-150: use mcs150Outdated=N from FMCSA API to show green even
without exact date. Fixes "Filing date not available" for carriers
not in local census.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1. Insurance "on file" check: undefined !== null was true, falsely
showing green. Changed to !!field && field !== "0".
2. Insurance lead ticket: filtered for c.id === "insurance" but
actual IDs are insurance_bipd/cargo/bond. Fixed to match prefix.
3. Bundle pricing: was $499 for $376 of services (MORE than
individual). Now includes Safety Audit Prep ($399), making
individual total $775 and bundle saves $276.
4. Order page submit button: inline styles for visibility
(bg-orange-500 not in Astro CSS).
UCR $46 gov fee confirmed correct for 2026 (fees stayed flat).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
API: Split "Insurance Filing" into separate checks:
- Liability Insurance (BIPD) — BMC-91/91X
- Cargo Insurance — household goods
- Broker Bond / Trust Fund — BMC-84/85 ($75K minimum)
Each has its own clear label and specific remediation detail.
Frontend: Convert CTA box, insurance lead capture, and "looking good"
box from Tailwind classes to inline styles (Tailwind classes not in
Astro compiled CSS for static public/ files).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tries local fmcsa_carriers table first (ILIKE partial match).
If no results, falls back to FMCSA QCMobile API name search.
Ensures name search works even before full 2M census is loaded.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
GET /api/v1/dot/lookup?dot=XXXXXX — live compliance check combining
local census data + FMCSA QCMobile API. Checks:
- Operating status (allowed to operate Y/N)
- MCS-150 biennial update (overdue detection)
- Insurance filing (BIPD, cargo, bond)
- Safety rating (S/C/U)
- Operating authority status
- Out-of-service rates vs national average
- Crash record
GET /api/v1/dot/search?name=Acme — name search against local census
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>
The /api/v1/discount/:code endpoint now checks allowed_emails when
an email is provided. If the email isn't in the allowed list, returns
valid:false so the frontend doesn't show a fake discount. The promo
field is cleared and unlocked if validation fails.
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>
Was returning 502 early instead of throwing to trigger the catch block
where the local fcc_499_filers fallback lives.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
FCC/Akamai is blocking our server IP (403). Name search now falls back
to querying the local fcc_499_filers table (20K+ records) when the
live FCC search fails.
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>
- Checkout page reads ?code= or ?promo= from URL, pre-fills and locks the
promo field, shows the promo discount in the summary instead of the 15%
bundle discount
- API: when a promo code % >= bundle %, replace the bundle discount entirely
instead of stacking (e.g. MEMORIAL25 at 25% replaces the 15% bundle)
- Also checks discount code expiration in the query
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>
Check objects use status field (red/yellow/green), not severity
(critical/major/minor). Logging was always recording 0 issues.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Was only reading pdf_checks, missing structured_checks. Also skip
minor-only issues — show major/critical that match email campaign data.
This fixes the "clean" result for carriers our audit flagged as deficient.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Loading message: shows estimated time (30-90 seconds) + rotating status
updates (RMD, CPNI, USAC, BDC, STIR/SHAKEN, compiling report)
- Timeout increased to 90s (was 60s)
- Error messages: "try again in a few minutes" (not "moments" or "check internet")
- New compliance_check_log table: logs every FCC lookup with FRN, entity,
IP, user agent, referrer, issue count, severity, response time
- Enables conversion funnel analysis and follow-up
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>
Reusable signing flow: service handler generates document → inserts
esign_records row → emails JWT link → client reviews PDF + signs →
API stores signature + resumes pipeline. Works for RMD, CPNI, CALEA,
499-A engagement, discontinuance, CRTC, and any future doc types.
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>
Critical #1 — CRTC: Fix undefined 'province' variable (canada_crtc.py:1322)
Crashes every order at Step 6 document generation. Replaced with
order_data.get("custom_incorporation_province", "BC").
Critical #2 — FCC Carrier Reg: Add State PUC state picker
The order page collected "1/few/nationwide" but API expected an array
of state codes. Added a multi-state checkbox grid that appears when
State PUC add-on is checked. Sends puc_states: ["CA","NY",...] in
service_wizard. Price updates per-state ($399 × count).
Critical #3 — Compliance: Add REQUIRED_FIELDS for fcc-499q and
fcc-499a-discontinuance. Without these, intake validation was
completely skipped — invalid data accepted silently.
High #4 — FCC Carrier Reg: Don't mark D.C. Agent complete
prematurely. Was calling _update_step() right after creating the
admin todo. Now waits for admin to confirm NW order is placed.
High #5 — Compliance: Add fcc-499q and fcc-499a-discontinuance to
REQUIRES_ENTITY_FRN set. Both require FRN for USAC filing.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
After 499-A+Q bundle is filed, the handler now creates actual
compliance_orders for each remaining quarterly 499-Q filing:
Schedule: Q1 due Feb 1, Q2 due May 1, Q3 due Aug 1, Q4 due Nov 1
Each quarterly order:
- Created as paid (covered by bundle price)
- Has due_date, quarter, period_end_date in intake_data
- Links to parent 499-A order
- Tracks reminder status (30d/14d/7d sent flags)
Notification worker (quarterly_499q_notify.py):
- Runs daily at 8am CT via systemd timer
- Sends HTML reminder emails at 30, 14, 7 days before due
- Email includes intake link for client to submit quarterly data
- Late warning at 7 days: "USAC may estimate higher contributions"
- Idempotent: won't re-send same reminder level
Added fcc-499q service slug ($0, not sold standalone).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New service slug fcc-499a-zero for carriers with no telecom revenue:
- $179 instead of $499 (no revenue analysis needed)
- Minimal intake: entity, officer, filer ID, filing type only
- Skips revenue schedules (blocks 3-4), USF calculations (block 5),
traffic study upload, and revenue workbook generation
- Fills blocks 1-2 and 6 only, all revenue lines left as zero
Compliance checker: shows both options (mutually exclusive checkboxes)
Order page: maps form_499a_zero to fcc-499a-zero slug
Handler: detects slug and skips revenue pipeline
DC Agent shown when either 499-A variant is checked
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
STIR/SHAKEN card creates confusion with OCN bundling on the order
page — if carried over, it doesn't auto-select OCN. Self-reported
RMD status also doesn't reliably indicate actual compliance.
Reverted to hidden (computed internally but not shown to users).
Removed STIR toggle and pending-question watcher for it.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
BDC Voice Subscription filing is required for all retail voice
providers (VoIP, CLEC, wireline) even without broadband service.
The compliance checker was asking about broadband first, which
caused voice-only carriers to overlook their BDC Voice obligation.
- Renamed card: "BDC Filing (Broadband + Voice Subscription Data)"
- Reversed question order: ask retail voice first, then broadband
- "No" for voice now says "No, or wholesale only" (wholesale exempt)
- Voice-only retail carriers correctly flagged for BDC Voice filing
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Uncomment STIR/SHAKEN check in fcc-lookup.ts — shows self-reported
implementation status from RMD filing
- Add toggle: "Do you originate calls or only terminate?"
- Terminate only → green, signing cert not required, file RMD as
partial implementation
- Originate or both → red, must have own STI certificate as of
June 2025
- Toggle integrates with pending-question system (CTA waits for answer)
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>
Phase 1-2 of the new registration product:
- Migration 075: fcc_carrier_registrations table with full pipeline status,
service wizard answers, entity choice, pricing, idempotency tracking
- Order page with 5-step wizard:
1. Service wizard (voice/broadband/wholesale + delivery method + infra needs)
2. Registration checklist (auto-determined + add-ons with dynamic pricing)
3. Entity choice (existing FRN search OR new formation with nexus guidance)
4. Contact & officer info
5. Review & payment with engagement clickwrap
Still needed: API endpoint, checkout integration, worker pipeline handler.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Updated across 61 static HTML files (nav links), bundles catalog,
service page title/description/heading, and llms.txt.
URL stays /services/telecom/ipes-isp (no redirect needed).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>