- send_test no longer overwrites {{ UnsubscribeURL }} with a dead static URL;
Listmonk renders it into a working per-subscriber unsubscribe link.
- dot-compliance hero grid: 4 columns (minmax 150px, max-width 920px) instead
of 3 to reduce vertical space.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- import_subscribers: was POSTing wrong bulk shape AND fallback used 'list_ids'
(ignored by Listmonk) instead of 'lists' -> subscribers never attached to the
list -> real sends would go to an empty list. Now single-adds with 'lists',
handles already-exists, returns a count, logs if 0 added.
- send_test: passed base['lists'] (objects) instead of IDs -> test send rejected.
Now extracts list IDs.
- create_and_schedule_campaign: add schedule= flag (preview makes drafts).
- --preview: 1 sample carrier/campaign, only owner email, drafts not scheduled,
test sends immediately, never marks real carriers sent.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Each of the 8 daily campaigns gets a test send immediately after creation
using the first row's real carrier data as the sample. TEST_EMAIL env var
overrides the default (carrierone@gmx.com).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
- 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>
- 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
- filing_attestation.py: generates cover page attesting PW submitted document
to recipient with date/time stamp, contact info, and digital signature
- fax_sender.py: sends PDFs via VitalPBX API, polls for delivery, generates
attested copy for customer records
- dot-lookup.ts: if DOT has pending MCS-150 order, show green 'UPDATE SUBMITTED'
instead of red 'OVERDUE' in compliance checker
- requirements.txt: add pyhanko + cryptography for PDF digital signatures
- id-upload.ts: replace broken direct minio import with workers presign/upload
- job_server.py: add minio-upload handler for API to store files via workers
- rewrite presigned URLs from internal minio:9000 to public minio.performancewest.net
- fixes: thumbnail not showing after phone upload, base64 fallback storage
Campaign emails send from .71 via Postfix (now explicitly bound).
Verification RCPT TO probes go from .72 to protect sending reputation.
Configurable via VERIFY_SOURCE_IP env var.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- 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>
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>
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>
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>
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>
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>
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>
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>
- 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>
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>
- For-hire carriers now flagged with issues (BOC-3/UCR/insurance needed)
- Zero trucks/drivers flagged as stale data
- For-hire + MCS-150 overdue = critical severity
- Actionable flags count excludes zero_fleet (informational only)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
MCS-150 Biennial Update ($79):
- Admin-assisted filing (FMCSA Portal requires Login.gov MFA)
- Creates admin todo with intake data and filing steps
- Checks current MCS-150 status via FMCSA API
- Sends status email to client
BOC-3 Process Agent Filing ($149):
- Partners with blanket process agent (NWRA or similar)
- Collects carrier info, submits designation to partner
- Partner files electronically with FMCSA
- Stub for future process agent API integration
- Sends status/confirmation emails
Both follow the same handler pattern as FCC services (admin todo
with structured data when full automation isn't possible).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Set Calibri as explicit font on all runs via _run() helper
- Added note that many large US carriers work with Canadian carriers
and to ask about specific regulatory requirements
- BCM One ownership for Flowroute
- Cleaned up leftover manual font assignments
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>