Commit graph

20 commits

Author SHA1 Message Date
justin
4e7493b088 Mark MC Authority as non-discountable ($300 FMCSA gov fee)
Non-discountable services: BOC-3 ($25 vendor), D&A (~$100 provider),
MC Authority ($300 gov fee). All other DOT services are pure labor.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:02:31 -05:00
justin
79fb4722f1 Mark BOC-3 as non-discountable (passthrough cost to Process Agent LLC)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 15:00:46 -05:00
justin
78ed1db15a Recalculate bundle pricing + bundle auto-uncheck individual items
- DOT Full Compliance Bundle: $499 → $399 (saves $376 vs $775 individual)
- State Compliance Bundle: $599 → $499 (saves $297 vs $796 individual)
- D&A marked non-discountable (passthrough cost to testing provider)
- Order page: selecting a bundle auto-unchecks its individual components
  via data-bundle attribute listing component slugs

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-29 14:49:59 -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
dddfd53cd3 Update DOT service pricing per competitive research
MCS-150: $69, BOC-3: $89, UCR: $69 + gov fee ($46 min),
New USDOT: $89, MC Authority: $349 + $300 gov fee,
D&A Program: $149/yr, Audit Prep: $399, Full Bundle: $499.

Positioned below market on entry-level services (MCS-150 $69 vs
$99-200 competitors) to win first orders and upsell.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-28 22:57:43 -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
d4c4ae003e Fix 6 bugs from code review
Critical:
- Single-order discount used wrong column names (discount_pct/discount_flat_cents
  → discount_type/discount_value). Discounts were silently $0.
- Single-order discount skipped allowed_emails and expires_at checks
- Free orders now set paid_at = NOW()

High:
- Discount usage now tracked in discount_usage table + current_uses incremented
- Flat discount only replaces bundle when flat >= bundle (was always replacing)

Minor:
- Removed unused CDR profile fetch in EntityStep

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-22 02:16:38 -05:00
justin
6d441a5cc0 Add email-restricted discount codes and $0 order bypass
- discount_codes.allowed_emails: when set, code only valid for listed emails
- Flat discounts now replace bundle discount (don't stack)
- $0 orders skip all payment gateways, mark paid immediately, redirect to success
- FREEDOM249: $249 flat off restricted to 4+ deficiency carriers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-22 00:16:47 -05:00
justin
d39e10485f Add URL promo code pre-fill and fix discount stacking logic
- Checkout page reads ?code= or ?promo= from URL, pre-fills and locks the
  promo field, shows the promo discount in the summary instead of the 15%
  bundle discount
- API: when a promo code % >= bundle %, replace the bundle discount entirely
  instead of stacking (e.g. MEMORIAL25 at 25% replaces the 15% bundle)
- Also checks discount code expiration in the query

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-21 15:06:19 -05:00
justin
7d783bdb39 Reprice services: à la carte ~$2,000 vs FCC Carrier Reg bundle $1,299
Individual services repriced so buying separately costs ~$2K, making
the $1,299 FCC Carrier Registration a clear 35% savings:

- CORES/FRN: $99 → $149
- Form 499 Initial: $299 → $349
- D.C. Registered Agent: $99 → $149/yr
- RMD: $219 → $249 (+ $100 FCC fee)
- CPNI: $149 → $199
- CALEA SSI: $299 → $799 (includes consulting work)
- BDC Broadband: $199 → $249
- BDC Voice: $149 → $199
- BDC Both: $299 → $349

Retired New Carrier Bundle ($1,799) — redirected to FCC Carrier
Registration ($1,299) which includes more services and the wizard.

Updated prices in: API catalog, batch order page, compliance checker CTA.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-04 06:23:19 -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
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
d6c513bca5 Link telecom_entity_id by FRN on intake save, fix batch siblings
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 18:31:59 -05:00
justin
7b650179e4 Add Finish button handler + intake save API endpoint
- Wizard "Finish" button now submits intake data to the API
- New PUT /api/v1/compliance-orders/:id/intake endpoint saves intake data,
  updates entity, re-dispatches worker, and unpauses batch siblings
- Shows success screen with portal link after submission

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 18:26:20 -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
438d3a6e2e Add customer portal orders page + my-orders API
- GET /api/v1/compliance-orders/my-orders?email= returns all orders
  grouped by batch, with USAC delegation status
- /account/orders page shows order history with:
  - Entity name, FRN, batch ID, date, payment status
  - Itemized services with pricing
  - USAC delegation callout with confirmation button
  - Auth-gated (requires login)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 21:27:10 -05:00
justin
86205c309c Replace USAC email instructions with confirmation button + add API endpoint
- Intake email now has "I've completed the delegation →" button
  instead of "reply to this email"
- Button links to order success page with action=usac_delegation
- New API: POST /api/v1/compliance-orders/:id/usac-delegation
  Records confirmation timestamp in intake_data and logs it
- Removed "reply to this email" from intake email

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 21:20:22 -05:00
justin
a7d7fee154 Fix 6 bugs found in compliance and checkout flows
1. CRITICAL: Add compliance_batch to stripe session tableMap —
   session IDs weren't being stored for batch orders
2. CRITICAL: Fix batch orders using order_number instead of batch_id
   when storing stripe_session_id
3. MAJOR: Tax deductibility note only shows for compliance orders,
   not CRTC/formation/bundles
4. MAJOR: Identity verification fallback changed from localhost:4321
   to performancewest.net with warning log
5. MEDIUM: Fix discount rounding — last service absorbs remainder
   to prevent cent loss across batch orders
6. LOW: Validate at least one paid service in batch orders
7. Standardize support email to info@performancewest.net everywhere

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 09:56:12 -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