Commit graph

303 commits

Author SHA1 Message Date
justin
ed0a44645e Email verifier: add catch-all domain detection via random probe
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>
2026-05-29 14:34:23 -05:00
justin
258e384f95 Fix state list import: use individual subscriber creates instead of bulk
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>
2026-05-29 14:26:44 -05:00
justin
4df73337b8 Add state-targeted campaign creator (CA, OR, NY)
Script creates Listmonk campaigns with state-specific content:
- California: MCP + CARB + CHP CA Number + insurance
- Oregon: Weight-Mile Tax + IRP + ODOT authority
- New York: HUT + insurance ($1.5M NYC) + intrastate authority

Usage: python3 scripts/create_state_campaigns.py california

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:25:12 -05:00
justin
4aff121c0b Fix interstate detection: use carrier_operation code A, not text match
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>
2026-05-29 14:01:18 -05:00
justin
46411c09c6 Add Playwright automation for BOC-3 filing on processagent.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>
2026-05-29 13:24:12 -05:00
justin
584f887f82 Extend FMCSA flagger with state-level deficiency flags
- Interstate carriers flagged for IRP/IFTA needs
- Weight-distance tax flags (OR/NY/KY/NM/CT)
- State carrier permit flags (CA MCP, etc.)
- Emissions flags (CA CARB, ACT states)
- Intrastate authority flags (29 states, for-hire only)
- New --state-lists flag creates state-targeted Listmonk lists
  (CA, OR, NY, KY, NM, CT, TX, FL)
- Stats now include state-level counts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 13:03:49 -05:00
justin
e473953fef Update BOC-3 handler: Process Agent LLC (Registered Agents Inc)
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>
2026-05-29 13:00:31 -05:00
justin
33da00fd89 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>
2026-05-29 12:46:33 -05:00
justin
e67df3c4c3 DOT intake: review-only (no telecom entity step), email verifier,
updated flagger excluding 4+ year stale carriers

- Intake manifest: DOT services use ["review"] only, skipping the
  telecom entity step with FRN/USAC fields
- Flagger: excludes 4+ year overdue carriers from campaign (spam
  trap risk). 18,277 safe targets from 100K records.
- Email verifier: self-hosted MX + SMTP verification tool

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 00:29:28 -05:00
justin
5bf364aced Enhance FMCSA flagger: for-hire as deficiency, zero fleet detection
- 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>
2026-05-29 00:19:00 -05:00
justin
e510cefb88 Fix: bool(email) instead of email for campaign_eligible flag
Python 'and' returns the string, not True. Changed to bool().

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 00:17:18 -05:00
justin
563df6c5d4 Add FMCSA carrier deficiency flagger for campaign targeting
Analyzes census data and flags carriers with:
- MCS-150 overdue (2+ years) / severely overdue (4+ years)
- For-hire status (needs BOC-3, UCR, insurance)
- Hazmat (needs PHMSA registration)

Adds columns to fmcsa_carriers: deficiency_flags, deficiency_count,
deficiency_severity, issues_summary, campaign_eligible.

Can populate Listmonk subscriber list with --listmonk flag.
From 100K test: 20,039 campaign-eligible carriers with email.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 00:15:52 -05:00
justin
8149996107 Add 8 DOT/FMCSA services to catalog and handler registry
Service catalog (compliance-orders.ts):
- mcs150-update: $79 (MCS-150 biennial update)
- boc3-filing: $149 (BOC-3 process agent)
- ucr-registration: $79 + $59 gov fee (UCR annual)
- dot-registration: $149 (new USDOT number)
- mc-authority: $499 + $300 gov fee (operating authority)
- dot-drug-alcohol: $199 (D&A compliance program)
- dot-audit-prep: $399 (new entrant safety audit prep)
- dot-full-compliance: $499 (bundle)

