Commit graph

35 commits

Author SHA1 Message Date
justin
38739e023c mcs150: complete all-variant field mapping (150/150B/150C)
Adds the previously-unmapped fields so every variant fills fully:
- Q25 hazmat C/S/B/NB matrix (HAZMAT_ROW_MAP x HAZMAT_COL_MAP, 156 boxes)
- MCS-150B states-of-operation checkboxes (full name or 2-letter code), HMSP
  Hazard/Permit/Security radios, and accident count (32accidentNumber)
- MCS-150C intermodal equipment counts (20owned/leased/serviced) + correct
  field renumbering (17dunbrad/18irs/19eMail) + USDOT Button + named-export
  Reason/Mailing radios
- Structured fleet via intake['vehicles'] = {vehicle_type: {owned, term_leased,
  trip_leased}} across all Q26 vehicle rows; non-CMV count; cell/fax; second
  officer
- _set_button now resolves a candidate tuple against each field's actual export
  states, so numeric (/0../4) and named (/Yes,/Biennial...) radios both work

verify_mcs150_variants.py exercises all three variants end-to-end: ALL PASS.
2026-06-10 13:55:55 -05:00
justin
96f31e7c31 mcs150: only check Q29 passenger-cert box for passenger carriers
certifyBox is the Q29 Passenger Carrier Compliance Certification YES box
(page 3, y=530), not a general perjury checkbox. It was being checked
unconditionally, which wrongly marked freight/property carriers as passenger
carriers. Now only check it when the carrier is a passenger carrier; the
Q31 perjury declaration is made via the signature.
2026-06-10 13:44:34 -05:00
justin
b95ee04752 mcs150: fill all checkboxes/radios correctly + stamp explicit checkmarks
Fixes a batch of missing fields the FMCSA census does not provide and the
filler was mis-mapping:

- Corrected the question->field mapping to match the actual form: Q22 =
  COMPANY OPERATIONS (interstate/intrastate, 22xBox), Q23 = OPERATION
  CLASSIFICATIONS (for-hire/private/govt, 23xBox). These were swapped, and
  the bogus entity-type->23xBox map (no entity-type question exists on this
  form revision) was removed.
- Added proper radio-group handling for Reason for Filing (Biennial Update),
  Mailing-address (Same as principal vs below), and Q28 USDOT-revoked, with
  correct option indices (these are /0../n radios, not /Yes checkboxes; the
  old code set them to /Yes and never selected the right option).
- Map interstate/intrastate from the FMCSA census carrierOperationCode, and
  populate email/phone/mileage/cargo from intake.
- AcroForm checkbox/radio appearances use a ZapfDingbats glyph that
  poppler/Preview fail to render (value set but box looks empty). Now stamp
  an explicit X overlay into the page content for every 'on' box so it shows
  in every viewer and in the faxed output.
2026-06-10 13:41:48 -05:00
justin
386467bedf mcs150: trim FMCSA instruction pages from form templates
The official MCS-150/150B/150C PDFs ship with 8 (150/150B) or 4 (150C)
FMCSA instruction/example pages before the actual fillable form. We were
generating + faxing/submitting all of them. Trimmed the source templates
down to the FORM pages only:
  MCS-150  11 -> 3 pages (289 fields preserved)
  MCS-150B 12 -> 4 pages (349 fields preserved)
  MCS-150C  6 -> 2 pages (33 fields preserved)

The filler iterates writer.pages (no absolute index) and signature
anchors are derived dynamically via enumerate(reader.pages), so no
page-specific markup needed fixing. Removed one-off diag script.
2026-06-10 13:25:07 -05:00
justin
bd0d8c0e2c verify_mcs150: correct handler class name 2026-06-10 12:39:41 -05:00
justin
79c460ef25 mcs150: render verification harness + auto-generate appearance streams
- fill_mcs150 now uses auto_regenerate=True so pypdf writes appearance
  streams for every text field. Preview/Chrome ignore /NeedAppearances and
  were showing blank widgets over the values; generated /AP streams make
  the text render in all viewers.
- New verify_mcs150.py reads each widget's /AP /N appearance stream (the
  literal drawn glyphs) to confirm expected values actually render, since
  the container has no OCR/raster tooling. Exits non-zero on any miss.
