End-to-end design covering: - Address fuzzy search → fibre availability (16,056 entries, 30 OLTs) - Plan selection + pricing engine (FTTH 25M-1.5G, TV, Phone, combos) - Checkout → Stripe → n8n automation pipeline - ERPNext: Customer → Service Location → Subscriptions → Equipment - Project/task auto-creation for installation workflow - Dispatch job with preferred dates and tag-based tech matching - Field tech barcode scanning → Service Equipment creation - ACS auto-provisioning on device bootstrap (WiFi, VoIP, firmware) - Lead funnel for non-covered addresses (phone-only, business) - Customer portal (invoices, WiFi management, tickets) - Full product catalog mapped from legacy (Internet/TV/Phone/discounts) - 5-sprint build order with dependencies Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
24 KiB
24 KiB
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_availabilitytable 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
- Service selection (internet speed + TV package + phone yes/no)
- Address (pre-filled from availability check)
- Contact info (name, email, phone)
- Installation preference:
- Choose from 3 available dates (next 2 weeks, exclude weekends)
- OR "Contactez-moi" (we call to schedule)
- Payment via Stripe (first month + one-time charges)
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"],
stripe_payment_intent: "pi_xxx"
}
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
1. Link Fibre Table to RQA Addresses
-- 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 |
Build Order (Recommended)
Sprint 1: Data Foundation (1 week)
- Match fibre entries to RQA addresses (geo + fuzzy)
- Expose OLT port availability via Supabase/API
- Migrate product catalog to ERPNext Items (if not already done)
- Create ERPNext provisioning fields on Service Equipment
Sprint 2: Checkout Flow (1-2 weeks)
- Build plan selection UI on website (internet + TV + phone)
- Build checkout page (summary, date picker, Stripe)
- Build targo-hub
/checkoutwebhook endpoint - Build n8n "New Order" workflow (customer → location → subscriptions → project)
Sprint 3: Dispatch Integration (1 week)
- Auto-create Dispatch Job from new order
- SMS notifications (confirmation, tech en route, completed)
- Field tech app: barcode scanner → Service Equipment creation
Sprint 4: Auto-Provisioning (2 weeks)
- targo-hub
/devices/{serial}/provisionendpoint - Oktopus webhook integration (device connect → provision request)
- WiFi/VoIP credential auto-push on device bootstrap
- "Device online" SSE events to Ops UI
Sprint 5: Customer Portal (1-2 weeks)
- Login via email/SMS OTP (no legacy MD5)
- Invoice list + Stripe payment
- WiFi SSID/password change (pushes to ACS)
- Support ticket creation