Commit graph

359 commits

Author SHA1 Message Date
justin
dcd9fb61d0 migration 083: use CREATE INDEX CONCURRENTLY to avoid locking fmcsa_carriers
The original CREATE INDEX (non-concurrent) on a 2M-row table held a SHARE lock
for ~33 minutes, blocking all 25+ DOT checker queries and causing 'Failed to
fetch' for real users. CONCURRENTLY builds the index without a table lock.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:42:47 -05:00
justin
13492af732 dot-lookup: fix hanging FMCSA fetch with AbortController (not AbortSignal.timeout)
AbortSignal.timeout() requires Node 17.3+. The API container likely runs an
older Node version, so timeouts never fired -> fetch hung forever when FMCSA
API is down -> nginx proxy timeout -> 'Failed to fetch' in the browser.

Fix: use AbortController + manual setTimeout() which works on all Node versions.
All 3 external fetch points (fmcsaFetch x2, SOS x2) now actually abort at 5s.

Also: guard final res.json() with !res.headersSent so the 12s deadline fallback
and the normal response path can't double-send.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:36:28 -05:00
justin
cebc432af8 dot-lookup: add 12s hard deadline + reduce FMCSA timeout to 5s
If FMCSA live API is slow (can take 2x 10s = 20s when down), the route would
hang until nginx proxy killed the connection -> 'Failed to fetch'. Now:
- fmcsaFetch timeout: 10s -> 5s (two calls max 10s total)
- SOS entity-status timeout: already reduced to 5s
- 12s hard deadline: if any live API hangs past 12s, immediately return
  census-only data with a 'partial=true' flag so the user gets something

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:34:04 -05:00
justin
e7afc3002e dot-lookup: revert fmcsaFetch wrapping (already null-safe), keep 5s SOS timeout
The bare catch{} introduced a control-flow issue. fmcsaFetch() already returns
null on all errors and never throws, so the try/catch wrapping was unnecessary.
Keep only the SOS timeout reduction (20s->5s) as the actual fix for the nginx
proxy timeout that caused 'Failed to fetch' on slow DOT lookups.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:28:59 -05:00
justin
e0be6468d4 dot-lookup: fix 'Failed to fetch' caused by SOS timeout exceeding nginx proxy limit
Two WORKER_URL/entity-status calls both had 20s timeouts; worst case 40s total
response time exceeds nginx proxy_read_timeout, dropping the connection and
causing the browser to show 'Failed to fetch'. Also wraps fmcsaFetch calls
explicitly so FMCSA API failure still returns full local census data.

- AbortSignal.timeout(20000) -> 5000 on both SOS entity-status calls
- fmcsaFetch carrier + authority calls wrapped in individual try/catch

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:19:10 -05:00
justin
0b7a35a58e trucking campaigns: daily builder + MX verifier concurrency + tracking column
- build_trucking_campaigns.py: nightly script that creates 8 Listmonk campaigns
  per day (4 TZ x 2 types: MCS-150 overdue 2k/TZ, inactive USDOT 1k/TZ)
  at 4AM ET / 5AM ET (CT) / 6AM ET (MT) / 7AM ET (PT). Deduplicates via
  listmonk_sent_at column.
- migration 083: add listmonk_sent_at + listmonk_campaign_type to fmcsa_carriers
- email_verifier.py: bump max_workers from 5 to 20 for 4x faster throughput
- cron: daily pw-trucking-campaigns at 08:00 UTC (3 AM EST)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:07:44 -05:00
justin
54a46062a5 review fixes: wrap-up checkout dead-end, confident entity flag, textarea style
- order/dot-compliance: add carrier-closeout ($199) + entity-dissolution ($49)
  cards so the checker's wrap-up CTA actually resolves (was a dead-end: no
  matching data-slug checkbox to pre-select)
- new-carrier flag: drop the 'not tax advice / we'll confirm' hedge, reframe
  confidently as a fee/cost point (not taxes); only show the Wyoming-LLC caveat
  when Wyoming is actually selected
