From 2312edf5dfabae63db8442049263fb844acf3254 Mon Sep 17 00:00:00 2001 From: justin Date: Wed, 29 Apr 2026 08:39:03 -0500 Subject: [PATCH] Add FCC Carrier/ISP Registration: migration + order page Phase 1-2 of the new registration product: - Migration 075: fcc_carrier_registrations table with full pipeline status, service wizard answers, entity choice, pricing, idempotency tracking - Order page with 5-step wizard: 1. Service wizard (voice/broadband/wholesale + delivery method + infra needs) 2. Registration checklist (auto-determined + add-ons with dynamic pricing) 3. Entity choice (existing FRN search OR new formation with nexus guidance) 4. Contact & officer info 5. Review & payment with engagement clickwrap Still needed: API endpoint, checkout integration, worker pipeline handler. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../075_fcc_carrier_registration.sql | 128 +++ .../order/fcc-carrier-registration/index.html | 754 ++++++++++++++++++ 2 files changed, 882 insertions(+) create mode 100644 api/migrations/075_fcc_carrier_registration.sql create mode 100644 site/public/order/fcc-carrier-registration/index.html diff --git a/api/migrations/075_fcc_carrier_registration.sql b/api/migrations/075_fcc_carrier_registration.sql new file mode 100644 index 0000000..7e9cfc7 --- /dev/null +++ b/api/migrations/075_fcc_carrier_registration.sql @@ -0,0 +1,128 @@ +-- 075_fcc_carrier_registration.sql +-- +-- FCC Carrier / ISP Registration — dedicated order table with +-- CRTC-style multi-step pipeline. Supports optional formation, +-- CORES/FRN, Form 499, state PUC, and compliance filings. + +BEGIN; + +CREATE TABLE IF NOT EXISTS fcc_carrier_registrations ( + id BIGSERIAL PRIMARY KEY, + order_number TEXT NOT NULL UNIQUE, -- FCR-YYYY-XXXXX + + -- Customer + customer_email TEXT NOT NULL, + customer_name TEXT NOT NULL, + customer_phone TEXT, + + -- Entity choice + entity_source TEXT NOT NULL CHECK (entity_source IN ('existing', 'new_formation')), + telecom_entity_id INTEGER, + formation_order_number TEXT, + + -- Entity info (populated from either source) + entity_legal_name TEXT, + entity_type TEXT, + formation_state CHAR(2), + ein TEXT, + frn TEXT, + filer_id_499 TEXT, + + -- Contact / Officer + contact_name TEXT, + contact_email TEXT, + contact_phone TEXT, + contact_title TEXT, + address_street TEXT, + address_city TEXT, + address_state CHAR(2), + address_zip TEXT, + + -- Service wizard answers (JSONB for flexibility) + service_wizard JSONB NOT NULL DEFAULT '{}'::jsonb, + -- e.g. { service_types: ["voice","broadband"], voice_delivery: "reseller", + -- needs_lcr: true, broadband_type: "facilities_based", operating_states: 5 } + + -- Service configuration (derived from wizard + confirmation) + include_formation BOOLEAN NOT NULL DEFAULT FALSE, + include_dc_agent BOOLEAN NOT NULL DEFAULT TRUE, + include_rmd BOOLEAN NOT NULL DEFAULT FALSE, + include_cpni BOOLEAN NOT NULL DEFAULT FALSE, + include_calea BOOLEAN NOT NULL DEFAULT FALSE, + include_bdc BOOLEAN NOT NULL DEFAULT FALSE, + include_stir_shaken BOOLEAN NOT NULL DEFAULT FALSE, + include_ocn BOOLEAN NOT NULL DEFAULT FALSE, + state_puc_states TEXT[] DEFAULT '{}', + + -- Pipeline status + status TEXT NOT NULL DEFAULT 'received' CHECK (status IN ( + 'received', + 'awaiting_formation', + 'formation_complete', + 'cores_registration', + 'form_499_initial', + 'state_registrations', + 'compliance_filings', + 'review', + 'delivered', + 'cancelled' + )), + + -- Pricing (cents) + service_fee_cents INTEGER NOT NULL DEFAULT 129900, + formation_fee_cents INTEGER NOT NULL DEFAULT 0, + state_fee_cents INTEGER NOT NULL DEFAULT 0, + puc_fee_cents INTEGER NOT NULL DEFAULT 0, + addon_fee_cents INTEGER NOT NULL DEFAULT 0, + discount_cents INTEGER NOT NULL DEFAULT 0, + discount_code TEXT, + + -- Payment + payment_status TEXT NOT NULL DEFAULT 'pending_payment' + CHECK (payment_status IN ('pending_payment','paid','refunded','cancelled')), + payment_method TEXT, + stripe_session_id TEXT, + paid_at TIMESTAMPTZ, + + -- ERPNext + erpnext_sales_order TEXT, + + -- Pipeline tracking (idempotency timestamps) + formation_completed_at TIMESTAMPTZ, + cores_completed_at TIMESTAMPTZ, + frn_obtained TEXT, + form_499_completed_at TIMESTAMPTZ, + filer_id_obtained TEXT, + dc_agent_completed_at TIMESTAMPTZ, + state_puc_completed_at TIMESTAMPTZ, + rmd_completed_at TIMESTAMPTZ, + cpni_completed_at TIMESTAMPTZ, + calea_completed_at TIMESTAMPTZ, + bdc_completed_at TIMESTAMPTZ, + stir_shaken_completed_at TIMESTAMPTZ, + ocn_completed_at TIMESTAMPTZ, + + -- Engagement + engagement_accepted_at TIMESTAMPTZ, + engagement_accepted_ip TEXT, + + -- Timestamps + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW() +); + +CREATE INDEX IF NOT EXISTS idx_fcr_customer_email ON fcc_carrier_registrations(customer_email); +CREATE INDEX IF NOT EXISTS idx_fcr_status ON fcc_carrier_registrations(status) WHERE status NOT IN ('delivered','cancelled'); +CREATE INDEX IF NOT EXISTS idx_fcr_formation ON fcc_carrier_registrations(formation_order_number) WHERE formation_order_number IS NOT NULL; + +-- Updated_at trigger +CREATE OR REPLACE FUNCTION set_updated_at_fcr() RETURNS trigger AS $$ +BEGIN NEW.updated_at = NOW(); RETURN NEW; END; +$$ LANGUAGE plpgsql; + +DROP TRIGGER IF EXISTS trg_fcr_updated_at ON fcc_carrier_registrations; +CREATE TRIGGER trg_fcr_updated_at + BEFORE UPDATE ON fcc_carrier_registrations + FOR EACH ROW EXECUTE FUNCTION set_updated_at_fcr(); + +COMMIT; diff --git a/site/public/order/fcc-carrier-registration/index.html b/site/public/order/fcc-carrier-registration/index.html new file mode 100644 index 0000000..0902d01 --- /dev/null +++ b/site/public/order/fcc-carrier-registration/index.html @@ -0,0 +1,754 @@ + + + + + + + +FCC Carrier / ISP Registration — Performance West Inc. + + + + + + + +
+

FCC Carrier / ISP Registration

+

Start your telecom carrier or ISP from scratch. We handle all federal and state registrations based on the services you plan to offer.

+ +
+
1
+
2
+
3
+
4
+
5
+
+ + + + +
+

What services will you offer?

+

Tell us what you plan to do and we'll determine exactly which registrations you need.

+ + +
+

What type of service will you offer?

+

Select all that apply.

+ + + +
+ + + + + + + + + + + + + +
+ +
+
+ + + + + + + + + + + + + + + + + + + + +
+ + + +