diff --git a/docs/CUSTOMER-FLOW-ARCHITECTURE.md b/docs/CUSTOMER-FLOW-ARCHITECTURE.md new file mode 100644 index 0000000..fffc12c --- /dev/null +++ b/docs/CUSTOMER-FLOW-ARCHITECTURE.md @@ -0,0 +1,542 @@ +# 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** 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 +```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