new-site/docs/plan.md
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

16 KiB

Performance West — Build Plan

Last updated: 2026-04-05
Status: Pre-launch. CRTC pipeline ~95% built (14 steps, BITS/CCTS/compliance calendar implemented). DocServer provisioned. US formation plumbing exists but no state has been filed end-to-end. Payment flow is wired but gateways not yet configured in ERPNext UI.

See also: docs/multi-province-plan.md — Plan to extend CRTC to multi-province + standalone Canadian formation + universal compliance calendar. 28-36 hours, 16 sub-phases. See also: docs/competitive-pricing.md — Competitor pricing analysis: US formation, Canadian formation, registered agents. Updated 2026-04-05.


How to Read This Plan

Tracks are independent workstreams. Within each track, items are ordered by dependency — complete them top-to-bottom. Across tracks, work in parallel where possible.

Labels:

  • [BLOCKER] — nothing ships until this is done
  • [CRTC] — affects the $3,899 flagship product
  • [FORMATION] — affects US LLC/Corp product
  • [INFRA] — server/ops
  • [PLUMBING] — backend wiring, no user-facing change

Track 1 — CRTC Pipeline (Flagship Revenue)

The Canada CRTC Carrier Package is the highest-value product. Get one real order through end-to-end before doing anything else.

1.1 ERPNext Payment Config [BLOCKER][CRTC]

ERPNext gateways exist as code but are not configured in the UI — no payment can complete.

  • Configure Crypto Payment Settings: URL = https://pay.performancewest.net, SHKeeper API key
  • Create Payment Gateway Account Crypto-Crypto in ERPNext
  • Configure Adyen Settings (5 instances: Card, ACH, Klarna, CashApp, AmazonPay) — pending Adyen account approval
  • Create 5 Adyen Payment Gateway Accounts
  • Configure ERPNext SMTP for outbound email (invoices, notifications)
  • Test: place a $1 test order, confirm Payment Request is created, confirm redirect to checkout, confirm webhook fires back to Express API

1.2 COLIN Selector Verification [BLOCKER][CRTC]

The BC incorporation adapter (frappe_ca_registry/provinces/bc/adapter.py) has 13 steps mapped but selectors are unverified against the live portal. No real BC incorporation can complete until this is tested.

  • Place a real test incorporation order against COLIN (corporateonline.gov.bc.ca)
  • Verify/fix selectors for: Step 6 Director, Step 7 Office Addresses, Step 8 Share Structure, Step 9 Notification, Step 12 Payment
  • Verify payment step: COLIN accepts Visa/MC — use relay-filing-card via get_filing_card API
  • Implement multiple-directors loop (currently only first director is inserted)
  • Confirm that BC sends certificate email to filings@performancewest.net
  • End-to-end smoke test: frappe_ca_registry creates Filing Request → COLIN automation completes → certificate arrives

1.3 CRTC Pipeline Remaining Stubs [CRTC]

  • Anytime Mailbox automation hardening — provider has no API, but Playwright flow now exists. Validate selectors against live UI and stabilize OTP retrieval via Carbonio IMAP, then keep admin handoff as fallback.
  • CCTS registration — Step 11 is a stub. Research CCTS online registration form, implement Playwright or keep as admin ToDo with instructions.
  • eSign workflow for CRTC letter — Step 6 generates the DOCX letter but customer signature is not collected. Use ERPNext built-in eSign (drawing pad). Wire: generate letter → send for eSign → on signed → continue pipeline.
  • CRTC letter email submission — After eSign, email the signed letter to CRTC from the customer's provisioned .ca address (regulatory@{domain}.ca). Requires IMAP send via HestiaCP provisioned mailbox.
  • BITS affidavit — BITS requires a notarized affidavit confirming the company is a US carrier (or Canadian equivalent). Provider: NotaryLive ($59/mo platform + $23/session). Implement: generate affidavit DOCX → send NotaryLive session invite → on completion → attach to binder.
  • Order confirmation email — After payment, send customer a confirmation email with order summary, expected timeline, and next steps checklist. Currently nothing is sent at payment time.
  • Branded HTML email templates — 15 ERPNext Email Notifications are plain text. Design and import HTML templates (header logo, PW brand colors, footer with unsubscribe).