Handler registry (__init__.py):
- MCS150UpdateHandler for admin-assisted filings
- BOC3FilingHandler for process agent designations
- Other DOT services use MCS150 handler pattern (admin todo)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-28 22:43:57 -05:00
justin
8441c6f0c0 Add MCS-150 and BOC-3 service handlers for trucking compliance
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>
2026-05-28 22:37:47 -05:00
justin
dfee4fc6c0 Add FMCSA motor carrier census table and Socrata data downloader
New vertical: FMCSA/DOT motor carrier compliance services.
- Migration 078: fmcsa_carriers table with 31 fields (DOT#, name,
  email, phone, address, fleet size, MCS-150 date, carrier type)
- Downloader: Socrata API ingest for 2M+ carriers with upsert
- Data source: data.transportation.gov (free, public)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-28 21:05:46 -05:00
justin
27a1a1f7ed Add Frontier Networks + Twilio to vendor guide (12 vendors total)
Skipped Comwave (acquired). Full list: Fibernetics, Iristel,
Flowroute/BCM One, VoIP.ms, Telnyx, SkySwitch/Sangoma, Distributel,
Allstream/Zayo, Bandwidth, IXICA, Frontier Networks, Twilio.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-27 11:21:07 -05:00
justin
79375c11b3 Add Bandwidth and IXICA to vendor guide from CRTC registry data
Scraped CRTC registered providers list (4,669 records, 1,843 companies).
Added Bandwidth Inc. (CLEC, wholesale DID/voice API) and IXICA
Communications (Toronto CLEC, wholesale voice/data). Now 10 vendors.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-27 11:20:35 -05:00
justin
9919947440 Fix: Flowroute (Intrado) -> Flowroute (BCM One)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-27 11:17:13 -05:00
justin
15cd006260 Vendor guide: Calibri font, US carrier note, cleanup
- 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>
2026-05-27 11:16:02 -05:00
justin
3bac30510e Update Flowroute ownership: now BCM One (acquired from Intrado)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-27 11:14:12 -05:00
justin
32c1e57c5c Add Canadian Wholesale Vendor Reference Guide to CRTC binder
New DOCX generator with 8 recommended upstream providers:
Fibernetics, Iristel, Flowroute, VoIP.ms, Telnyx, SkySwitch,
Distributel, Allstream. Each with services, website, and notes.

Wired into CRTC handler Step 6a (generates before eSign pause)
and added to binder compiler default sections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-27 11:11:47 -05:00
justin
7139630fa8 Add Accessible Canada Act (ACA) compliance tracking for CRTC orders
- CRTC handler: new compliance calendar entry for ACA accessibility
  plan/progress report (June 1 annual deadline), with 2-month advance
  reminder. Covers new entrant feedback process and existing carrier
  plans/reports. Notes dual notification requirement (Commissioner + CRTC).
- Order page: amber advisory banner about June 1, 2026 ACA deadline
  with key obligations and penalty warning
- "What's included" list: added ACA accessibility compliance tracking

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-27 10:09:33 -05:00
justin
ba2f6eb667 UPL-proof document templates + reliable bounce sync
Templates (22 files):
- Replace "Reviewed By" with "Document prepared by" + consulting disclaimer
- Add "not a law firm / not legal advice" footer to all CPNI, CALEA, RMD docs
- Change "on behalf of" to "at the direction of" in discontinuance letter
- Reframe RMD penalty language as client acknowledgment

Bounce sync:
- New listmonk-bounce-sync.py replaces unreliable bash tail watcher
- Scans full mail.log, matches QIDs to campaign senders, inserts directly
  into Listmonk DB with proper subscriber_id foreign keys