- checker: fix malformed inline style on the sell-truck textarea (missing ;)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 02:02:20 -05:00
justin
d85fdd36d9 new-carrier wizard: flag corp-favorable states (CA/TN/NY) in the entity step
When forming or operating in CA (gross-receipts fee >$250k), TN ($300 vs $20
report), or NY (LLC publication + filing fee), show an advisory with the reason
and a one-click 'Use a corporation'. Keyed off wiz.entityState/baseState.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 01:47:42 -05:00
justin
ffe6f34bc8 wrap-up: reframe as done-for-you (we file everything; client only cancels insurance etc.)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 01:25:58 -05:00
justin
374db59ba7 checker: add 'not selling' sell-trucks option; remove em dashes from trucking pages
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 01:21:23 -05:00
justin
c98f48848c entity dissolution: $49 add-on to wrap-up + state fees (was $199)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 01:13:19 -05:00
justin
b25d1f5fd3 trucking wrap-up: close-out becomes a paid order + workflow
- Checker closing mode now pitches a done-for-you 'Trucking Wrap-Up' ($199)
  with a buy button to /order/dot-compliance?services=carrier-closeout, instead
  of a lead form. DIY checklist replaced by what's-included list.
- Entity dissolution offered as a paid add-on with the lawsuits/liens/judgments
  warning before dissolving.
- New catalog services: carrier-closeout ($199), entity-dissolution ($199).
- CarrierCloseoutHandler orchestrates the sequential shutdown workflow
  (final MCS-150 out-of-business, MC revoke, UCR cancel, IFTA/IRP + state
  closures; dissolution branch for the add-on) as admin-tracked tasks.
- Sell-your-trucks: single shared form with quick-cash / marketplace / both;
  name field is now a real first+last name (no corp-name prefill).
- tickets categories: add truck_sale_both, drop business_closeout (now an order).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 01:01:02 -05:00
justin
1e34707258 migration 082: widen tickets.category CHECK for lead-capture categories
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 00:50:32 -05:00
justin
0409167e5a tickets API: allow insurance_lead + business_closeout + truck_sale categories
These lead-capture categories were posted by the DOT checker but missing from
VALID_CATEGORIES, so the API rejected them with 400 (insurance_lead too — it
was referenced in the Telegram code but never allowlisted).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 00:49:18 -05:00
justin
5f3a9dc54f web: remove CB 10-codes and ByeTruck name from checker + new-carrier page
- 10-code jokes are email-only now; revert checker/new-carrier CTAs to plain
- Sell-trucks quick-cash flow no longer names ByeTruck or links out; lead still
  routes via the truck_sale_quickcash ticket (internal routing stays generic)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 00:48:12 -05:00
justin
0835358cd4 add resized 536px JPEG banner for trucking emails (lighter, fits display 1:1)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 00:43:58 -05:00
justin
d9ffda27a4 trucking CTAs: CB 10-codes in buttons + compliance-check button on new-carrier page
- DOT checker: '10-4' on Fix My DOT Filings / Get These Handled; '10-7'
  (out of service) on the business close-out CTA
- New-carrier (LLC) page: add a free Compliance Check button in the hero

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 00:07:55 -05:00
justin
c0021c3cd6 DOT checker: add business close-out mode + sell-your-trucks routing
- Intent toggle: 'staying in business' (compliance) vs 'closing my business'
- Closing mode shows a green, personalized wind-down checklist from FMCSA data
  (final MCS-150/USDOT deactivation, MC revoke, UCR, IFTA/IRP, state permits,
  insurance, entity dissolution) + 'let us handle the shutdown' lead capture
- Sell-your-trucks box: quick cash -> ByeTruck referral lead + handoff;
  marketplace -> email capture for follow-up guide
- Deep link via ?intent=closing for the email CTAs

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 23:57:44 -05:00
justin
df48ef786d add CB radio accessories banner image for trucking email campaigns
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 23:43:36 -05:00
justin
2f635227aa improve name-check: match base name without entity suffix (LLC/Inc/Corp), flag close matches 2026-05-30 23:07:52 -05:00
justin
e0ba8acc90 add pipeline orchestrator, mailbox 1583 flow, EIN + virtual-mailbox services
- Pipeline orchestrator: chains sequential fulfillment for new carrier bundles
  (formation → EIN → USDOT → MC → BOC-3 → MCS-150 → D&A → UCR)
