Commit graph

208 commits

Author SHA1 Message Date
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
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
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
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
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
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
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
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
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
justin
6dd2fc6e56 add disclaimer + recent update notice to DOT compliance check results 2026-05-30 20:33:10 -05:00
justin
efbf849b54 fix: recommendedServices undefined in yellow-only CTA (caused 'length' error on DOTs with 0 red issues) 2026-05-30 20:29:37 -05:00
justin
ed45265793 add null guard in renderResults to prevent 'cannot read length' error 2026-05-30 20:23:10 -05:00
justin
77c3e8e3e3 add progress steps to DOT compliance checker loading state
Shows animated step-by-step progress instead of generic spinner:
- Looking up FMCSA registration...
- Checking safety record...
- Verifying insurance filings...
- Reviewing operating authority...
- Checking state requirements...
- Verifying business entity status...
Each step gets a green checkmark as it 'completes'
2026-05-30 20:19:20 -05:00
justin
e2313bcc5e add blur detection + Ollama ID validation + corporate check for all carriers
- Client-side: Laplacian variance blur detection in photo quality check
  (very blurry / somewhat blurry / acceptable / good)
- Server-side: async Ollama vision model validates uploaded image is a
  real government ID (minicpm-v:8b), flags non-ID uploads
- Corporate check: sole proprietors now get yellow 'form an LLC' upsell,
  formal entities get annual report/RA reminder
2026-05-30 19:17:31 -05:00
justin
ca7af40ceb update photo ID instructions: suggest QR code first for desktop users 2026-05-30 19:07:13 -05:00
justin
e2c7cc582b increase font sizes in photo ID section for readability (min 14px) 2026-05-30 18:15:22 -05:00
justin
e0fc4810d1 show proper error on phone when photo ID upload fails to MinIO 2026-05-30 18:13:18 -05:00
justin
f60c5229ab Fix mobile photo upload: resize large camera images + increase body limit
Mobile cameras produce 8-12MB photos. Now:
- Canvas-based resize to max 2000x1500 before upload
- JPEG compression at 0.7-0.85 quality
- Express body limit increased to 5MB for id-upload route
- Falls back to raw upload for small images and PDFs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 17:24:16 -05:00
justin
04861ccfe0 Fix QR code: add inline script right at image element for immediate generation
Previous approach relied on the main is:inline script block which
could be blocked by FCC step crashes. New approach: tiny self-contained
script right next to the QR img element, runs immediately, fetches
upload token and generates QR. Falls back to page URL on failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 17:20:04 -05:00
justin
66bd1306e3 Accept TIFF images for photo ID upload (scanner default format)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 16:28:22 -05:00
justin
d2f9e642d4 Hide QR code on mobile phones, auto-trigger camera on mobile
QR code hidden via CSS on screens < 640px (phones). On mobile,
file input gets capture=environment so tapping the button opens
the camera directly. Tablets still show QR code.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 16:25:52 -05:00
justin
1535acb413 Complete phone-to-desktop photo ID upload pipeline
- API: POST /api/v1/id-upload/token generates upload token
- API: POST /api/v1/id-upload/:token receives base64 image, stores in MinIO
- API: GET /api/v1/id-upload/:token/status returns upload status + thumbnail
- Mobile page: sends image as base64 with upload_token
- Desktop intake: requests token, generates QR with upload URL, polls
  every 3s for phone upload, auto-shows thumbnail when detected
- MinIO storage with presigned URLs for thumbnails
- Compliance order intake_data updated with photo_id_uploaded flag

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 16:24:35 -05:00
justin
1611b67543 Add mobile photo ID upload page at /portal/upload-id/
Dedicated mobile-friendly page for phone camera ID capture:
- Big "Take Photo of ID" button with camera capture
- Image preview with basic quality check
- Submit uploads to API with JWT auth
- Success/error states with retry
- QR code on desktop intake links here instead of full form

