# 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 ### 1. Link Fibre Table to RQA Addresses ```sql -- 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) 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