Commit graph

263 commits

Author SHA1 Message Date
justin
2dacf1ea0e FMCSA enrichment: OOS orders bulk download + authority/insurance API lookup
- Downloads 389K OOS orders from Socrata, merges into fmcsa_carriers
- Batch enriches authority status + insurance filing via FMCSA API
- Adds columns: oos_active, authority_status, insurance_*_on_file, etc.
- Rate limited to 1 req/sec for API calls
- Prioritizes campaign-eligible for-hire carriers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 14:46:40 -05:00
justin
6f3ad1b686 Customer dashboard: order tracking + portal login
- New page: /portal/dashboard/ — customer can view all orders
- Auth: cookie-based login, shows auth modal if not logged in
- Orders grouped by batch, filtered by DOT/FCC tabs
- Shows service name, amount, discount, status badge, payment method
- Portal API: /api/v1/portal/me now returns compliance_orders

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 14:20:58 -05:00
justin
1cfda2c119 Fix census download crash at 100K: integer out of range
safe_int now clamps values to PostgreSQL INTEGER max (2.1B) and
handles scientific notation. Mileage columns changed to BIGINT
on prod since carriers can have >2B annual miles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 13:41:24 -05:00
justin
b59b266a80 MCS-150 intake: add encryption notice, EIN field, photo ID upload
- Security notice: SSL encryption, encrypted at rest, no third-party sharing
- EIN field added (required for MCS-150 form field 19)
- Photo ID upload with camera capture on mobile
- ID auto-deleted after filing processed
- Preview with remove button

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 13:28:43 -05:00
justin
a265990351 Add official FMCSA MCS-150 fillable PDF forms
MCS-150 (standard), MCS-150B (hazmat), MCS-150C (intermodal).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 13:08:32 -05:00
justin
d32ef991b8 Fix Dockerfile: use JSON array syntax for filenames with spaces
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 13:07:26 -05:00
justin
02b65fc37a Fix Dockerfile: quote MCS-150 filenames with spaces
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 13:06:58 -05:00
justin
8ab5768606 Add MCS-150 PDF forms to workers Docker image
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 13:05:26 -05:00
justin
b2a4a48610 Add pypdf to requirements for MCS-150 form filling
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 13:00:20 -05:00
justin
1f24255358 MCS-150 official PDF filler — fills actual FMCSA fillable form
Uses pypdf to fill the official MCS-150/150B/150C fillable PDFs.
Maps intake data to 289 form fields (text + checkboxes).
Supports form type detection (standard vs hazmat vs intermodal).
Produces ready-to-fax PDF from intake data.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 12:59:15 -05:00
justin
e82aa0b8c2 Fix PayPal capture for compliance orders + MCS-150 form generator
PayPal capture was defaulting to canada_crtc_orders table for all
non-formation orders. Now properly routes compliance_batch orders
to compliance_orders table with batch_id lookup. Also infers
order type from ID prefix (CB-=batch, CO-=compliance, FO-=formation).

MCS-150 form generator: produces DOCX with fax cover sheet + filled
MCS-150 form for faxing to FMCSA at 202-366-3477.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 11:34:16 -05:00
justin
d2b42cd4b8 Add MCS-150 intake form for biennial update orders
Collects all fields needed for FMCSA Form MCS-150:
- Legal name, DBA, DOT#, MC#
- Principal business address
- Entity type, carrier operation, interstate/intrastate
- Fleet info (power units, drivers, annual miles)
- 29 cargo type checkboxes
- Authorized signer name and title

Filed via fax to FMCSA at 202-366-3477 (VitalPBX).
Previously was review-only with no data collection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 11:29:05 -05:00
justin
b5cf4151ca Add trucking/DOT terms to homepage description
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 21:14:52 -05:00
justin
46bcd257a2 Fix Services dropdown on DOT order page — add hoisted JS
Page was missing the hoisted.yFz1BYXO.js script that handles
nav dropdown toggle, mobile menu, auth, and subscribe modal.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 16:34:20 -05:00
justin
3a197f591f Sync nav/footer across all 62 static HTML pages
Bulk updated nav to include Trucking/DOT section in desktop dropdown,
mobile menu, and footer across all public/ HTML pages. Consistent
site chrome everywhere now.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 16:31:03 -05:00
justin
d4a738d28d Remove "licensed" language from trucking pages
No such thing as a "licensed compliance firm" — changed to
"Professional compliance consulting" and "Experienced Compliance Team".
Keeps factual descriptions only to avoid any UPL/misrepresentation risk.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 16:26:40 -05:00
justin
a720c0df6b Rebuild trucking services page with full nav/footer + inline styles
Complete rewrite: was missing nav, footer, had wrong links pointing
to compliance checker instead of order page, and used Tailwind
classes that don't render in public/ HTML. Now uses California page
as template with proper site chrome and inline styles.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 16:23:10 -05:00
justin
1f76955937 Fix bundle CTA button on trucking services page (use inline styles)
Tailwind classes don't render in public/ static HTML files.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 16:18:14 -05:00
justin
c47c52e9e8 Remove external action_url links from compliance checker
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>
2026-05-29 16:16:44 -05:00
justin
da00817174 Show DOT# or FRN in Telegram order notifications
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>
2026-05-29 15:55:41 -05:00
justin
9579d74d7d Fix Telegram notification: show actual paid amount after discount
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>
2026-05-29 15:51:34 -05:00
justin
607412e182 Add PayPal as payment option on DOT order page
3-column grid: Card | PayPal | ACH. PayPal logo added to security
badges. Checkout API already supports paypal payment_method.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:45:20 -05:00
justin
1633522e95 Smart bundle promotion: auto-replace individual services with bundle
When 3+ services are pre-selected from URL and 2+ are bundle components,
automatically check the bundle and uncheck the individual items.
Also triggers bundle uncheck logic after any URL pre-selection.
Prevents showing bundle AND its individual services simultaneously.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:44:34 -05:00
justin
11e8fad4b1 Fix name search crash: guard against missing/non-array results
Added Array.isArray check and error message display for API errors.
Prevents "Cannot read properties of undefined (reading 'length')".

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:42:40 -05:00
justin
8902912bfd Add trust signals, security badges, and closing language to DOT order page
- Trust bar below hero: licensed firm, 1-2 day turnaround, Stripe secure, 5K+ carriers
- Payment security badges: Stripe logo, 256-bit SSL, PCI Compliant
- About Performance West section below payment: company description,
  Wyoming registration, nationwide service, phone number
