From 47ca1bf10fbfe68675e9163cab0dc3b252775d1f Mon Sep 17 00:00:00 2001 From: justin Date: Mon, 4 May 2026 05:28:13 -0500 Subject: [PATCH] Production readiness fixes: 3 critical + 2 high-priority MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- api/src/routes/compliance-orders.ts | 3 ++ scripts/workers/services/canada_crtc.py | 2 +- .../services/fcc_carrier_registration.py | 2 +- .../order/fcc-carrier-registration/index.html | 45 ++++++++++++++++++- 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/api/src/routes/compliance-orders.ts b/api/src/routes/compliance-orders.ts index fde6551..3d8c5a6 100644 --- a/api/src/routes/compliance-orders.ts +++ b/api/src/routes/compliance-orders.ts @@ -343,6 +343,8 @@ const REQUIRED_FIELDS: Record = { "fcc-63-11-notification": { required: ["foreign_carrier.foreign_carrier_legal_name", "foreign_carrier.country", "foreign_carrier.ownership_pct", "foreign_carrier.affected_routes", "foreign_carrier.affiliation_date"], soft: ["foreign_carrier.notification_type"] }, "ocn-registration": { required: ["service_category", "operating_states"], soft: ["expedited"] }, "dc-agent": { required: [], soft: [] }, + "fcc-499q": { required: ["quarter", "revenue"], soft: [] }, + "fcc-499a-discontinuance": { required: ["filer_id_499", "discontinuance_reason"], soft: ["last_service_date", "successor_entity"] }, "cdr-analysis": { required: ["reporting_year"], soft: ["reporting_period"] }, "fcc-full-compliance": { required: [ @@ -364,6 +366,7 @@ const REQUIRED_FIELDS: Record = { // service can run"). Checked against the linked telecom_entity. const REQUIRES_ENTITY_FRN: ReadonlySet = new Set([ "rmd-filing", "cpni-certification", "fcc-499a", "fcc-499a-zero", "fcc-499a-499q", + "fcc-499q", "fcc-499a-discontinuance", "fcc-499-initial", "stir-shaken", "bdc-filing", "bdc-broadband", "bdc-voice", "calea-ssi", "fcc-63-11-notification", "fcc-full-compliance", ]); diff --git a/scripts/workers/services/canada_crtc.py b/scripts/workers/services/canada_crtc.py index 78c43f5..4529632 100644 --- a/scripts/workers/services/canada_crtc.py +++ b/scripts/workers/services/canada_crtc.py @@ -1319,7 +1319,7 @@ class CanadaCRTCHandler(BaseServiceHandler): name=director.get("name", ""), address=director.get("address", ""), city=director.get("city", ""), - state=director.get("province", province), + state=director.get("province", order_data.get("custom_incorporation_province", "BC")), zip_code=director.get("postal_code", ""), title="Director", is_organizer=director.get("is_incorporator", False), diff --git a/scripts/workers/services/fcc_carrier_registration.py b/scripts/workers/services/fcc_carrier_registration.py index cdd6b6f..c4b2d0a 100644 --- a/scripts/workers/services/fcc_carrier_registration.py +++ b/scripts/workers/services/fcc_carrier_registration.py @@ -146,7 +146,7 @@ class FCCCarrierRegistrationHandler: f" UPDATE fcc_carrier_registrations SET dc_agent_completed_at = NOW() " f"WHERE order_number = '{order_number}'", ) - self._update_step(order_number, "dc_agent_completed_at") + # Don't mark complete — admin must confirm NW order is placed first # ── Step 5: State PUC Registrations ─────────────────────────────── puc_states = order.get("state_puc_states") or [] diff --git a/site/public/order/fcc-carrier-registration/index.html b/site/public/order/fcc-carrier-registration/index.html index 1796753..70b1ecc 100644 --- a/site/public/order/fcc-carrier-registration/index.html +++ b/site/public/order/fcc-carrier-registration/index.html @@ -398,6 +398,8 @@ select:focus,input:focus{outline:none;border-color:#1e3a5f;box-shadow:0 0 0 2px // Contact contactName: '', contactEmail: '', contactPhone: '', contactTitle: 'Chief Executive Officer', addrStreet: '', addrCity: '', addrState: '', addrZip: '', + // State PUC + pucStates: [], // Pricing baseFee: 129900, formationFee: 0, stateFee: 0, pucFee: 0, addonFee: 0, }; @@ -581,6 +583,46 @@ select:focus,input:focus{outline:none;border-color:#1e3a5f;box-shadow:0 0 0 2px addonRow('International Section 214 Authorization', 149900, 'intl_214', wizard.needs214); addonRow('State PUC Registration (per state)', 39900, 'state_puc', false); + // State PUC picker — appears when state_puc checkbox is checked + var pucPicker = document.createElement('div'); + pucPicker.id = 'puc-state-picker'; + pucPicker.className = 'hidden'; + pucPicker.style.cssText = 'margin:0.5rem 0 0.5rem 1.5rem;padding:0.5rem 0.75rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px'; + pucPicker.innerHTML = '

Select states where you will have customers:

' + + '
' + + '

0 states selected ($0)

'; + addons.appendChild(pucPicker); + + var stateGrid = document.getElementById('puc-state-grid'); + STATES.forEach(function(s) { + var lbl = document.createElement('label'); + lbl.style.cssText = 'display:flex;align-items:center;gap:3px;font-size:.78rem;cursor:pointer;padding:2px 4px;border-radius:4px'; + lbl.innerHTML = ' ' + s[0]; + lbl.title = s[1]; + stateGrid.appendChild(lbl); + }); + + // Toggle picker visibility when state_puc checkbox changes + var pucCheckbox = addons.querySelector('[data-reg="state_puc"]'); + if (pucCheckbox) { + pucCheckbox.addEventListener('change', function() { + pucPicker.classList.toggle('hidden', !this.checked); + if (!this.checked) { + // Uncheck all states + document.querySelectorAll('[data-puc-state]').forEach(function(cb) { cb.checked = false; }); + wizard.pucStates = []; + } + updatePrice(); + }); + } + + // Update count + price when states are checked + stateGrid.addEventListener('change', function() { + wizard.pucStates = Array.from(document.querySelectorAll('[data-puc-state]:checked')).map(function(cb) { return cb.dataset.pucState; }); + document.getElementById('puc-count').textContent = wizard.pucStates.length + ' state' + (wizard.pucStates.length !== 1 ? 's' : '') + ' selected ($' + (wizard.pucStates.length * 399).toLocaleString() + ')'; + updatePrice(); + }); + updatePrice(); } @@ -595,7 +637,7 @@ select:focus,input:focus{outline:none;border-color:#1e3a5f;box-shadow:0 0 0 2px if (key === 'stir_shaken') { total += 49900; details.push('STIR/SHAKEN: +$499'); } if (key === 'ocn') { total += 265000; details.push('OCN: +$2,650'); } if (key === 'intl_214') { total += 149900; details.push('Intl 214: +$1,499'); } - if (key === 'state_puc') { total += 39900; details.push('State PUC: +$399/state'); } + if (key === 'state_puc') { var n = wizard.pucStates.length || 1; total += 39900 * n; details.push('State PUC: +$' + (399 * n).toLocaleString() + ' (' + n + ' state' + (n > 1 ? 's' : '') + ')'); } }); // Formation fees (if new entity) @@ -803,6 +845,7 @@ select:focus,input:focus{outline:none;border-color:#1e3a5f;box-shadow:0 0 0 2px infra_needs: wizard.infraNeeds, broadband_type: wizard.broadbandType, operating_states: wizard.operatingStates, + puc_states: wizard.pucStates, }, services: services, engagement_accepted: true,