Commit graph

83 commits

Author SHA1 Message Date
justin
050b19a43a Enable STIR/SHAKEN card in compliance checker with originate/terminate toggle
- Uncomment STIR/SHAKEN check in fcc-lookup.ts — shows self-reported
  implementation status from RMD filing
- Add toggle: "Do you originate calls or only terminate?"
  - Terminate only → green, signing cert not required, file RMD as
    partial implementation
  - Originate or both → red, must have own STI certificate as of
    June 2025
- Toggle integrates with pending-question system (CTA waits for answer)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 10:55:00 -05:00
justin
b02b5b4c1f Add STIR/SHAKEN originate vs terminate guidance in Q3
Wholesale providers that only receive/terminate pre-signed calls don't
need a STIR/SHAKEN signing certificate. Info box explains: originating
providers must sign with own cert (as of June 2025), but
terminating-only providers just verify signatures (software config)
and file RMD as "partial implementation."

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 10:52:18 -05:00
justin
3ea47b52ed Fix Q5 showing retail variant for wholesale carriers
Q5 was shown immediately on voice/broadband checkbox, before Q1b
(customer type) was answered — always defaulting to retail variant.
Now Q5 only appears after Q1b is answered, and the correct variant
(retail vs wholesale) is set at that point.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 10:48:53 -05:00
justin
653837617e Clarify non-interconnected VoIP with examples
Explain that non-interconnected VoIP means voice apps without phone
numbers (e.g. Microsoft Teams, Discord) to distinguish from
interconnected VoIP which connects to the PSTN.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 10:08:51 -05:00
justin
dec69ffc0e Add contact-us notice for non-standard service types
Non-interconnected VoIP, satellite, paging, private radio, and other
specialized services have different registration requirements. Show
a yellow info box under Q1 directing these users to contact us for
a custom assessment instead of using the wizard.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 10:02:02 -05:00
justin
337528b08a Split Q5 into retail vs wholesale variants
Retail carriers: ask where end-user customers are located, explain
state PUC nexus (registration triggered by customer location, not
incorporation). Wholesale carriers: simplified question about carrier
customer regions, explains they generally don't need state PUC
registration since the retail carrier holds the state obligation.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 10:01:46 -05:00
justin
9c4d65c7a9 Skip Q2 voice delivery for wholesale-only carriers
Wholesale voice carriers run their own switching by definition — the
Q2 options (reseller, UCaaS, own switch) are retail delivery models.
When wholesale is selected in Q1b, Q2 is hidden and Q3 (infrastructure
needs: LCR, DIDs, interconnection, STIR/SHAKEN) is shown directly.
voiceDelivery is auto-set to own_switch for wholesale.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 09:59:03 -05:00
justin
3273a7020e Rewrite Q5 to ask where customers are located, explain state PUC nexus
State PUC registration is triggered by customer location, not
incorporation state. Telecom services use local infrastructure
(switches, numbers, towers) creating attributional nexus. Rewritten
Q5 explains this and provides guidance: ~27 states need full
certification, ~9 registration only, ~5 minimal. Shows PUC info
box for multi-state/nationwide selections.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 09:44:41 -05:00
justin
f6809730e5 Recommend Canada CRTC registration for international carriers
When carrier selects "Yes" to international services on Q6, show a
Canada CRTC recommendation box explaining: direct Canadian DIDs,
lower termination rates vs US gateway routing, CRTC interconnection.
Links to /order/canada-crtc with pricing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 09:39:03 -05:00
justin
eee3af0919 Add CALEA retail/wholesale toggle to FCC compliance checker
When CALEA SSI card shows red/amber, ask if carrier serves end users
(retail) or only other carriers (wholesale). Wholesale-only carriers
are exempt as "interconnecting carriers" under CALEA — card turns
green. Retail/both keeps the red status. Toggle integrates with
existing pending-question system (CTA waits for all toggles answered).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 09:38:35 -05:00
justin
c6863f7eae Add CALEA wholesale exemption, international Q6, Section 214 add-on
- CALEA: wholesale-only carriers exempt as "interconnecting carriers" per
  FCC rules. Only retail/both customer types trigger CALEA SSI requirement.
- New Q6 "Will you offer international services?" appears after Q5.
  Triggers International Section 214 Authorization add-on ($1,499).
- Section 214 info box explains when it's required.
- Customer type question (Q1b) is now visually separate from service
  type checkboxes to avoid confusion.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 09:35:27 -05:00
