#!/usr/bin/env python3 """ Phase-5 campaign segment validation (no production DB required). Builds a synthetic in-memory fmcsa_carriers table and asserts that every deficiency-flag segment in build_trucking_campaigns.DEFICIENCY_SEGMENTS: - selects exactly the carriers carrying its flag, - excludes blocked-domain + already-sent + unflagged carriers, - routes to a valid order landing page (incl. per-state overrides). Requires a reachable Postgres (DATABASE_URL) only to create a TEMP table; it never reads real data. Run: DATABASE_URL=postgresql://pw:pw_dev_2026@localhost:5434/performancewest \ python3 scripts/tests/check_campaign_segments.py """ from __future__ import annotations import importlib.util import os import sys ROOT = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) BTC = os.path.join(ROOT, "scripts/build_trucking_campaigns.py") if ROOT not in sys.path: sys.path.insert(0, ROOT) def main() -> int: if not os.environ.get("DATABASE_URL"): print("SKIP: DATABASE_URL not set (needs any reachable Postgres for TEMP table)") return 0 import psycopg2 spec = importlib.util.spec_from_file_location("btc", BTC) btc = importlib.util.module_from_spec(spec) spec.loader.exec_module(btc) conn = psycopg2.connect(os.environ["DATABASE_URL"]) cur = conn.cursor() cur.execute(""" CREATE TEMP TABLE fmcsa_carriers ( dot_number text, email_address text, legal_name text, phy_state text, mcs150_parsed timestamptz, oos_active boolean, email_verified boolean, email_verify_result text, listmonk_sent_at timestamptz, deficiency_flags text[]); """) rows = [ ("1", "a@good.com", "For Hire Co", "NY", None, False, True, None, None, ["for_hire_carrier"]), ("2", "b@good.com", "IRP Co", "TX", None, False, True, None, None, ["interstate_needs_irp_ifta"]), ("3", "c@good.com", "Intrastate Co", "CA", None, False, True, None, None, ["intrastate_authority_CA"]), ("4", "d@good.com", "Weight Tax Co", "OR", None, False, True, None, None, ["state_weight_tax_OR"]), ("5", "e@good.com", "Emissions Co", "CO", None, False, True, None, None, ["state_emissions_CO"]), ("6", "f@good.com", "Hazmat Co", "OH", None, False, True, None, None, ["hazmat_carrier"]), ("7", "g@good.com", "Clean Co", "NY", None, False, True, None, None, []), # no flags ("8", "h@aol.com", "Blocked Co", "NY", None, False, True, None, None, ["for_hire_carrier"]), # blocked domain ("9", "i@good.com", "Sent Co", "NY", None, False, True, None, "2026-01-01", ["for_hire_carrier"]), # already sent ] for r in rows: cur.execute("INSERT INTO fmcsa_carriers VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)", r) conn.commit() all_states = tuple(s for cfg in btc.TIMEZONE_CONFIG.values() for s in cfg["states"]) expected = { "for_hire_boc3": 1, "irp_ifta": 1, "intrastate_authority": 1, "state_weight_tax": 1, "state_emissions": 1, "hazmat": 1, } ok = True for ctype in btc.DEFICIENCY_SEGMENTS: got = len(btc.fetch_carriers(conn, all_states, ctype, 1000)) status = "OK" if got == expected[ctype] else "FAIL" if got != expected[ctype]: ok = False print(f" {status}: {ctype:<22} matched {got} (expected {expected[ctype]})") lp_ok = ( btc.build_lp_link("state_weight_tax", "OR").endswith("/order/or-weight-mile-tax") and btc.build_lp_link("state_emissions", "CA").endswith("/order/ca-mcp-carb") and btc.build_lp_link("hazmat", None).endswith("/order/hazmat-phmsa") and btc.build_lp_link("irp_ifta", None).endswith("/order/state-trucking-bundle") ) print(" LP routing:", "OK" if lp_ok else "FAIL") conn.close() passed = ok and lp_ok print("CAMPAIGN SEGMENTS:", "PASS" if passed else "FAIL") return 0 if passed else 1 if __name__ == "__main__": sys.exit(main())