- Mailbox setup: Anytime Mailbox provisioning with USPS 1583 e-sign + online notarization
- New services: ein-application ($79), virtual-mailbox ($149/yr)
- Registered all new handlers in SERVICE_HANDLERS
- Pipeline cron: every 5 minutes
2026-05-30 22:56:54 -05:00
justin
e1ece093cd show order timeline with step names + estimated dates on success page
Visual timeline with dots, connecting lines, step names, descriptions,
and business-day estimated completion dates. Fetches from /api/v1/order-timeline.
2026-05-30 22:49:35 -05:00
justin
90a0f983ee add order timeline API: step names + estimated business-day completion dates per service
GET /api/v1/order-timeline/:order_id — returns steps with dates:
- Skips weekends + US federal holidays (matches business_days.py)
- Per-service timelines: MCS-150 (2 days), BOC-3 (3 days), MC Auth (15 days), etc
- Entity upgrade bundle shows full sequential pipeline (10 business days)
- ETA emergency shows same-day processing
2026-05-30 22:48:44 -05:00
justin
ad41de817c BOC-3: use relay_integration.load_card_from_erpnext() for proper card matching 2026-05-30 22:46:52 -05:00
justin
6ca835b1b4 BOC-3: load matching PW card from ERPNext (stripe/paypal/crypto per payment method)
EIN: add handler with IRS hours check (Mon-Fri 7am-10pm ET), dev mode guard
2026-05-30 22:43:30 -05:00
justin
cf270e9f5b add Wyoming formation package doc: full component breakdown, pricing, wizard logic, photo ID reuse, annual compliance, LTV estimates 2026-05-30 22:34:51 -05:00
justin
7197b95946 add virtual mailbox notes: Anytime Mailbox already in use, photo ID reuse for 1583 2026-05-30 22:32:47 -05:00
justin
260bfd04c3 add foreign qualification fee reference: all 50 states, one-time vs annual, wizard pricing guidance 2026-05-30 22:30:07 -05:00
justin
6dd311f375 add dev mode guards: skip FMCSA submission, fax, and web filing in non-production environments 2026-05-30 22:28:59 -05:00
justin
d6704e850e rebuild new carrier page as 4-step wizard: fleet profile → entity strategy → services → checkout
Step 0: fleet size, vehicle type, cargo (hazmat), interstate/intl, base state, operating states, for-hire/private
Step 1: existing entity or new, home state vs Wyoming optimization, name check (SOS + FMCSA parallel)
Step 2: auto-populated services from matrix, bundle detection, non-discountable items marked
Step 3: checkout with Klarna 4 payments, discount codes, batch order flow
2026-05-30 22:24:07 -05:00
justin
aa7ed5efe9 wire MCS-150 handler to full pipeline: PDF fill → MinIO → e-sign → web/fax submit → attestation
- Fills official MCS-150 PDF with intake data (pypdf)
- Uploads to MinIO for storage
- Creates esign_records row with perjury declaration
- Sends e-sign link to customer (JWT, 7-day expiry)
- After sign: submits via ask.fmcsa.dot.gov (3x) → fax fallback
- Generates attestation cover page + digital signature
- Updates order with filing status, method, screenshots
- Creates admin todo for verification
2026-05-30 22:13:18 -05:00
justin
21b94c9ea9 add New Carrier Setup link to nav across all static pages
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 22:12:23 -05:00
justin
479f3dfc45 add entity upgrade bundle service + deploy completion/IMAP crons
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 22:12:11 -05:00
justin
6c75a27893 add vehicle buy/sell referral topics: ByeTruck, Kelly, Big Rig Lending, Truck Trader 2026-05-30 21:37:08 -05:00
justin
ad3d189b2b post-completion flow: survey, referral program, review ask
- Migration 081: referral_codes, referral_uses, exit_surveys tables
- API: POST /api/v1/survey, POST /api/v1/referral/check, GET /api/v1/referral/:email
- Worker: completion_emails.py — sends completion + 24h follow-up (survey + referral)
- Survey page: /survey/?order=X&rating=N — star rating, feedback, Google review ask
- Referral: REF-FIRSTNAME codes, $25 credit per referred order, no limit
- Low ratings (1-3 stars) trigger Telegram alert for admin follow-up
- Cron: every 15 minutes
2026-05-30 21:22:14 -05:00
justin
6b20ba7f08 add post-completion flow: exit survey, Google review ask, referral program spec 2026-05-30 21:17:01 -05:00
justin
4cde6bbb4a add financing/factoring interest checkbox on success page + campaign topics 16-17
- Checkbox on post-order success page: 'Interested in freight factoring?'
- Stores lead via /api/v1/insurance-leads with source=financing_interest
- Added factoring + fuel card campaign topics to docs
2026-05-30 21:15:25 -05:00
justin
0c9a500fee correct campaign topic #1: MC numbers NOT eliminated yet, still proposed 2026-05-30 21:12:31 -05:00
justin
91501f78cd add 15 trucking campaign topics with priority matrix — sourced from forums + FMCSA changes 2026-05-30 21:11:18 -05:00
justin
08e80e11f9 add POST /api/v1/dot/name-check: parallel SOS + FMCSA name availability check
- Checks state SOS for entity name availability (via workers adapter)
- Checks FMCSA census for exact + fuzzy name matches
- Returns: sos_available, fmcsa_in_use, fmcsa_matches, combined 'available' flag
- 20s timeout on SOS lookup, FMCSA query is instant (local DB)
2026-05-30 21:02:32 -05:00
justin
340a364d8c add insurance + state compliance upsells to success page for trucking orders
- Insurance lead capture: pre-filled name/email from order, submits to /api/v1/insurance-leads
- State compliance CTA: shown for new carrier orders, links to DOT compliance page
- Only shown for trucking/DOT order slugs
2026-05-30 20:57:30 -05:00
justin
29ff57694e add new carrier order page with Klarna 4-payments option
/order/trucking-new-carrier/ — for new trucking businesses without a DOT:
- New Carrier Starter Bundle 99 (LLC + USDOT + MC Auth + BOC-3 + MCS-150 + D&A)
- Individual service cards with bundle auto-toggle
- Klarna 4 payments, Card, PayPal, ACH
- No DOT pre-fill (new carriers)
2026-05-30 20:54:35 -05:00
justin
c7251b8aac Klarna: say '4 payments' instead of 'Pay Later' 2026-05-30 20:50:44 -05:00
justin
095838a015 add Klarna Pay Later option to DOT compliance order page 2026-05-30 20:50:20 -05:00
justin
58aa2cf78e map all FMCSA status codes to services: OOS→ETA ($499), Inactive→reactivation, Revoked/Suspended→reinstatement
- OOS (Out of Service): RED, urgent messaging, maps to Emergency Temporary Authority $499
- Inactive: YELLOW, reactivation $149
- Not Authorized: YELLOW, new USDOT + MC authority
- Revoked: RED, new authority application
- Suspended: YELLOW, compliance resolution + reinstatement
- Cancelled: YELLOW, new registration
- Each status has specific actionable messaging with PW CTA
2026-05-30 20:48:47 -05:00
justin
b106a88e90 add USDOT reactivation service ($149) + map inactive status to reactivation CTA
- New service: usdot-reactivation — filed via ask.fmcsa.dot.gov (sub-cat 302)
- Inactive carriers see 'PW can handle reactivation, no Login.gov needed'
- Compliance checker maps inactive operating status to reactivation service
2026-05-30 20:40:56 -05:00
justin
2b8e2cf7ea fix: inactive carriers show yellow warning instead of green, even if FMCSA says 'allowed' 2026-05-30 20:39:28 -05:00
justin
18fb45dba0 fix operating status: translate FMCSA status codes to human-readable labels (A=Active, I=Inactive, etc) 2026-05-30 20:38:22 -05:00
justin
4345a7546d yellow CTA: list specific state/entity items needing attention instead of generic message 2026-05-30 20:36:24 -05:00
justin
2b67420624 fix disclaimer: we ARE a compliance firm, only disclaim legal advice 2026-05-30 20:35:20 -05:00