fix(trucking-email): route order CTAs to the correct service page (not $399 catch-all)

Two routing bugs that sent carriers to wrong/dead order pages:

1. MCS-150 + Inactive campaigns linked to /order/dot-full-compliance ($399)
   instead of their actual service: build_lp_link()/lp_slug_for() fell through
   to the dot-full-compliance catch-all for any campaign_type not in
   DEFICIENCY_SEGMENTS, ignoring the existing PRICE_SLUG_BY_CAMPAIGN map. So
   MCS-150 carriers (should be mcs150-update $79) and Inactive carriers (should
   be usdot-reactivation $149) were both quoted a 5x-priced bundle they never
   asked for — a severe conversion killer on the two highest-volume segments.
   Fix: lp_slug_for() now checks PRICE_SLUG_BY_CAMPAIGN first; build_lp_link()
   delegates to it (single source of truth).

2. IFTA-quarterly + UCR-annual builders set lp_link to a BARE path when no
   coupon was active (LP_LINK with no query). The body appends '&utm_source=...'
   so the CTA rendered as /order/ifta-quarterly&utm... (no '?') = 404. Fix:
   both now always emit a leading '?' query carrying ?dot= (and ?code= when a
   coupon is on), mirroring the main builder's lp_link_with_coupon().

Audited every campaign_type: all 14 order slugs now resolve 200 and match the
intended service/price. Compliance-check secondary links (/tools/dot-compliance-
check) verified correct and intentionally kept where a 'check status' CTA fits.
This commit is contained in:
justin 2026-06-23 15:19:23 -05:00
parent e3f439221a
commit a90cdc9066
3 changed files with 30 additions and 10 deletions

View file

@ -249,7 +249,16 @@ def main() -> int:
headline = headline_t.format(due=due_human)
def attribs(dot, company, state):
lp = f"{LP_LINK}?code={coupon}" if coupon else LP_LINK
# lp_link MUST start its query with `?` so the body's `&utm_source=...`
# appends cleanly. A bare path here yields `/order/ifta-quarterly&utm...`
# (no `?`) which 404s. Carry the carrier's `?dot=` (and `?code=` when a
# coupon is on) exactly like the main builder's lp_link_with_coupon().
params = []
if dot:
params.append(f"dot={dot}")
if coupon:
params.append(f"code={coupon}")
lp = f"{LP_LINK}?" + "&".join(params) if params else LP_LINK
a = {
"dot_number": dot or "", "company": company or "", "state": state or "",
"lp_link": lp,

View file

@ -232,17 +232,19 @@ def discounted_price_attribs(campaign_type: str, phy_state: str | None,
def build_lp_link(campaign_type: str, phy_state: str | None) -> str:
"""Return the order landing-page URL for a (segment, state)."""
seg = DEFICIENCY_SEGMENTS.get(campaign_type)
slug = seg["lp_slug"] if seg else "dot-full-compliance"
if campaign_type == "state_weight_tax" and phy_state in _WEIGHT_TAX_LP:
slug = _WEIGHT_TAX_LP[phy_state]
if campaign_type == "state_emissions" and phy_state == "CA":
slug = "ca-mcp-carb"
return f"{SITE_DOMAIN}/order/{slug}"
return f"{SITE_DOMAIN}/order/{lp_slug_for(campaign_type, phy_state)}"
def lp_slug_for(campaign_type: str, phy_state: str | None = None) -> str:
"""The order-page slug (== the discountable service slug) for a segment."""
"""The order-page slug (== the discountable service slug) for a segment.
Main (non-deficiency) campaigns route to their SPECIFIC service via
PRICE_SLUG_BY_CAMPAIGN (mcs150 -> mcs150-update $79, inactive ->
usdot-reactivation $149). Without this they fell through to the
`dot-full-compliance` ($399) catch-all sending MCS-150/Inactive carriers
to a 5x-priced page they never asked for (severe conversion killer)."""
if campaign_type in PRICE_SLUG_BY_CAMPAIGN:
return PRICE_SLUG_BY_CAMPAIGN[campaign_type]
seg = DEFICIENCY_SEGMENTS.get(campaign_type)
slug = seg["lp_slug"] if seg else "dot-full-compliance"
if campaign_type == "state_weight_tax" and phy_state in _WEIGHT_TAX_LP:

View file

@ -196,7 +196,16 @@ def main() -> int:
urgency = urgency_t.format(year=year, due=due_human)
def attribs(dot, company, state):
lp = f"{LP_LINK}?code={coupon}" if coupon else LP_LINK
# lp_link MUST start its query with `?` so the body's `&utm_source=...`
# appends cleanly. A bare path here yields `/order/ucr-registration&utm...`
# (no `?`) which 404s. Carry the carrier's `?dot=` (and `?code=` when a
# coupon is on) exactly like the main builder's lp_link_with_coupon().
params = []
if dot:
params.append(f"dot={dot}")
if coupon:
params.append(f"code={coupon}")
lp = f"{LP_LINK}?" + "&".join(params) if params else LP_LINK
a = {
"dot_number": dot or "", "company": company or "", "state": state or "",
"lp_link": lp,