- Payment reassurance: Stripe processing, no card storage, compliance team

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:39:59 -05:00
justin
763100f664 Fix bounce watcher: pass campaign_uuid to Listmonk webhook
Bounces showed 0 in campaigns because the webhook didn't include
campaign_uuid. Now fetches UUID of running campaign via API and
includes it in bounce reports. Refreshes every 100 messages.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:32:48 -05:00
justin
72f692007e Fix per-item discount: re-query checkboxes dynamically
checkboxes were captured at page load before state services rendered.
Now uses getCheckboxes() to re-query each time + delegated change
listener for dynamically added checkboxes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:09:52 -05:00
justin
472e9f92dc Fix discount fetch: trigger on any pre-filled value + debounced input
fetchDiscount now fires on page load if promo field has ANY value
(not just from URL param), plus debounced on input events.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:07:45 -05:00
justin
e6150bcdce Show per-item discount amounts on order page
Each service line item now shows its price and a green -$X discount
next to it when a coupon is applied. Non-discountable items (BOC-3,
D&A, MC Authority) show price only. Gov fees shown as sub-items.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:04:17 -05:00
justin
4e7493b088 Mark MC Authority as non-discountable ($300 FMCSA gov fee)
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>
2026-05-29 15:02:31 -05:00
justin
79fb4722f1 Mark BOC-3 as non-discountable (passthrough cost to Process Agent LLC)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:00:46 -05:00
justin
651f1984d9 Fix discount display on DOT order page
Order page now fetches discount code from API and shows:
- Discount line item with percentage and savings amount
- Non-discountable items excluded (D&A)
- Auto-fetches on page load if ?code= param present
- Re-fetches on promo field blur
- Green "You save $X!" text

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:54:50 -05:00
justin
78ed1db15a Recalculate bundle pricing + bundle auto-uncheck individual items
- DOT Full Compliance Bundle: $499 → $399 (saves $376 vs $775 individual)
- State Compliance Bundle: $599 → $499 (saves $297 vs $796 individual)
- D&A marked non-discountable (passthrough cost to testing provider)
- Order page: selecting a bundle auto-unchecks its individual components
  via data-bundle attribute listing component slugs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:49:59 -05:00
justin
4cfcb6a50c Add dnspython to requirements for email verifier
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:37:36 -05:00
justin
ed0a44645e Email verifier: add catch-all domain detection via random probe
Before checking the real address, sends a random 20-char address to
the domain. If the server accepts it (250), the domain is catch-all
and individual verification is meaningless. Result cached per domain.
Existing known catch-all list (gmail, outlook, etc.) still bypassed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:34:23 -05:00
justin
258e384f95 Fix state list import: use individual subscriber creates instead of bulk
Listmonk bulk import API returns 400. Switch to individual POST
/api/subscribers with 409 conflict handling (update existing subs
to add them to the new list). Progress logging every 200 records.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:26:44 -05:00
justin
4df73337b8 Add state-targeted campaign creator (CA, OR, NY)
Script creates Listmonk campaigns with state-specific content:
- California: MCP + CARB + CHP CA Number + insurance
- Oregon: Weight-Mile Tax + IRP + ODOT authority
- New York: HUT + insurance ($1.5M NYC) + intrastate authority

Usage: python3 scripts/create_state_campaigns.py california

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:25:12 -05:00
justin
ba3eb30b58 Add trucking system documentation and architecture SVG
trucking-system.md: comprehensive doc covering data pipeline, compliance
checker (14 checks), 21 service slugs, vendors, database tables, frontend
pages, order flow, and campaign segmentation (29,792 eligible).