justin
790e980ef8 Separate customer type into its own question section
The retail/wholesale radios were visually mixed in with the voice/broadband
checkboxes, making it easy to misread "Wholesale" as a service type.
Moved to a distinct Q1b section "Who are your customers?" that only
appears after checking voice or broadband. Single selection covers
both services (retail / wholesale / both).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 09:33:42 -05:00
justin
95d4779660 Split retail/wholesale into per-service radios for voice and broadband
Voice and broadband can have independent customer models (e.g. wholesale
voice + retail broadband). Each service type now gets its own inline
retail/wholesale/both radio when checked. Derivation logic updated:
- Voice carriers always need RMD+CPNI regardless of mode
- BDC only required when broadband has retail end users
- CALEA still triggered by voice or facilities-based broadband

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 09:12:18 -05:00
justin
b473bf1783 Fix pricing calculation: remove feedback loop in updatePrice
wizard.addonFee was being subtracted and then recalculated each call,
causing prices to accumulate/subtract randomly on checkbox toggle.
Simplified to just sum base + checked addons + formation fees.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 08:55:21 -05:00
justin
2927b5cebb Add FCC Carrier/ISP Registration: API, checkout, handler, dispatch
Phase 3-5:
- API: POST /api/v1/fcc-carrier-registration (order creation with pricing)
- API: GET /api/v1/fcc-carrier-registration/:id (status)
- API: GET /api/v1/fcc-carrier-registration/state-fees (formation fees)
- Checkout: fcc_carrier_registration order type with Stripe line items
- Payment handler: dispatch worker + send confirmation email
- Pipeline handler: 8-step CRTC-style pipeline (formation → CORES → 499 →
  DC Agent → State PUC → RMD/CPNI/CALEA/BDC → add-ons → final review)
- Job server dispatch map entry
- Service page CTA updated to link to order page

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 08:48:36 -05:00
justin
830f5ae738 All standard registrations included in base $1,299, only add-ons are extra
Base package includes CORES/FRN, Form 499, DC Agent, RMD, CPNI, CALEA,
BDC — all shown as included with checkmarks. Wizard determines which
are relevant (grayed out if not needed for service type).

Only STIR/SHAKEN (+$499), OCN (+$2,650), State PUC (+$399/state),
and formation are itemized add-ons.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 08:40:56 -05:00
justin
2312edf5df 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>
2026-04-29 08:39:03 -05:00
justin
94ce14dc17 Explain IPES = VoIP provider in plain language, expand service description
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 08:14:55 -05:00
justin
118d24cc1a Rename 'IPES & ISP Registrations' to 'FCC Carrier / ISP Registration'
Updated across 61 static HTML files (nav links), bundles catalog,
service page title/description/heading, and llms.txt.
URL stays /services/telecom/ipes-isp (no redirect needed).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 08:06:47 -05:00
justin
424a7f3b2d Add missing updateResource import
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:49:07 -05:00
justin
28b407eea6 Fix portal user linking: use updateResource instead of set_value for child table
set_value doesn't work for child tables like portal_users. Use
updateResource (PUT /api/resource/Customer) which handles it correctly.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:48:05 -05:00
justin
02d2415d7a Fix escaped backtick that broke Docker Astro build
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:42:12 -05:00
justin
e1b95a20fb Show 'Intake Already Completed' screen with Revise button on revisit
When the user revisits a completed intake (intake_data_validated=true),
shows a success screen with Go to Portal and Revise buttons instead of
the blank form. Revise adds ?revise=1 to bypass the check.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:40:48 -05:00
justin
314a711e95 Fix: add batch_id + engagement columns to job_server PG query
batch_id was missing from the SELECT, so order_data.batch_id was always
None. This meant the batch email skip in _request_entity_intake never
triggered, causing duplicate intake emails for every batch order.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:35:56 -05:00
justin
e49efb7207 Scroll to page title on step navigation instead of wizard body
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:31:34 -05:00
justin
f6f4853ab6 Scroll to top of wizard on Next/Back step navigation
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:29:32 -05:00
justin
27108b9080 Change prefill notice to 'public sources' instead of 'FCC records'
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:28:40 -05:00
justin
1f87ad4554 Add pre-fill review notice on every step, fix CORES address detection
- Yellow banner on each step: "We've pre-filled this from your FCC records.
  Please review carefully and correct any information that is inaccurate."
- Only shows when accessed via token/FRN (post-payment intake)
- CORES address: filter by company name suffix (LLC/Inc/Corp) instead of
  requiring a number — addresses like "PO Box 123" now work

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:26:25 -05:00
justin
42f331101e Skip CORES address suggestion when it's just the company name
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:24:10 -05:00
justin
63f74e8486 Style officer suggestions as clickable cards with arrow hint
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:22:25 -05:00
justin
834d2fc1ee Keep officer suggestions visible after selection, highlight chosen one
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:18:11 -05:00
justin
dcdc6df879 Fix CategoryStep crashing non-499-A intake pages
CategoryStep script runs on ALL pages using the Wizard component.
It tried to find #pw-wizard (its inner quiz div) and called
querySelectorAll on it — null on CPNI/RMD/etc pages, crashing the
entire script bundle. This prevented FRN auto-fill, officer
suggestions, and all other intake functionality.