1.4 Customer Portal Auth [CRTC]

Portal pages (/portal/domain-search, /portal/manage-services) exist but have no authentication. Any URL visitor can access any order.

  • Implement portal authentication via ERPNext portal login (ERPNext has a built-in portal user system)
  • Generate a signed JWT or ERPNext portal token and embed in the email links sent to customers
  • Add auth middleware to all /portal/* API routes — validate token, scope to customer's own orders only
  • Add session expiry (24h) and re-send link flow

1.5 End-to-End CRTC Test [CRTC]

  • Place a real CRTC order (numbered company, test customer)
  • Walk through all 12 pipeline steps
  • Confirm: DID provisioned, COLIN automation runs, domain registered, CRTC letter generated + eSigned, binder compiled, MinIO upload, customer emails received
  • Document any failures and fix before first real customer order

Track 2 — US Formation (Second Revenue Stream)

2.1 Wyoming End-to-End [FORMATION]

WY is the highest-priority state — selectors verified on name search, no CAPTCHA, cheapest filing fee.

  • Implement WY filing automation: walk the WYO SOS filing wizard step-by-step with Playwright, map all form field selectors
  • Wire payment step: WY SOS accepts credit card — use relay-filing-card
  • Test: place a real WY LLC order, confirm name search works, confirm filing completes, confirm confirmation number saved to DB
  • Wire formation worker to create ERPNext Formation Order + Sales Invoice on order receipt
  • Wire formation worker to send order confirmation email after payment

2.2 Colorado End-to-End [FORMATION]

CO name search is already working (Socrata API). Need filing automation.

  • Research CO SOS filing wizard (sos.state.co.us), map selectors
  • Implement CO LLC filing automation
  • Test end-to-end

2.3 Server-Side Fee Validation [FORMATION][PLUMBING]

Currently the API trusts client-submitted state_fee_cents. This is a billing vulnerability.

  • Add server-side lookup: on order receipt, look up state_fee_cents from state_filing_fees DB table using state code
  • Reject any order where client-submitted fee does not match DB value
  • Audit and fix the 12+ known fee discrepancies between the frontend hardcoded array and DB (identified last session)

2.4 Operating Agreement + EIN [FORMATION]

  • Test operating agreement DOCX generation end-to-end (template → DocxBuilder → PDF → MinIO)
  • Test EIN obtainment worker (IRS Playwright) on a real WY entity after filing
  • Confirm both documents are attached to the ERPNext Formation Order and emailed to customer

2.5 DocServer (Windows VM) [FORMATION][INFRA]

LibreOffice fallback produces lower-quality PDFs. Office 2021 on Windows is required for production-quality DOCX→PDF conversion.

  • Provision Windows Server 2022 VM in Proxmox (2 vCPU, 4 GB RAM, 40 GB SSD)
  • Install Microsoft Office 2021
  • Deploy DocServer Flask app on port 5050
  • Configure DOCSERVER_URL env var to point workers at Windows VM
  • Verify: workers use DocServer when available, fall back to LibreOffice when not

2.6 Remaining State Adapters [FORMATION]

Priority order based on formation volume. Each requires: portal inspection, selector extraction, Playwright implementation, payment wiring.

  • Delaware (DE) — CAPTCHA. Integrate 2captcha or AntiCaptcha solving service first.
  • Florida (FL) — High demand. Playwright needed, no CAPTCHA expected.
  • Texas (TX) — SOSDirect account needed for search. Get account first.
  • Nevada (NV) — WAF. Use stealth Playwright (playwright-extra + puppeteer-stealth).
  • Utah (UT) — Name search works without login. Filing needs UtahID OAuth.
  • New Mexico, Ohio, Montana — Untested, research portals.
  • Remaining 37 states — Batch: inspect portals, extract selectors, implement in priority order.

Track 3 — Infrastructure & Ops

3.1 Production Deployment [INFRA][BLOCKER]

The rsync to production timed out. Get the current codebase deployed.

  • Fix rsync: run with --timeout=30 and --compress, or use a staged approach (tar | ssh)
  • On server: docker compose build && docker compose up -d
  • Update ERPNext Docker image: rebuild performancewest-erpnext:latest with latest frappe_ca_registry + performancewest_erpnext changes
  • Run any pending DB migrations on production

3.2 Environment Variables [INFRA]

Several env vars are not yet set in production .env.

  • PORKBUN_API_KEY / PORKBUN_SECRET_KEY
  • FLOWROUTE_ACCESS_KEY / FLOWROUTE_SECRET_KEY
  • HESTIA_HOST / HESTIA_USER / HESTIA_PASSWORD
  • SHKEEPER_API_KEY
  • ADYEN_API_KEY / ADYEN_MERCHANT_ACCOUNT / ADYEN_CLIENT_KEY (when account approved)
  • DOCSERVER_URL (when Windows VM is provisioned)
  • CUSTOMER_JWT_SECRET (for portal auth)

3.3 Monitoring & Alerts [INFRA]

  • Set up UptimeRobot (free) to monitor: performancewest.net, api.performancewest.net, crm.performancewest.net, pay.performancewest.net
  • Configure alert email to ops@performancewest.net
  • Set up weekly automated DB backup to MinIO (pg_dump → minio/backups/)
  • Verify ERPNext daily backup is configured and uploading to MinIO

Track 4 — Payment & Billing Completion

4.1 Bundle / Compliance Checkout [PLUMBING]

The Express API returns null for bundle and compliance service checkout. These are broken.

  • Implement bundle checkout in api/src/routes/checkout.ts: look up bundle from service_bundles table, create Sales Order + Invoice with correct line items and 20% bundle discount
  • Implement compliance service checkout (CCPA audit, FLSA audit, etc.): create Sales Invoice with correct item and turnaround date
  • Test both flows end-to-end through payment

4.2 Subscription / Renewal Billing [PLUMBING]

Annual renewals (RA $99/yr ($49 WY), Annual Report $99/yr, CRTC Maintenance $349/yr) exist as ERPNext Subscription Plans but the renewal worker is not wired to trigger them.

  • Wire renewal_handler.py: on subscription due date (from Compliance Calendar), create ERPNext Sales Invoice + Payment Request, send renewal email with payment link
  • Test: manually trigger a renewal for a test customer, confirm invoice created, confirm email sent, confirm payment marks subscription renewed

4.3 Refund Flow [PLUMBING]

  • Verify ERPNext Credit Note flow works end-to-end
  • Test: issue a partial refund on a test invoice, confirm Adyen processes the refund, confirm customer email is sent
  • Document refund policy in customer-facing portal

Track 5 — Docs Update

All 15 docs have stale content. These need to be rewritten to match current state before bringing on any contractors or making architectural decisions.

Critical (do first):

  • docs/architecture.md — Replaced Mautic with Listmonk. Added DocServer, workers, portal. Updated container count to 15.
  • docs/go-live-todo.md — Marked completed items. Added multi-province priority 11. Updated pricing.
  • docs/formation-system.md — Updated BC section with BITS/CCTS/GCKey/compliance. Updated DocServer.
  • docs/crm.md — Replaced Mautic Integration → Listmonk. Added CRTC campaign.

High priority:

  • docs/product-facts.md — Added Canada annual maintenance ($349), consulting ($75/hr), Canadian formation (C$449), maintenance bundles ($179/yr). Updated CRTC pipeline to 14 steps.
  • docs/billing.md — Added renewal billing, compliance calendar billing, maintenance bundles, Canadian formation pricing.
  • docs/infrastructure.md — Replaced Mautic/MySQL with Listmonk. Updated container count to 15. Added portal nginx config.

Medium priority:

  • docs/marketing.md — Add FCC RMD as primary lead gen channel. Add Listmonk drip campaign details. Add 3 campaign descriptions.
  • docs/state-automation-status.md — Updated BC section with all new capabilities + GCKey automation table.
  • docs/document-generation.md — Update DocServer section (MinIO transport, not HTTP). Add template list.

Track 6 — frappe_registry Migration (Future)

This is a significant refactor — ~24 hours of work. Do not start until CRTC pipeline is working end-to-end and at least WY formation is live.

  • Rename frappe_ca_registryfrappe_registry
  • Generalize CA Filing Request DocType to Registry Filing Request (55 jurisdictions)
  • Add Registry Settings DocType: NWRA defaults, per-state RA override, CA mailbox config
  • Move 51 US state adapters from scripts/formation/states/ into Frappe app
  • Add extra-provincial registration support (10 Canadian provinces)
  • Add foreign state qualification support (US foreign entity)
  • Define BaseAdapter interface with auto-discovery by jurisdiction code
  • Build fee scraper framework:
    • base_scraper.py — abstract scraper class with rate limiting, retry, user-agent rotation
    • pdf_scraper.py — Tesseract OCR for scanned fee schedule PDFs, pdfplumber for text PDFs
    • fee_change_detector.py — compares scraped values against DB, generates diff report
    • Admin email alert when any fee changes (does NOT auto-update — human review required)
    • Monthly cron job in workers container (0 6 1 * * — 1st of each month, 6am)
    • Store scraped results in state_fee_scrape_history table with timestamp + source URL + old/new values
  • Implement US state fee scrapers (51 jurisdictions):
    • Tier 1 (top 10 by formation volume): WY, DE, FL, TX, NV, CA, CO, NY, GA, IL
    • Tier 2 (remaining 41 states + DC)
    • Handle: annual report fees, franchise taxes, business license fees, privilege taxes, personal property returns
    • Reference: docs/state-annual-fees-complete.md for current verified values + source URLs
  • Implement Canadian province fee scrapers (10 provinces):
    • BC, AB, ON, QC, MB, SK, NS, NB, PE, NL
    • Scrape in CAD, convert to USD via fx.ts Bank of Canada rate + 10% buffer
  • Fix fee data integrity: DB as single source of truth, frontend fetches from API, server-side validation (see 2.3)

Launch Readiness Checklist

Before accepting the first paying customer:

  • ERPNext payment gateways configured (Track 1.1)
  • CRTC end-to-end test passes (Track 1.5)
  • Portal authentication implemented (Track 1.4)
  • Order confirmation email sends after payment (Track 1.3)
  • Production deployed with current codebase (Track 3.1)
  • All env vars set in production (Track 3.2)
  • UptimeRobot monitoring configured (Track 3.3)

Formation orders can follow ~2 weeks after CRTC is live (WY first).


Open Questions / Decisions Needed

Question Context Deadline
Adyen account approval status? Without Adyen, card/ACH payments are blocked. Only crypto works. Before first customer
NotaryLive account — go or no-go? $59/mo + $23/session for BITS affidavit notarization. Alternative: partner with a Canadian notary. Before first CRTC delivery
Anytime Mailbox credential handoff policy? Provider confirmed no API; Playwright signup uses shared inbox OTP. Decide whether to bootstrap with filings@performancewest.net then transfer to client, or require client email from the start. Before first customer
Portal auth strategy? ERPNext portal login vs. signed JWT in email link. Signed JWT is simpler, no password needed. Before first customer uses portal
Canadian accountant? 3 hours free accounting support is promised in the CRTC package. Need to onboard a freelance Canadian accountant. Before first delivery