trucking-architecture.svg: visual diagram of full system — data sources,
processing layer, database, frontend, campaigns, and order flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:10:57 -05:00
justin
f34df45e5f Add New York and Florida trucking compliance landing pages
New York: HUT (18K lb threshold), IRP, IFTA, intrastate authority,
$1.5M insurance in NYC.

Florida: 3rd largest market, IRP, IFTA, intrastate authority,
no weight tax, no emissions — carrier-friendly state.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:08:34 -05:00
justin
4aff121c0b Fix interstate detection: use carrier_operation code A, not text match
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>
2026-05-29 14:01:18 -05:00
justin
3b2ae6b050 Add Texas and Oregon trucking compliance landing pages
Texas: IRP, IFTA, intrastate authority, state insurance focus.
Largest carrier market — no weight-distance tax.

Oregon: Weight-Mile Tax (unique, replaces diesel tax), IRP, IFTA,
ODOT Certificate of Authority, ACT emissions.

Both follow California page template with orange theme, inline styles,
full nav/footer, SEO meta tags, and service pricing cards.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:00:33 -05:00
justin
68d8a9c479 DOT checker: state service recommendations + action URLs + yellow CTA
- State-level yellow checks now map to recommended services in CTA
  (IRP, IFTA, weight taxes, CA MCP, intrastate authority)
- State param passed through to order page (?state=XX)
- Action URLs rendered as "Learn more" links on check cards
- New yellow-only CTA: "Federal filings look good! Review state compliance"
  shown when no red issues but state warnings exist

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 13:33:04 -05:00
justin
46411c09c6 Add Playwright automation for BOC-3 filing on processagent.com
- boc3_playwright.py: 4-step form automation (company info, contact,
  account, payment) using patchright/undetected Playwright
- Payment with PW company card ($25/filing), credentials from env
- CAPTCHA detection — falls back to admin todo if reCAPTCHA triggers
- boc3_filing.py: process() tries Playwright first, falls back to
  manual admin todo on failure
- Env vars needed: PW_CARD_NUMBER, PW_CARD_CVC, PW_CARD_EXP_MONTH,
  PW_CARD_EXP_YEAR, BOC3_ACCOUNT_PASSWORD

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 13:24:12 -05:00
justin
584f887f82 Extend FMCSA flagger with state-level deficiency flags
- Interstate carriers flagged for IRP/IFTA needs
- Weight-distance tax flags (OR/NY/KY/NM/CT)
- State carrier permit flags (CA MCP, etc.)
- Emissions flags (CA CARB, ACT states)
- Intrastate authority flags (29 states, for-hire only)
- New --state-lists flag creates state-targeted Listmonk lists
  (CA, OR, NY, KY, NM, CT, TX, FL)
- Stats now include state-level counts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 13:03:49 -05:00
justin
e473953fef Update BOC-3 handler: Process Agent LLC (Registered Agents Inc)
ProcessAgent.com is subsidiary of Registered Agents Inc. $25/yr
blanket BOC-3, no API, will automate via Playwright. Updated
partner details, admin todo steps, removed dead API stub.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 13:00:31 -05:00
justin
3385ad84a4 Add Trucking/DOT section to pricing page
11 federal + state services listed with prices and turnaround times.
DOT Full Compliance Bundle ($499) and free DOT Compliance Check CTAs.
Orange header matching the trucking brand color.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 12:53:47 -05:00
justin
f1027694a3 Add interest field to mailing list subscribe (telecom/trucking/formation)
- 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>
2026-05-29 12:50:27 -05:00
justin
33da00fd89 50-state trucking compliance: services, checker, order page, CA landing
- Migration 079: state_trucking_requirements table seeded for all 51 jurisdictions
  (IRP, IFTA, weight-distance taxes, MCP/CARB, intrastate authority, state DOT)
- Migration 080: carrier_operating_states tracking table
- 13 new state trucking services in catalog ($99-$599)
- StateTruckingHandler with state-specific admin todos
- DOT compliance checker: 7 new state-level checks (IRP, IFTA, weight tax,
  MCP/CARB, emissions, intrastate authority, state DOT number)
- New API endpoint: GET /api/v1/dot/state-requirements
- DOT order page: state compliance service cards with auto-preselect
- California trucking landing page (MCP + CARB + IRP + IFTA)
- Fix: DOT checker nav missing Trucking/DOT section
- Fix: All 8 DOT intake pages missing style block (dangling text)
- Fix: DOT confirmation email now says "Order Confirmed" not "Action Required"
- Fix: MCS150/BOC3/StateTrucking handlers missing async process() method
- Fix: StateTruckingHandler connection leak + slug resolution

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 12:46:33 -05:00
justin
c80f3a408a Fix: generic review step text (was FCC/USAC specific)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 00:49:18 -05:00
justin
e67df3c4c3 DOT intake: review-only (no telecom entity step), email verifier,
updated flagger excluding 4+ year stale carriers

- Intake manifest: DOT services use ["review"] only, skipping the
  telecom entity step with FRN/USAC fields
- Flagger: excludes 4+ year overdue carriers from campaign (spam
  trap risk). 18,277 safe targets from 100K records.
- Email verifier: self-hosted MX + SMTP verification tool

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 00:29:28 -05:00