Guard: if #pw-wizard doesn't exist, skip all CategoryStep logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:13:06 -05:00
justin
acf63eb819 Officer suggestions: use FCC data (RMD contact, CORES address) instead of entity_cache
Entity cache has no RA/officer data yet. Instead, fetch the FCC lookup
(quick mode) and offer RMD contact name + address and CORES principal
address as clickable suggestions to auto-fill Officer 1.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 01:02:18 -05:00
justin
6a0162f0a9 Simplify Officer step: remove count dropdown, officers 2+3 optional
- Removed "How many officers" dropdown — all 3 always visible
- Officers 2 and 3 marked as (optional) in legend
- Only Officer 1 validated (name, title, street, city required)
- Blank optional officers skipped in saved data

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-29 00:56:45 -05:00
justin
59c2d06736 Always show corp suggestions on Officer step, check intake_data for name
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 23:37:22 -05:00
justin
f5d307a1e8 Fix corp search LIMIT type: cast to int
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 23:05:43 -05:00
justin
159a576157 Add corporate record suggestions on Officer step, search all states
- OfficerStep searches entity_cache for matching corporations when loaded
- Shows clickable suggestions with RA name and address to auto-fill Officer 1
- Pre-fills contact_name/email/phone from entity data (helps data-only filers)
- Corp search endpoint: state param now optional (searches all states)
- Corp search returns registered_agent and principal_address fields

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 23:02:16 -05:00
justin
ab7a2d7dc0 Rename EIN to TIN/EIN, accept SSN format (XXX-XX-XXXX)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 18:53:24 -05:00
justin
862c06a8fd Add validation to CPNI and STIR/SHAKEN intake steps
- CPNI: requires either clean compliance checkbox OR issues section opened
- STIR/SHAKEN: requires selecting implementation status before advancing

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 18:40:28 -05:00
justin
06143c51c2 Add stricter entity step validation: structure, EIN format, address required
- Entity structure (LLC/Corp/etc) is now required
- EIN must be provided and match XX-XXXXXXX format
- Full address (street, city, state, ZIP) required
- Email validation format checked

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 18:35:43 -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
3dce721120 Add PUT to CORS allowed methods (needed for intake save)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 18:29:00 -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
3614284a78 Fix intake wizard: global styles for JS-created step bar, re-render after pre-fill
- Changed <style> to <style is:global> so CSS applies to dynamically
  created step chips (Astro scoped styles don't match JS-created elements)
- After async pre-fill from order data completes, re-renders the active
  step so EntityStep reads the populated state
- Removes payment step when token/order param is present

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 05:04:21 -05:00
justin
5d9b378e55 Scroll to results anchor when search result is clicked
Immediate scroll before the FCC lookup starts, so the user sees
the loading spinner even when the search results list is long.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 04:58:59 -05:00
justin
0d07b6a2d9 Skip worker intake emails for batch orders, remove payment step for paid orders
- Batch orders: checkout API already sends combined intake email, so worker
  handlers no longer send their own (was causing 2-3 duplicate emails)
- When accessed via ?token= or ?order= (post-payment), the "payment" step
  is removed from the intake wizard since payment is already complete

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 04:52:49 -05:00
justin
99bdfdfd91 DC Agent: don't send acceptance letter until NW order is placed
The handler was returning the acceptance letter as an artifact, which
triggered the instant-delivery email to the client before the admin
placed the wholesale order with Northwest. Now uploads to MinIO but
returns empty artifacts. Admin todo includes the MinIO path to send
the letter after confirming the NW order.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 04:50:15 -05:00
justin
98a4c90e3a Pre-fill intake wizard from order data + FRN, use quick mode for FCC lookup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 04:46:09 -05:00
justin
af65fca709 Show portal link for existing accounts even if never logged in
Previously required both has_account && returning (logged in before).
Now shows portal link whenever has_account is true.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 04:35:22 -05:00
justin
e76f54b11f Fix batch Payment Entry (paidAmountCents was 0), fix CTA button JS syntax error
- Batch invoice creation now calculates actual total from line items
- Fixed JS syntax error: `className = "..." style="..."` was invalid JS
  (style= outside string literal caused Unexpected identifier 'style')
- Portal menu: set hide_standard_menu=1 to remove duplicate sidebar items

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-28 04:20:05 -05:00