gigafibre-fsm/docs/CUSTOMER-FLOW-ARCHITECTURE.md
louispaulb bfffed2b41 feat: ONT diagnostics — grouped mesh topology, signal RSSI, management link
- EquipmentDetail: collapsible node groups (clients grouped by mesh node)
- Signal strength as RSSI % (0-255 per 802.11-2020) with 10-tone color scale
- Management IP clickable link to device web GUI (/superadmin/)
- Fibre status compact top bar (status + Rx/Tx power when available)
- targo-hub: WAN IP detection across all VLAN interfaces
- targo-hub: full WiFi client count (direct + EasyMesh mesh repeaters)
- targo-hub: /devices/:id/hosts endpoint with client-to-node mapping
- ClientsPage: start empty, load only on search (no auto-load all)
- nginx: dynamic ollama resolver (won't crash if ollama is down)
- Cleanup: remove unused BillingKPIs.vue and TagInput.vue
- New docs and migration scripts

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-03 21:26:14 -04:00

26 KiB
Raw Blame History

Complete Customer Flow — From Lead to Live Service

Overview

┌──────────────────────────────────────────────────────────────────────┐
│                     CUSTOMER-FACING WEBSITE                         │
│  www.gigafibre.ca                                                   │
│                                                                     │
│  [Vérifier la disponibilité] ← Visitor enters address              │
│         │                                                           │
│         ▼                                                           │
│  ┌─────────────────────┐    ┌──────────────────────────────┐       │
│  │ Address Fuzzy Search │───▶│ Supabase / Address Server    │       │
│  │ (pg_trgm)           │    │ 5.2M RQA addresses           │       │
│  └─────────────────────┘    │ + fiber_availability table    │       │
│         │                   └──────────────────────────────┘       │
│         ▼                                                           │
│  ┌──── AVAILABLE ────┐   ┌──── NOT AVAILABLE ────┐                 │
│  │ Show plans/pricing │   │ "Pas encore disponible"│                │
│  │ Internet speeds    │   │ Capture contact info   │                │
│  │ TV packages        │   │ → Lead / Waitlist      │                │
│  │ Phone service      │   └────────────────────────┘                │
│  └────────┬───────────┘                                             │
│           ▼                                                         │
│  ┌──── CHECKOUT ─────┐                                              │
│  │ Summary: Internet  │                                             │
│  │ + TV (1st free)    │                                             │
│  │ + Phone optional   │                                             │
│  │ Choose 3 dates     │                                             │
│  │ Stripe payment     │                                             │
│  └────────┬───────────┘                                             │
└───────────┼──────────────────────────────────────────────────────────┘
            │
            ▼  WEBHOOK / API
┌──────────────────────────────────────────────────────────────────────┐
│                     BACK-OFFICE AUTOMATION                           │
│                                                                     │
│  n8n / targo-hub                                                    │
│  ┌──────────────────────────────────────────────────────────┐      │
│  │ 1. Create Customer in ERPNext                             │      │
│  │ 2. Create Service Location (address + OLT port)           │      │
│  │ 3. Create Service Subscriptions (internet/tv/phone)       │      │
│  │ 4. Create Project "Installation {customer}"               │      │
│  │    └─ Task: Assign tech + schedule from chosen dates      │      │
│  │    └─ Task: Prepare equipment (ONT + Deco + STB)          │      │
│  │    └─ Task: Activate OLT port (VLAN provisioning)         │      │
│  │    └─ Task: Configure WiFi/VoIP in provisioning DB        │      │
│  │ 5. Create Dispatch Job (tech assignment)                  │      │
│  │ 6. Send SMS confirmation (Twilio)                         │      │
│  │ 7. Send email confirmation (Mailjet)                      │      │
│  └──────────────────────────────────────────────────────────┘      │
│                                                                     │
└──────────────────────────────────────────────────────────────────────┘
            │
            ▼  TECHNICIAN ARRIVES
┌──────────────────────────────────────────────────────────────────────┐
│                     FIELD TECH APP                                   │
│                                                                     │
│  1. Open Dispatch Job → see address, OLT port, equipment list       │
│  2. Scan ONT barcode (RCMG/TPLG serial) → creates Service Equipment│
│  3. Scan Deco barcode → links to Service Location                   │
│  4. Scan STB barcode (if TV) → links to Service Location            │
│  5. Connect fiber → ONT powers up → TR-069 INFORM to ACS           │
│                                                                     │
└──────────────────────────────────────────────────────────────────────┘
            │
            ▼  DEVICE CONNECTS (TR-069 INFORM)
┌──────────────────────────────────────────────────────────────────────┐
│                     ACS (GenieACS → Oktopus)                        │
│                                                                     │
│  ┌─── ON BOOTSTRAP (first connect) ───┐                            │
│  │ 1. Identify device (OUI, model, SN) │                            │
│  │ 2. Match to Service Equipment       │                            │
│  │    (serial tag → ERPNext lookup)    │                            │
│  │ 3. Apply device profile:            │                            │
│  │    - Bridge mode (Raisecom)         │                            │
│  │    - WiFi SSID/pwd (Deco)           │                            │
│  │    - VoIP SIP credentials           │                            │
│  │    - NTP, DSCP, UPnP settings       │                            │
│  │ 4. Push firmware if needed           │                            │
│  │ 5. Notify targo-hub (SSE)           │                            │
│  │    → "Device online" event          │                            │
│  └──────────────────────────────────────┘                            │
│                                                                     │
│  ┌─── ON INFORM (periodic) ───┐                                    │
│  │ Refresh: IP, signal, hosts  │                                    │
│  │ Check firmware version      │                                    │
│  │ Report to monitoring        │                                    │
│  └─────────────────────────────┘                                    │
│                                                                     │
└──────────────────────────────────────────────────────────────────────┘
            │
            ▼  SERVICE LIVE
┌──────────────────────────────────────────────────────────────────────┐
│                     CUSTOMER PORTAL                                  │
│  client.gigafibre.ca                                                │
│                                                                     │
│  - View/pay invoices (Stripe QR)                                    │
│  - View subscriptions                                               │
│  - Change WiFi SSID/password → pushes to ACS                       │
│  - Open support tickets                                             │
│  - View service status                                              │
│                                                                     │
└──────────────────────────────────────────────────────────────────────┘

Phase 1: Address Search & Availability

Current State

  • AvailabilityDialog.tsx exists on www.gigafibre.ca
  • Fuzzy search via search_addresses() RPC (pg_trgm on Supabase)
  • 5.2M RQA addresses loaded
  • fiber_availability table with zone_tarifaire + max_speed
  • Lead capture sends email to support@targo.ca via Mailjet

What Needs to Change

Address source: The fiber_availability table needs to be linked to the fibre table (legacy). Currently fiber_availability has generic coverage data. It needs the actual OLT port availability:

fiber_availability (current)
  uuidadresse → address → zone_tarifaire + max_speed

fiber_availability (target)
  uuidadresse → address → fibre.id → OLT/slot/port → has_available_port (bool)
                                    → max_speed (from OLT capacity)
                                    → zone_tarifaire (pricing zone)

The fibre table IS the availability database:

  • 16,056 entries = 16,056 physical fibre drops to premises
  • 4,949 have an ONT installed (sn populated) = occupied port
  • 11,107 have no ONT = available for new service (but 1,149 are "boitier_pas_install")
  • Each entry has: address, OLT IP, frame/slot/port, ontid slot

Matching RQA addresses to fibre entries:

  • fibre.rue + fibre.ville + fibre.zip → fuzzy match to RQA address
  • OR fibre.latitude/longitude → nearest RQA address
  • Once matched: each RQA address either has a fibre entry (available) or not

OLT Capacity (30 OLTs, 25 locations)

OLT Location Total Connected Available
172.17.16.2 Saint-Anicet 2,155 844 1,311
172.17.32.2 Hemmingford 1,742 689 1,053
172.17.48.2 Saint-Antoine 1,383 594 789
172.17.64.2 Havelock 1,347 484 863
172.17.208.4 Athelstan 1,167 589 578
172.17.112.2 Saint-Louis 1,054 329 725
... ... ... ... ...
Total 25 locations 16,056 4,949 ~11,000

Phase 2: Pricing & Plan Selection

Product Catalog (from legacy, combo_ready=1)

Internet (Mensualités fibre):

SKU Speed ↓/↑ Price Profile
FTTH25 25/5 Mbps $49.95 LP:100
FTTH80I 80/80 Mbps $79.95 LP:101
FTTH150I 150/150 Mbps $99.95 LP:102
FTTH500I 500/500 Mbps $99.95 LP:103
FTTH1500I 1.5G/1G $109.95 LP:104

TV (Mensualités télévision):

SKU Name Price Note
TVBSKINNY Skinny $25 Base package
TVBSTANDARD Standard $30 Mid package
TVBEVO Evo $35 Premium
TELE Base TV $0 Included with internet?
+ add-ons Sports, Films, etc. $5-$25 each

Phone (Téléphonie):

SKU Price Note
TELEPMENS $28.95/mo Residential SIP line
SERV911 $0.69/mo 911 fee
ACTTELEP $69.95 once Activation

Discounts (combo):

SKU Discount Condition
RAB2X -$5 2 services
RAB3X -$10 3 services
RAB4X -$15 4 services
RAB_X -$20 Special
RAB24M -$15 24-month commitment
RAB36M -$15 36-month commitment

Checkout Logic

Monthly total = Internet plan
              + TV package (if selected)
              + TV add-ons
              + Phone ($28.95 if selected)
              + 911 fee ($0.69 if phone)
              - Combo discount (2x/3x/4x)
              - Commitment discount (24m/36m)

One-time charges:
  + Installation ($0 for standard FTTH)
  + TV box: 1st FREE, 2nd+ at regular price
  + Phone activation ($69.95)

First TV Box Credit

  • Detect: if order includes TV + this is customer's first box
  • Apply credit equal to STB equipment price
  • Show on summary: "1er décodeur offert"

Phase 3: Checkout & Order Submission

Customer Input

  1. Service selection (internet speed + TV package + phone yes/no)
  2. Address (pre-filled from availability check)
  3. Contact info (name, email, phone)
  4. Installation preference:
    • Choose from 3 available dates (next 2 weeks, exclude weekends)
    • OR "Contactez-moi" (we call to schedule)
  5. Payment (Stripe — card registered but NOT charged)

Payment Strategy

Website path (self-service):

  • Customer registers their card on Stripe (SetupIntent, not PaymentIntent)
  • We create a Stripe Customer + attach the payment method
  • No charge is taken at checkout — customer sees: "Aucun frais avant la complétion de l'installation à votre satisfaction"
  • Payment is collected AFTER installation is confirmed complete by the technician
  • On installation completion → auto-charge first month + one-time fees via Stripe

Agent path (phone order):

  • No payment collected upfront
  • Agent creates the order and an invoice is generated
  • Agent can send a payment link via email or SMS to the customer:
    • Stripe Checkout Session or Payment Link → customer pays when ready
    • SMS via Twilio: "Votre commande est confirmée! Payez ici: {link}"
    • Email via Mailjet: order summary + payment button
  • Payment can also be collected on-site by tech or post-installation

What Happens on Submit

POST /api/checkout
{
  address: { fibre_id, rue, ville, zip, olt_port, lat, lng },
  customer: { name, email, phone },
  services: [
    { sku: "FTTH150I", type: "internet" },
    { sku: "TVBSTANDARD", type: "tv" },
    { sku: "TELEPMENS", type: "phone" }
  ],
  preferred_dates: ["2026-04-07", "2026-04-09", "2026-04-11"],
  payment: {
    method: "stripe_setup",           // website: card registered, not charged
    stripe_customer_id: "cus_xxx",    // Stripe Customer created
    stripe_payment_method: "pm_xxx",  // Card saved for later charge
    // OR for agent path:
    method: "invoice_later",          // agent: no payment upfront
    send_payment_link: "email|sms|both"  // optional: send link to customer
  }
}

Phase 4: Back-Office Automation (n8n + targo-hub)

Trigger: New Order Webhook

n8n workflow: "New Customer Order"
═══════════════════════════════════

1. VALIDATE
   - Verify Stripe payment
   - Verify fibre port still available
   - Verify address matches fibre.id

2. CREATE CUSTOMER (ERPNext API)
   POST /api/resource/Customer
   {
     customer_name: "Jean Tremblay",
     customer_group: "Résidentiel",
     email_id, mobile_no,
     legacy_customer_id: null (new customer)
   }

3. CREATE SERVICE LOCATION
   POST /api/resource/Service Location
   {
     customer, address_line, city, postal_code,
     connection_type: "FTTH",
     olt_name, olt_ip, olt_frame, olt_slot, olt_port, ont_id,
     status: "Pending Install"
   }

4. CREATE SUBSCRIPTIONS (one per service)
   POST /api/resource/Service Subscription
   × Internet: { item: FTTH150I, location, status: "Pending" }
   × TV: { item: TVBSTANDARD, location, status: "Pending" }
   × Phone: { item: TELEPMENS, location, status: "Pending" }

5. CREATE SERVICE EQUIPMENT (pre-assigned)
   × ONT: { type: "ONT", serial: TBD (tech assigns on site) }
   × Deco: { type: "Routeur", serial: TBD }
   × STB: { type: "Décodeur TV", serial: TBD } (if TV)
   × ATA: { type: "Téléphone IP", serial: TBD } (if phone)

6. CREATE PROJECT "Installation - Jean Tremblay"
   Tasks:
   ☐ Préparer équipement (support)
   ☐ Assigner technicien (dispatch)
   ☐ Activer port OLT - frame/slot/port (support)
   ☐ Configurer WiFi dans DB provisioning (support)
   ☐ Configurer VoIP dans DB provisioning (if phone)
   ☐ Installation sur site (tech)
   ☐ Vérifier signal ONT (tech)
   ☐ Confirmer service fonctionnel (tech)

7. CREATE DISPATCH JOB
   {
     customer, location,
     preferred_dates: [...],
     required_tags: ["Fibre", "Installation"],
     equipment_list: [ONT, Deco, STB?],
     notes: "FTTH 150M + TV Standard + Phone"
   }

8. RESERVE FIBRE PORT
   UPDATE fibre SET sn = 'RESERVED-{order_id}'
   WHERE id = {fibre_id} AND (sn IS NULL OR sn = '')

9. SEND NOTIFICATIONS
   × SMS to customer: "Commande confirmée! Installation prévue le..."
   × Email to customer: order summary
   × SSE to Ops: new order event
   × Slack/Teams to dispatch: new installation job

Phase 5: Installation Day

Field Tech App Flow

1. Tech opens Dispatch Job on mobile
   → Sees: address, customer info, equipment list, OLT port

2. Tech picks up equipment from warehouse
   → Scans each barcode:
   - ONT: RCMG19E0XXXX → Service Equipment created, linked to location
   - Deco: 403F8CXXXXXX → Service Equipment created
   - STB: (ministra MAC) → Service Equipment created

3. Tech drives to site (GPS tracked via Traccar)
   → Customer gets SMS: "Technicien en route"

4. Tech installs fiber drop + ONT
   → ONT powers up → sends TR-069 BOOTSTRAP to ACS

5. ACS receives BOOTSTRAP
   → Matches ONT serial to Service Equipment
   → Applies provisioning profile:
     - Bridge mode, VLANs, DSCP
     - WiFi SSID/password (via ext script → provisioning DB)
     - VoIP SIP credentials (if phone service)
     - Firmware check/upgrade

6. Tech connects Deco router behind ONT
   → Deco sends TR-069 INFORM
   → ACS configures WiFi (SSID/password from DB)

7. Tech verifies:
   ☐ Internet speed test
   ☐ WiFi working on both bands
   ☐ TV channels loading (if applicable)
   ☐ Phone dial tone (if applicable)

8. Tech marks job complete in app
   → Service Location status → "Active"
   → Service Subscriptions → "Active"
   → Service Equipment status → "Actif"
   → Customer gets SMS: "Service activé!"
   → First invoice generated (pro-rated)

Phase 6: ACS Provisioning (GenieACS → Oktopus)

Current GenieACS Flow

ONT connects → CWMP INFORM
  → Preset matches (by ProductClass tag)
  → Provision script runs:
    1. bootstrap: clear tree, force refresh
    2. default: refresh hourly params (IP, MAC, hosts, firmware)
    3. model-specific inform:
       - HT803G-W: VoIP DSCP, NTP, bridge mode, UPnP off
       - Device2 (Deco): WiFi from DB (ext→provisioning.js→MariaDB)
       - XX230v/430v/530v: VoIP digit map, SIP server, DTMF
    4. firmware-upgrade: auto-push if version mismatch

Target Oktopus Flow

ONT connects → MQTT/CWMP
  → Device identified → matched to device group
  → Device profile applied:
    1. Webhook to targo-hub: GET /devices/{serial}/provision
       → targo-hub looks up Service Equipment in ERPNext
       → Returns: WiFi config, VoIP config, VLAN settings
    2. Oktopus pushes params to device
    3. Webhook to targo-hub: POST /devices/{serial}/activated
       → targo-hub updates Service Equipment status
       → Broadcasts SSE event to Ops UI

n8n Trigger for Device Events

Oktopus → MQTT topic: device/bootstrap/{serial}
  → n8n MQTT listener
  → n8n workflow:
    1. Look up serial in ERPNext Service Equipment
    2. If found: mark "Connected", update IP/firmware
    3. If NOT found: create Issue "Unknown device {serial}"
    4. Broadcast to targo-hub SSE

Phase 7: Not Available → Lead Funnel

When Address Has No Fiber

Visitor searches "123 rue Principale, Somewhere"
  → No fibre entry found
  → Show: "La fibre n'est pas encore disponible à votre adresse"

  ┌─────────────────────────────────────────────┐
  │ Options presented:                           │
  │                                              │
  │ 📱 Phone service is available anywhere!      │
  │    VoIP works over any internet connection   │
  │    → [Voir les forfaits téléphonie]          │
  │                                              │
  │ 🏢 Business fiber? Custom installation!      │
  │    → [Demander une soumission]               │
  │                                              │
  │ 📧 Be notified when fiber arrives:           │
  │    [email/phone] → [M'aviser]                │
  └─────────────────────────────────────────────┘

On "M'aviser" submit:
  → Create Lead in ERPNext (name, contact, address, interest)
  → Tag with area/municipality for future coverage planning
  → n8n: if address is in planned expansion zone, notify sales

On "Demander une soumission" (business):
  → Create Lead with type "Enterprise"
  → Create Issue "Soumission fibre entreprise - {address}"
  → Assign to sales team
  → n8n: send email to sales@targo.ca

Data Migration: What Needs to Happen

-- Match fibre entries to RQA addresses by fuzzy address + postal code
-- This enables the website availability check to return OLT port info
UPDATE fiber_availability fa
SET fibre_id = f.id,
    olt_ip = f.info_connect,
    olt_port = CONCAT(f.frame, '/', f.slot, '/', f.port),
    available = (f.sn IS NULL OR f.sn = '')
FROM fibre f
WHERE fa.address matches f.rue + f.ville (fuzzy)

2. Migrate Provisioning DB to ERPNext

For each device in genieacs.wifi:
  → Find Service Equipment by MAC (Deco) or serial (ONT)
  → Store WiFi SSID/password as custom fields on Service Equipment
  → Or: keep in a separate provisioning table that targo-hub queries

For each device in genieacs.voip:
  → Find Service Equipment by RCMG serial
  → Store SIP username/password as custom fields
  → Or: keep in Fonoster/Routr as SIP accounts

3. Map Legacy Customers to ERPNext

fibre.service_id → service.delivery_id → delivery.account_id
  → ERPNext Customer (legacy_customer_id = account_id)

Systems Inventory

System Role Current Target
www.gigafibre.ca Website + availability React/Vite + Supabase Same + checkout flow
Supabase Address DB + search 5.2M RQA addresses + fibre availability link
ERPNext CRM, billing, inventory Running Add provisioning fields
targo-hub SSE relay + API proxy SMS, voice, telephony, ACS + checkout webhook, device events
n8n Workflow automation Exists, minimal use Order→project→dispatch pipeline
GenieACS TR-069 ACS Running, 7,550 devices → Migrate to Oktopus
Oktopus TR-369 ACS At oss.gigafibre.ca Take over from GenieACS
Stripe Payments Planned Checkout + recurring billing
Twilio SMS/Voice Running via targo-hub Order confirmations, tech ETA
Mapbox Maps Dispatch app + coverage map on website?
Traccar GPS tracking Running for techs Continue
Fonoster/Routr SIP/VoIP Running SIP account provisioning
MariaDB (10.100.80.100) Legacy + provisioning wifi/voip tables Migrate to ERPNext or keep
MongoDB (10.5.2.116) GenieACS device DB 7,550 devices Archive after Oktopus migration

Sprint 1: Data Foundation (1 week)

  1. Match fibre entries to RQA addresses (geo + fuzzy)
  2. Expose OLT port availability via Supabase/API
  3. Migrate product catalog to ERPNext Items (if not already done)
  4. Create ERPNext provisioning fields on Service Equipment

Sprint 2: Checkout Flow (1-2 weeks)

  1. Build plan selection UI on website (internet + TV + phone)
  2. Build checkout page (summary, date picker, Stripe)
  3. Build targo-hub /checkout webhook endpoint
  4. Build n8n "New Order" workflow (customer → location → subscriptions → project)

Sprint 3: Dispatch Integration (1 week)

  1. Auto-create Dispatch Job from new order
  2. SMS notifications (confirmation, tech en route, completed)
  3. Field tech app: barcode scanner → Service Equipment creation

Sprint 4: Auto-Provisioning (2 weeks)

  1. targo-hub /devices/{serial}/provision endpoint
  2. Oktopus webhook integration (device connect → provision request)
  3. WiFi/VoIP credential auto-push on device bootstrap
  4. "Device online" SSE events to Ops UI

Sprint 5: Customer Portal (1-2 weeks)

  1. Login via email/SMS OTP (no legacy MD5)
  2. Invoice list + Stripe payment
  3. WiFi SSID/password change (pushes to ACS)
  4. Support ticket creation