2026-06-10 12:37:25 -05:00
justin
d5e66786a2 mcs150: enrich intake from FMCSA carrier census before PDF fill
The MCS-150 biennial update re-confirms the carrier's existing FMCSA
record. Previously the PDF filler only had whatever the intake form
collected; rescued/sparse orders (or orders where the carrier's data
lives in FMCSA, not the intake) produced near-empty forms. Now we pull
the carrier census (legal name, address, EIN, fleet counts) from the
FMCSA carrier API and merge it under any customer-provided intake values
(customer edits win), so the form is pre-filled with the carrier's
current registered data. Refactored the FMCSA fetch into a shared
_fetch_fmcsa_carrier helper used by both enrichment and status check.
2026-06-10 12:35:52 -05:00
justin
7e5946d65a fix(mcs150 pdf): set /NeedAppearances so filled field values actually render
Customer saw the MCS-150 looking blank / 'data covered by the form fields': the
values were correctly written to the AcroForm /V, but pypdf left the template's
empty /AP appearance streams in place and NeedAppearances was false, so viewers
rendered the blank widget over the value. Setting AcroForm /NeedAppearances=true
makes viewers regenerate appearances from the values. (The missing signature was
a downstream effect of the separate fobj_put MinIO-upload bug, now fixed -- with
no PDF in MinIO the anchor extraction + signature stamping both failed.)
2026-06-10 12:20:45 -05:00
justin
b0a8563a93 ink-signature: pen-plotter pipeline for original wet-ink CMS signatures
The Standard no-login CMS path needs an ORIGINAL ink signature on paper
(CMS-10114: 'Stamped, faxed or copied signatures will not be accepted'). This
adds a pipeline to redraw the provider's own captured strokes in real ink with a
pen on a CR-10 V2 (or any Marlin/GRBL machine) — original, in ink, never copied.

- migration 090: esign_records.signature_vector (JSONB stroke paths, 0..1).
- signing page now captures normalized stroke paths alongside the PNG; API
  stores a size-bounded vector for drawn signatures.
- ink_signature_plotter.py (hardware-independent): fit strokes to the signature
  anchor box, PDF-pt -> bed-mm via jig offset, emit Marlin/GRBL G-code (Z pen or
  M280 servo/BLTouch), SVG toolpath preview, and render_signature_on_pdf (a
  digital twin that proves the toolpath lands on the cert line). Gated serial
  sender (dry_run default).
- ink_signature_cli.py: end-to-end load-record -> gcode+preview, --test-box jig
  calibration, --plot to stream over USB.
- Corrected CMS-10114 signature anchor to sit inside the Section 4A signing cell
  (above the bottom rule, below the label).
- docs/ink-signature-plotter.md documents the CR-10 retrofit + interpretive risk.

