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) <noreply@anthropic.com>
This commit is contained in:
justin 2026-04-29 08:39:03 -05:00
parent 94ce14dc17
commit 2312edf5df
2 changed files with 882 additions and 0 deletions

View file

@ -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;