- Idempotent, runs via cron every 5 minutes

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 15:06:29 -05:00
justin
71d466c922 Wire createCommission() into compliance batch checkout
Compliance batch orders now create commission ledger entries when
a discount code (agent referral) is used. Tracks total order amount,
discount applied, and links to the agent for payout processing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-11 11:00:38 -05:00
justin
97dd08c821 Fix flagged items: CRTC email submission, BITS todo, selector docs, stale plans
- CRTC letter now auto-emailed to secretary.general@crtc.gc.ca after eSign
- BITS admin todo updated to reference electronic + physical submission
- COLIN selectors.py: documented verification status per step
- BC config: added CRTC Secretary General email address
- plan.md: marked completed items (eSign, portal auth, CRTC email)
- go-live-todo.md: marked Compliance Calendar DocType as imported

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 11:33:45 -05:00
justin
d6da7f4d7b Use Word VM PDF converter instead of raw LibreOffice in base handler
_convert_to_pdf() now calls pdf_converter.convert_to_pdf() which tries
the Windows Word VM via MinIO first (pixel-perfect), falling back to
LibreOffice headless automatically when the VM is unavailable.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 11:02:49 -05:00
justin
9ca6094984 Fix MinioStorage.upload_file → .upload + suppress instant delivery during eSign pause
- upload_file doesn't exist on MinioStorage — the method is upload()
- Return [] when pausing for eSign so job_server doesn't trigger instant delivery

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 10:59:45 -05:00
justin
ff47f47a37 Wire CPNI, CALEA, 499-A engagement, and discontinuance to generic eSign
Each handler now pauses for officer signature via the eSign portal
before filing/submitting. esign_completed callback re-dispatches
through standard pipeline with client_approved=true.

- CPNI: officer signs certification before ECFS submission (perjury)
- CALEA SSI: officer signs plan before delivery
- 499-A engagement: replaced custom JWT/email with request_esign()
- Discontinuance: officer signs deactivation letter before USAC email
- job_server: injects client_approved + order_number into order_data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 10:53:59 -05:00
justin
40844b2aff Add generic eSign portal for all compliance document types
Reusable signing flow: service handler generates document → inserts
esign_records row → emails JWT link → client reviews PDF + signs →
API stores signature + resumes pipeline. Works for RMD, CPNI, CALEA,
499-A engagement, discontinuance, CRTC, and any future doc types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 10:45:37 -05:00
justin
37a22cf474 Delete 499-A checklist generator — intake wizard handles data collection
The checklist was a manual-process artifact that listed what info the
client needed to gather. Since all data is now collected through the
intake wizard and CDR upload, the checklist is unnecessary. Removed
from the 499-A handler's prep packet and deleted the 1,326-line
generator file.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 09:10:50 -05:00
justin
463c180444 Add shared DOCX style module + campaign tools
_styles.py: Centralized typography, spacing, and formatting for all
26 DOCX generators. Calibri 9.5pt body, 1.15 line spacing, navy
headings, consistent signature blocks, page numbers, PW footer.
All generators will be migrated to use this instead of defining
their own styles.

Campaign tools:
- campaign_template.html: Styled email template for Listmonk campaigns
- populate_deficiency_list.py: Populates Listmonk with FCC deficiency data
- send_test_campaigns.py: Sends test emails with real carrier data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 08:52:07 -05:00
justin
47ca1bf10f Production readiness fixes: 3 critical + 2 high-priority
Critical #1 — CRTC: Fix undefined 'province' variable (canada_crtc.py:1322)
  Crashes every order at Step 6 document generation. Replaced with
  order_data.get("custom_incorporation_province", "BC").

Critical #2 — FCC Carrier Reg: Add State PUC state picker
  The order page collected "1/few/nationwide" but API expected an array
  of state codes. Added a multi-state checkbox grid that appears when
  State PUC add-on is checked. Sends puc_states: ["CA","NY",...] in
  service_wizard. Price updates per-state ($399 × count).

Critical #3 — Compliance: Add REQUIRED_FIELDS for fcc-499q and
  fcc-499a-discontinuance. Without these, intake validation was
  completely skipped — invalid data accepted silently.

High #4 — FCC Carrier Reg: Don't mark D.C. Agent complete
  prematurely. Was calling _update_step() right after creating the
  admin todo. Now waits for admin to confirm NW order is placed.

