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>
This commit is contained in:
justin 2026-05-29 12:46:33 -05:00
parent c80f3a408a
commit 33da00fd89
21 changed files with 2078 additions and 14 deletions

View file

@ -2038,8 +2038,23 @@ async function sendComplianceIntakeEmail(
</p>
</div>` : "";
// Build intake form links for each service
const intakeLinks = orders.map(o => {
// DOT services are admin-assisted — no intake form needed
const DOT_SLUGS = new Set([
"mcs150-update", "boc3-filing", "ucr-registration", "dot-registration",
"mc-authority", "dot-drug-alcohol", "dot-audit-prep", "dot-full-compliance",
// State-level trucking
"irp-registration", "ifta-application", "ifta-quarterly",
"or-weight-mile-tax", "ny-hut-registration", "ky-kyu-registration",
"nm-weight-distance", "ct-highway-use-fee", "ca-mcp-carb",
"state-dot-registration", "intrastate-authority", "osow-permit",
"state-trucking-bundle",
]);
const dotOrders = orders.filter(o => DOT_SLUGS.has(o.service_slug as string));
const fccOrders = orders.filter(o => !DOT_SLUGS.has(o.service_slug as string));
const isDotOnly = fccOrders.length === 0;
// Build intake form links for FCC services only
const intakeLinks = fccOrders.map(o => {
const slug = o.service_slug as string;
const orderNum = o.order_number as string;
const name = o.service_name as string;
@ -2047,7 +2062,7 @@ async function sendComplianceIntakeEmail(
return `<li style="margin:6px 0;"><a href="${intakeUrl}" style="color:#1e40af;font-weight:600;font-size:14px;text-decoration:underline;">${name}</a></li>`;
}).join("\n");
const intakeSection = `
const intakeSection = fccOrders.length > 0 ? `
<div style="background:#eff6ff;border:2px solid #3b82f6;border-radius:8px;padding:20px;margin:20px 0;">
<p style="margin:0 0 8px;font-size:16px;font-weight:700;color:#1e3a5f;">Action Required: Complete Your Intake Form</p>
<p style="margin:0 0 12px;font-size:13px;color:#374151;line-height:1.5;">
@ -2055,12 +2070,26 @@ async function sendComplianceIntakeEmail(
</p>
<ul style="margin:0 0 12px;padding-left:18px;">${intakeLinks}</ul>
<p style="margin:0;font-size:12px;color:#6b7280;">This usually takes 2-5 minutes. We cannot begin your filing until the intake form is complete.</p>
</div>`;
</div>` : "";
const dotSection = dotOrders.length > 0 ? `
<div style="background:#fff7ed;border:2px solid #fdba74;border-radius:8px;padding:20px;margin:20px 0;">
<p style="margin:0 0 8px;font-size:16px;font-weight:700;color:#9a3412;">We're Working On It</p>
<p style="margin:0 0 12px;font-size:13px;color:#374151;line-height:1.5;">
The following services are being processed by our team. No further action is needed from you.
</p>
<ul style="margin:0 0 12px;padding-left:18px;">${dotOrders.map(o =>
`<li style="margin:4px 0;font-size:14px;color:#374151;">${o.service_name}</li>`
).join("\n")}</ul>
<p style="margin:0;font-size:12px;color:#6b7280;">You'll receive a confirmation email when your filing is complete, typically within 1 business day.</p>
</div>` : "";
const { sendEmail } = await import("../email.js");
await sendEmail({
to: customerEmail,
subject: `Action Required — ${entityName || "Your"} FCC Compliance Order`,
subject: isDotOnly
? `Order Confirmed — ${entityName || "Your"} DOT Compliance Order`
: `Action Required — ${entityName || "Your"} Compliance Order`,
html: `<!DOCTYPE html>
<html><head><meta charset="UTF-8"></head>
<body style="margin:0;padding:0;background:#eef0f3;font-family:Arial,sans-serif;">
@ -2093,14 +2122,22 @@ async function sendComplianceIntakeEmail(
${usacSection}
${dotSection}
${intakeSection}
<h2 style="margin:24px 0 8px;font-size:16px;font-weight:700;color:#111827;">What to Expect</h2>
${isDotOnly ? `
<p style="margin:0 0 4px;font-size:14px;color:#374151;"><span style="color:#1e3a5f;font-weight:600;">1.</span> Our team is already working on your filing.</p>
<p style="margin:0 0 4px;font-size:14px;color:#374151;"><span style="color:#1e3a5f;font-weight:600;">2.</span> Most DOT filings are completed within 1 business day.</p>
<p style="margin:0 0 4px;font-size:14px;color:#374151;"><span style="color:#1e3a5f;font-weight:600;">3.</span> You will receive a confirmation email when everything is filed.</p>
` : `
<p style="margin:0 0 4px;font-size:14px;color:#374151;"><span style="color:#1e3a5f;font-weight:600;">1.</span> Complete the intake form above so we have the details we need.</p>
<p style="margin:0 0 4px;font-size:14px;color:#374151;"><span style="color:#1e3a5f;font-weight:600;">2.</span> We will prepare your filing within 3-7 business days.</p>
<p style="margin:0 0 4px;font-size:14px;color:#374151;"><span style="color:#1e3a5f;font-weight:600;">3.</span> You will receive the document for review and electronic signature.</p>
<p style="margin:0 0 4px;font-size:14px;color:#374151;"><span style="color:#1e3a5f;font-weight:600;">4.</span> Once signed, we file it with the FCC and send you confirmation.</p>
${has499 ? `<p style="margin:0 0 4px;font-size:14px;color:#374151;"><span style="color:#1e3a5f;font-weight:600;">4.</span> For 499-A filings, complete the USAC delegation above and click the confirmation button.</p>` : ""}
<p style="margin:0 0 4px;font-size:14px;color:#374151;"><span style="color:#1e3a5f;font-weight:600;">4.</span> Once signed, we file it and send you confirmation.</p>
${has499 ? `<p style="margin:0 0 4px;font-size:14px;color:#374151;"><span style="color:#1e3a5f;font-weight:600;">5.</span> For 499-A filings, complete the USAC delegation above and click the confirmation button.</p>` : ""}
`}
<p style="margin:20px 0 0;font-size:13px;color:#9ca3af;">
Questions? Contact us at