Still needs: API upload endpoint, polling from desktop, OCR validation

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 16:20:27 -05:00
justin
daf6d1f831 Always show QR code for phone photo upload — no click to reveal
QR code displayed inline below the upload button so truckers can
immediately scan with their phone to take a photo of their ID.
Clear instructions: 'Scan with your phone camera to take a photo'

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 16:17:17 -05:00
justin
73a10d4a0f Simplify photo ID upload: clear instructions for truckers
- Yellow instruction box explains 3 methods in plain English
  (phone photo, computer upload, scanner)
- One big orange "Add Photo of Your ID" button
- Webcam + QR code kept in code but simplified UI
- Accepted formats note

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 16:11:49 -05:00
justin
3423b4914a Relabel photo ID buttons: Upload File/Scan + Use Webcam + scanner instructions
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 16:09:47 -05:00
justin
39fb1c9998 Webcam capture for photo ID via getUserMedia
Desktop users can now use their webcam to photograph their ID:
- Click "Use Camera" → browser requests webcam permission
- Live video preview with orange guide rectangle for ID placement
- Capture button takes high-res JPEG (1280x720)
- Cancel button stops webcam and returns to upload options
- Captured image goes through same quality check flow
- Works on Chrome, Firefox, Edge, Safari (desktop + mobile)
- No libraries needed — native WebRTC API

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 16:09:02 -05:00
justin
c40dfb552e Auto-save intake data to server after every step
Intake data now persists to DB after each step completion (non-blocking).
If browser crashes, data is recoverable from compliance_orders.intake_data.

Partial saves (_partial: true) only update intake_data without changing
payment_status or marking intake_data_validated. Final submit still
triggers the full validation + worker dispatch flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 16:01:20 -05:00
justin
beb23d777e Photo ID quality check after upload
Shows uploaded image at larger size with automated quality checks:
- File size (too small = low quality warning)
- File type validation (JPEG, PNG, PDF, HEIC)
- Resolution check (minimum 400x250 for readable text)
- Aspect ratio check (should look like an ID card)

Green checkmark for passing checks, red X for issues.
Yellow warning box for quality problems with specific guidance.
Accept & Continue button to confirm, Retake to re-upload.
After accept, collapses to small preview with "Change ID" option.

Front of ID only (sufficient for FMCSA MCS-150 filing).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 15:59:27 -05:00
justin
e8769e4d5d Photo ID upload: add QR code for phone + scanner device support
Three upload methods:
- Upload File: standard file picker
- Camera / Scanner: uses capture attribute for camera on mobile
  or TWAIN/WIA scanner devices on desktop
- QR Code: generates QR with current page URL so user can scan
  with phone and take a photo of their ID on mobile

QR generated via api.qrserver.com (no library dependency).
Remove button restores all upload options.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 15:56:00 -05:00
justin
b8a52303b3 DOT intake: use is:inline script to avoid hoisted bundle crash
FCC step scripts crash on DOT pages due to missing elements. By
using is:inline, DOT intake script runs independently, not in the
hoisted bundle. Stripped TypeScript annotations for plain JS compat.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 15:38:04 -05:00
justin
db96af53bf Guard DOT intake script — skip on non-DOT pages
Wraps entire script in element existence check to prevent running
on FCC pages where other step scripts crash from missing elements.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 15:35:52 -05:00
justin
989ccaec93 Fix MCS150Step null crash — was breaking ALL DOT intake pages
MCS150Step script compiled into hoisted JS for all order pages.
Non-null assertions on photo ID elements crashed on non-MCS150 pages,
preventing DOTIntakeStep's showRelevantSections from running.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 15:33:56 -05:00
justin
c98ac9ae54 Fix DOT intake crash: null-safe photo ID element refs
Script crashed on 'Cannot read properties of null' because photo ID
elements are inside a hidden section. All element refs now use
optional chaining instead of non-null assertions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 15:31:15 -05:00
justin
d55384975e Fix DOT intake: retry init until wizard found + null-safe PWIntake
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 15:29:42 -05:00
justin
7fe3311921 Fix DOT intake: wait for DOMContentLoaded before showing sections
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-30 15:27:39 -05:00