Tests: test_ink_signature.py 30/30, test_cms10114.py 27/27, test_paper_batch.py
15/15, API tsc clean, Astro build 58 pages.
2026-06-07 02:34:17 -05:00
justin
e6a630ada1 healthcare: verify CMS-10114 update path, correct NPI Enumerator address, build CMS-10114 filler
Verified firsthand against the live CMS-10114 (Rev. 02/25, OMB 0938-0931):
- Section 1A confirms paper is valid for Change of Information (#2) AND
  Reactivation (#4), not just initial enumeration. Resolves the UNCERTAIN flag.
- Current mailing address is CMS NPI Enumerator Services, Mail Stop DO-01-51,
  7500 Security Blvd, Baltimore MD 21244. The old Fargo PO Box 6059 is retired;
  corrected in mac_routing.NPI_ENUMERATOR + all docs.
- No electronic no-login equivalent exists for CMS (NPI Registry API is
  read-only; PECOS/NPPES-IA require login), unlike FMCSA's ask.fmcsa ticket form.
  So tiers stay: Standard=paper CMS-10114 (no login), Expedited=NPPES surrogate.

New: cms10114_pdf_filler.py fills the flat official form via text overlay
(reason checkbox + NPI + Section 2A identity + Section 4A cert name + signature
anchor); wired into npi_provider._generate_10114_for_signing for nppes-update.
Signed forms route to the NPI Enumerator via the existing daily batch.

Tests: test_cms10114.py 27/27, test_paper_batch.py 15/15, Astro build 58 pages.
2026-06-07 02:04:41 -05:00
justin
138fec17e9 healthcare: daily batched paper-filing fulfillment
Standard (no-login) CMS filings are mailed in one Priority Mail envelope per
destination agency, batched each postal working-day morning to save postage.

- migration 089: paper_filing_batches table + esign_records.paper_batch_id /
  filing_destination_key (idempotent: a filing is batched at most once).
- batch_cover_sheet.py: per-agency cover sheet (sender/dest/date/manifest) +
  merged print-job PDF (cover + all enclosed signed filings).
- daily_paper_batch.py worker: gather signed+unbatched cms855/cms10114 filings,
  group by destination (MAC by state via mac_routing; Fargo for CMS-10114),
  build cover+merged PDF per agency, persist batch, mark filings batched.
  Self-gates on postal working days (skips weekends + federal/USPS holidays).
  Phase 1 = human prints+mails; phase 2 = wire print-mail API.
- worker-crons: pw-paper-batch systemd timer (Mon-Fri 13:30 UTC, self-gated).
- test_paper_batch.py: 15/15 pass (working-day gating, routing, cover+merge).
2026-06-07 00:30:01 -05:00
justin
695ace207c Reframe healthcare filing as standard vs expedited; e2e test + bug fixes
Copy: drop paper/electronic/fax framing across the revalidation + enrollment
marketing pages and the order-confirmation email; present two service tiers:
- Standard filing  (no CMS account; we prepare CMS-855, you sign, we submit to MAC)
- Expedited filing (CMS I&A surrogate access; same-day PECOS filing + tracking)
Internal worker todos + the _STANDARD_FILING_SLUGS identifier updated to match.

New scripts/test_healthcare_e2e.py validates the whole order line (slug
consistency x6 places, price agreement, intake field collection+enforcement,
worker dispatch, handler execution producing CMS-855 PDF+anchor, free-tool
action_urls). 45 checks.

Bugs found + fixed by the test:
- medicare-enrollment requires practice_state server-side but the wizard never
  enforced it -> orders could be paid then stall. Wizard now requires it.
- determine_form_type defaulted org NPIs to the individual 855I because
  enumeration_type is never collected -> wrong form, CMS rejection. Now does a
  live NPPES lookup (safe 855I fallback).
2026-06-05 03:58:46 -05:00
justin
e212f20a34 Add CMS-855 PDF filler + e-sign fulfillment for Medicare revalidation/enrollment
- cms855_pdf_filler.py: fills official CMS-855I/B/O/A AcroForms from intake
  (name, NPI, DOB, cert-page printed name) and records the signature anchor at
  the form's official /Sig box so the e-sign stamper lands on the cert line.
- npi_provider handlers (revalidation/reactivation/enrollment) now generate the
  paper CMS-855, upload it to MinIO, request_esign with anchors, and email the
  signing link. Human completes/verifies + USPS Priority Mails to the MAC.
- scripts/Dockerfile: copy the official CMS-855I/B/O/A forms into the image.
2026-06-05 02:27:11 -05:00
justin
f21f3d41d9 DOT D&A binder: remove Performance West and National Drug Screening from vendor directory
Drop the two self-listings (Performance West C-TPA and supervisor training) and
the National Drug Screening / NDS entries from the Suggested Vendors panels.
The non-endorsement disclaimer (which still names Performance West) is unchanged.
2026-06-02 22:02:07 -05:00
justin
843a5bfacb DOT D&A binder: add DER Quick-Start checklist, two-column vendor directory, flow sections
- Add a one-page 'DER Quick-Start Checklist' tear-off as the first content page
  (set-up-once / every-hire / ongoing checkboxes, each pointing to the relevant
  section or form).
- Add a two-column 'Suggested Vendors & Resources' directory page: C-TPA/
  consortium, collection sites & labs, MRO, SAP, supervisor training, and (mode-
  aware) FMCSA Clearinghouse or DOT resources, plus employee help lines. Marked
  as examples not endorsements; mode-aware.
- Remove forced page breaks between consecutive content sections (now a light
  section rule) so they flow continuously; page breaks kept only for the cover,
  quick-start, TOC, each form, the vendor page, regulations, and the addendum.
- New builder helpers: section_rule(), checkbox(), two_col_panels().
2026-06-02 21:54:06 -05:00
justin
501e417584 DOT D&A binder: add Section 11 — Practical Guidance for the Administrator
Adds the real-world know-how a first-time DER needs beyond the bare regs:
- Owner-operators / one-driver companies (must use a consortium; cannot self-test
  or self-select) — the most misunderstood case.
- Audits & penalties: what the new-entrant safety audit asks for and the
  consequences of no program (civil penalties, failed audit, out-of-service).
- Problem test results: dilute, shy bladder, cancelled test, split-specimen.
- Prescriptions / marijuana / CBD (marijuana prohibited regardless of state law;
  CBD trap; route medical questions to the MRO).
- What counts as a refusal (treated as a positive).
- Costs & timeline expectations.
- DER do's and don'ts (act same-day, keep records separate/confidential, never
  tip off a random selection, don't interpret results yourself).
2026-06-02 21:42:55 -05:00
justin
b569a32f3a DOT D&A binder: add driver enrollment guidance + Form G roster
Customers (the DER) had no concrete how-to for onboarding/enrolling drivers or
what information to collect. Add:
- Section 1 'Enrolling a driver (new-hire onboarding)' subsection: exact info to
  collect, the onboarding sequence (collect info, sign Forms A/B, Clearinghouse
  query, prior-employer inquiry, add to C-TPA pool, pre-employment test, wait for
  MRO negative), and a driver-removal note.
- Form G — Driver Enrollment & Covered-Employee Roster: per-driver enrollment
  block (name, DOB, SSN last4, CDL #/state, contact, hire date, test result,
  Clearinghouse/prior-employer status) plus a roster table for the covered pool.
- TOC, email, and handler text updated A-F -> A-G.
2026-06-02 21:39:50 -05:00
justin
9718ab9ffa DOT D&A binder: editable DOCX output, all 6 forms each full-page, service-aware delivery email
- Rewrite dot_da_binder_generator.py to emit an editable .docx (was reportlab PDF)
  so carriers/counsel can review and adapt the program. ~4000 words, 10 sections.
- Render all six required forms (A-F); previously only A, D, E existed. Each form
  starts on its own page (page break) and fills a page.
- Mode-aware policy text for FMCSA/FRA/PHMSA/FTA/FAA/USCG with correct CFR parts
  and random-testing rates; optional single-state Drug-Free Workplace addendum
  (federal DOT program is nationwide; only the optional DFWP addendum is state-keyed).
- Handler now outputs .docx instead of .pdf.
- job_server instant-delivery: attach DOCX (correct MIME) as well as PDF, and use
  DOT-specific email copy + CTA instead of the FCC/telecom boilerplate.
2026-06-02 21:27:44 -05:00
justin
06e59965cc DOT D&A: instant PDF compliance-program binder (49)
Turn the DOT Drug & Alcohol Compliance Program into an automated
instant-delivery deliverable: when a carrier orders, we generate a
complete, print-ready PDF binder and email it (no admin step).

The binder (dot_da_binder_generator.py) bundles everything a small
carrier needs under 49 CFR Part 382 + Part 40:
  - How to manage the program (DER setup + annual operations)
  - Written drug & alcohol testing policy for employees
  - The six DOT test scenarios + triggers
  - Random testing / consortium (C-TPA) instructions
  - Supervisor reasonable-suspicion training + live/online access
  - Violations, SAP access, return-to-duty / follow-up
  - EAP / rehab / treatment resources (SAMHSA, 988, locator, ODAPC)
  - Recordkeeping retention schedule
  - Ready-to-use forms (acknowledgment, reasonable-suspicion,
    post-accident decision worksheet)
  - Regulation citations
  - Optional state Drug-Free Workplace addendum

Policy-variant selection: FMCSA (Part 382) is the trucking default;
honors an explicit dot_da_mode override for FRA/PHMSA/FTA/FAA/USCG.

New DrugAlcoholProgramHandler returns the binder PDF; slug added to
INSTANT_DELIVERY_SLUGS so job_server emails it automatically. Slug
rerouted from MCS150UpdateHandler (was admin-assisted enrollment) and
re-priced as a discountable own-deliverable (no passthrough cost).

Tests: scripts/tests/test_dot_da_binder.py (FMCSA sections, PHMSA+state
addendum, all-modes render) — passing.
2026-06-02 19:28:58 -05:00
justin
1f1113d63c add fax filing pipeline: VitalPBX sender, attestation cover page with digital signature, compliance checker pending filing override
- 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
2026-05-30 18:32:01 -05:00
justin
1f24255358 MCS-150 official PDF filler — fills actual FMCSA fillable form
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>
2026-05-30 12:59:15 -05:00
justin
e82aa0b8c2 Fix PayPal capture for compliance orders + MCS-150 form generator
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>
2026-05-30 11:34:16 -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
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
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
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
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
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
justin
f8cd37ac8c Initial commit — Performance West telecom compliance platform
Includes: API (Express/TypeScript), Astro site, Python workers,
document generators, FCC compliance tools, Canada CRTC formation,
Ansible infrastructure, and deployment scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 06:54:22 -05:00