High #5 — Compliance: Add fcc-499q and fcc-499a-discontinuance to
  REQUIRES_ENTITY_FRN set. Both require FRN for USAC filing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 05:28:13 -05:00
justin
78c04b8bc3 Add Playwright failure monitoring: Telegram alerts + screenshots + health check
When any Playwright submission fails (selector not found, timeout, etc.):
1. Full-page screenshot captured and uploaded to MinIO
2. Telegram alert sent immediately with error details + screenshot link
3. Email alert to ops with same info
4. Admin todo includes screenshot MinIO path for debugging
5. Client order stays pending for manual completion

Proactive selector health check (daily 7am CT cron):
- Navigates to each portal (FCC RMD, USAC E-File, FCC CPNI/ECFS)
- Verifies all critical selectors are still present in the DOM
- If selectors are missing (UI changed): alerts via Telegram + email
  BEFORE any real client order fails
- Reports which service slugs are affected

Integrated into:
- RMD filing handler (fccprod.servicenowservices.com)
- Form 499-A handler (forms.universalservice.org)
- Form 499-Q handler (already had error handling)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 02:44:02 -05:00
justin
3e04edd384 Fix handler return types: return file path lists not dicts
job_server.py expects process() to return a list of file paths for
MinIO upload. The 499-Q and discontinuance handlers were returning
dicts like {'status':'admin_review'} which caused the job_server to
iterate dict keys as file paths -> 'File not found: status'.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 02:23:21 -05:00
justin
0bdaa4c373 Fix auto_filing: check env var before ERPNext to avoid hanging on dev
When AUTO_FILING_ENABLED is explicitly set as an env var, skip the
ERPNext API call entirely. The ERPNext client hangs indefinitely
when the host is unreachable (dev workers can't reach prod ERPNext),
blocking all compliance handlers.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 23:22:39 -05:00
justin
9be495dbb9 Fix import: BaseServiceHandler not BaseComplianceHandler, add _create_admin_todo
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 23:14:35 -05:00
justin
f30b0383a9 Automate 499-Q USAC filing + discontinuance letter auto-email
499-Q Handler:
- Auto-filing toggle integration (same as 499-A)
- Playwright USAC E-File submission for quarterly form
- Revenue field filling (4 categories)
- Confirmation number capture + PDF save
- Client receives "data received" email immediately, then
  "filed successfully" email with confirmation number after submission
- Falls back to admin todo if Playwright/session unavailable

Discontinuance Handler:
- Auto-emails deactivation letter to USAC (Form499@usac.org)
  with DOCX attachment + entity summary in body
- CC to admin email for records
- Dev mode: redirects USAC email to admin instead
- Client confirmation email with process timeline

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 23:04:15 -05:00
justin
a404cb1b57 Add USAC Filer ID Deactivation Letter template
Formal letter addressed to USAC Contributor Operations requesting
deactivation of a 499 Filer ID. Covers:
- Entity identification (name, Filer ID, FRN, EIN)
- Reason for deactivation + termination date
- Final 499-A status (zero-revenue included OR filed separately)
- Successor entity info (if applicable)
- Outstanding balance acknowledgment
- Related filings confirmation (RMD, CPNI, BDC)
- Officer signature block
- Entity summary box

Handler updated to:
- Generate the letter via document_gen template
- Upload DOCX to MinIO (compliance/{order_number}/)
- Reference the letter in admin todo

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 06:15:26 -05:00
justin
eee2aa497b Fix long-running PG transactions in RMD scrapers
Both scrapers held a cursor/transaction open while doing slow HTTP
requests to FCC ServiceNow and company websites, causing
"idle in transaction" for 10+ minutes and triggering the
PostgresSlowQueries alert.

Fix: fetch all row IDs upfront, commit the read transaction
immediately, then process each row with its own short
UPDATE+COMMIT cycle. No long-lived transactions.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 04:13:33 -05:00
justin
5e74c1dcb9 Split discontinuance CTA into two options based on revenue
When user selects "cancel registration" in the compliance checker:
- Option 1: "499-A Discontinuance (incl. zero-revenue filing)" $299
  For carriers with no revenue — includes final zero-revenue 499-A
  + deactivation letter + CORES update
- Option 2: "499-A Filing + Discontinuance" $798 ($499+$299)
  For carriers with actual revenue — full 499-A filed separately
  + deactivation process

Standalone discontinuance ($299) is for carriers already current
on filings who just want to close out.

Handler detects whether zero-revenue filing is included vs
handled by a separate full 499-A order.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 03:39:52 -05:00
justin
0c5f9d12c1 Update discontinuance handler with correct FCC process
Per 2026 FCC Form 499-A Instructions:
- Final 499-A CAN have actual revenue (not required to be zero)
  — reports revenue for the period the company was in service
- Deactivation is a SEPARATE step: submit letter to USAC with
  termination date and successor entity info, within 30 days
- Line 603: check TRS/LNP/NANPA exemption boxes, write
  "Not in business as of [date]"
- USAC processing takes 60-90 days
- CORES must be updated to reflect inactive status

Handler now creates admin todo with 4-step process:
1. File final 499-A with actual/zero revenue
2. Submit USAC deactivation letter (Form499@usac.org)
3. Update CORES registration
4. Confirm CPNI/RMD/BDC discontinued

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 03:02:23 -05:00
justin
0fc318cb38 Add 499-Q intake page, 499-Q handler, and 499-A discontinuance handler
499-Q Quarterly Filing:
- Intake page at /order/fcc-499q with simplified revenue form
  (4 fields: carrier's carrier inter/intra, end-user inter/intra)
- Zero-revenue confirmation checkbox
- Handler creates admin todo with filing details + sends client email
- Registers as fcc-499q in SERVICE_HANDLERS

499-A Discontinuance:
- Handler creates admin todo with step-by-step USAC instructions
  (file zero-revenue 499-A, request account closure, confirm CPNI/RMD)
- Sends client confirmation email explaining the process
- Compliance checker CTA: when user selects "No — cancel registration"
  in the 499-A toggle, shows discontinuance option ($299) instead of
  standard filing
- Order page maps form_499a_disc to fcc-499a-discontinuance slug

Compliance checker intelligence:
- 499-A toggle tracks _499aVariant (null/zero/discontinuance)
- CTA adapts: revenue=standard 499-A, zero=zero-revenue, cancel=discontinuance
- Reset clears variant flag

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 02:34:18 -05:00
justin
572f0cbf93 Implement 499-Q quarterly filing lifecycle
After 499-A+Q bundle is filed, the handler now creates actual
compliance_orders for each remaining quarterly 499-Q filing:

Schedule: Q1 due Feb 1, Q2 due May 1, Q3 due Aug 1, Q4 due Nov 1

Each quarterly order:
- Created as paid (covered by bundle price)
- Has due_date, quarter, period_end_date in intake_data
- Links to parent 499-A order
- Tracks reminder status (30d/14d/7d sent flags)

Notification worker (quarterly_499q_notify.py):
- Runs daily at 8am CT via systemd timer
- Sends HTML reminder emails at 30, 14, 7 days before due
- Email includes intake link for client to submit quarterly data
- Late warning at 7 days: "USAC may estimate higher contributions"
- Idempotent: won't re-send same reminder level

Added fcc-499q service slug ($0, not sold standalone).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 02:28:04 -05:00
justin
3e04a8fc16 Add zero-revenue 499-A filing at $179
New service slug fcc-499a-zero for carriers with no telecom revenue:
- $179 instead of $499 (no revenue analysis needed)
- Minimal intake: entity, officer, filer ID, filing type only
- Skips revenue schedules (blocks 3-4), USF calculations (block 5),
  traffic study upload, and revenue workbook generation
- Fills blocks 1-2 and 6 only, all revenue lines left as zero

Compliance checker: shows both options (mutually exclusive checkboxes)
Order page: maps form_499a_zero to fcc-499a-zero slug
Handler: detects slug and skips revenue pipeline
DC Agent shown when either 499-A variant is checked

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-03 02:04:18 -05:00
justin
fbf3b8a1ea Add terminate-only STIR/SHAKEN option across RMD pipeline
STIRShakenStep intake:
- New "Terminate only" option for carriers that only receive pre-signed
  calls and don't originate
- Contextual hints for each option explaining requirements
- Show/hide vendor and upstream fields based on selection

RMD letter generator:
- New terminate_only section explaining verification-only posture,
  citing 47 CFR § 64.6301 (signing obligation on originating provider)
- Added to needs_exhibit_a list

RMD Exhibit A generator:
- New terminate_only STIR/SHAKEN paragraph with SBC verification language
- Fixed scope paragraph: wholesale/facilities carriers no longer get
  "small provider without Class 4 switch" boilerplate
- Fixed OCN paragraph: wholesale carriers get neutral wording instead
  of "no OCN required for small retail provider"

RMD filing handler:
- Maps stir_shaken_status to rmd_option for Exhibit A generation
- Passes entity metadata (ocn, wholesale, gateway, contact) to generator
- Maps terminate_only → partial_implementation for FCC RMD form radio

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 10:59:28 -05:00
justin
2927b5cebb Add FCC Carrier/ISP Registration: API, checkout, handler, dispatch
Phase 3-5:
- API: POST /api/v1/fcc-carrier-registration (order creation with pricing)
- API: GET /api/v1/fcc-carrier-registration/:id (status)
- API: GET /api/v1/fcc-carrier-registration/state-fees (formation fees)
- Checkout: fcc_carrier_registration order type with Stripe line items
- Payment handler: dispatch worker + send confirmation email
- Pipeline handler: 8-step CRTC-style pipeline (formation → CORES → 499 →
  DC Agent → State PUC → RMD/CPNI/CALEA/BDC → add-ons → final review)
- Job server dispatch map entry
- Service page CTA updated to link to order page

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 08:48:36 -05:00
justin
314a711e95 Fix: add batch_id + engagement columns to job_server PG query
batch_id was missing from the SELECT, so order_data.batch_id was always
None. This meant the batch email skip in _request_entity_intake never
triggered, causing duplicate intake emails for every batch order.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:35:56 -05:00
justin
0d07b6a2d9 Skip worker intake emails for batch orders, remove payment step for paid orders
- Batch orders: checkout API already sends combined intake email, so worker
  handlers no longer send their own (was causing 2-3 duplicate emails)
- When accessed via ?token= or ?order= (post-payment), the "payment" step
  is removed from the intake wizard since payment is already complete

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 04:52:49 -05:00
justin
99bdfdfd91 DC Agent: don't send acceptance letter until NW order is placed
The handler was returning the acceptance letter as an artifact, which
triggered the instant-delivery email to the client before the admin
placed the wholesale order with Northwest. Now uploads to MinIO but
returns empty artifacts. Admin todo includes the MinIO path to send
the letter after confirming the NW order.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 04:50:15 -05:00
justin
cbfb8d6091 Add engagement authorization, remove price headers from intake pages, fix duplicate emails
- Add clickwrap authorization checkbox to fcc-compliance, state-puc, neca-ocn order pages
- Store engagement_accepted_at/ip/version in compliance_orders (migration 074)
- Add 499-A past-due/multi-year eSign engagement letter generator
- Gate 499-A handler on engagement signature for past-due/multi-year orders
- Remove price/tax/fee headers from all 19 intake pages (post-payment only)
- Fix duplicate confirmation email for compliance_batch orders
- Add USAC past-due fee negotiation research doc

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 02:50:02 -05:00