gigafibre-fsm/docs/ECOSYSTEM-OVERVIEW.md
louispaulb 922572653a docs: comprehensive ecosystem overview for dev/sysadmin onboarding
Complete synthesis covering infrastructure, ERPNext data model, ops app
architecture (40 composables, 12 pages, dispatch features), targo-hub
modules, migration pipeline, integrations, and deployment procedures.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-08 22:49:21 -04:00

494 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Gigafibre FSM — Ecosystem Overview
> Synthèse complète pour développeurs et sysadmins — Avril 2026
---
## 1. Vue d'ensemble
Gigafibre FSM est une plateforme de gestion d'opérations pour un fournisseur internet fibre (FTTH) desservant **6 600+ clients** au Québec. Elle remplace un système legacy PHP/MariaDB vieux de 15 ans par un écosystème moderne composé de :
- **4 applications web** (ops, field, client, website)
- **1 backend Node.js** (targo-hub) servant d'orchestrateur central
- **ERPNext v16** comme ERP et source de vérité des données
- **95+ scripts de migration** pour le transfert depuis le système legacy
- **Infrastructure Docker** avec Traefik, Authentik SSO, et monitoring
**Monorepo** : `git.targo.ca/louis/gigafibre-fsm`
```
gigafibre-fsm/
├── apps/
│ ├── ops/ → Quasar/Vue 3 PWA — outil interne (erp.gigafibre.ca/ops/)
│ ├── field/ → Quasar/Vue 3 PWA — app mobile techniciens
│ ├── client/ → Quasar/Vue 3 PWA — portail client (client.gigafibre.ca)
│ └── website/ → React/Vite — site vitrine (www.gigafibre.ca)
├── services/
│ └── targo-hub/ → Node.js 20 — backend API (msg.gigafibre.ca)
├── erpnext/ → Scripts de setup des doctypes custom
├── scripts/migration/ → Importation legacy → ERPNext
└── docs/ → Documentation architecture
```
---
## 2. Infrastructure serveur
### Serveur principal : 96.125.196.67 (hubdocker)
Tout roule sur un seul serveur Proxmox avec Docker. Le reverse proxy Traefik gère le TLS (Let's Encrypt) et le routage.
| Service | URL | Container | Auth |
|---------|-----|-----------|------|
| ERPNext v16 | erp.gigafibre.ca | erpnext-frontend-1 | Aucun (API token) |
| Ops App | erp.gigafibre.ca/ops/ | ops-frontend (nginx) | Authentik SSO |
| Portail client | client.gigafibre.ca | erpnext-frontend-1 | Authentik client |
| targo-hub | msg.gigafibre.ca | targo-hub | Authentik SSO |
| n8n | n8n.gigafibre.ca | erpnext-n8n-1 | Authentik (GUI) / aucun (webhooks) |
| Dispatch legacy | dispatch.gigafibre.ca | apps-dispatch-frontend-1 | Authentik SSO |
| Oktopus ACS | oss.gigafibre.ca | oktopus-frontend-1 | Authentik SSO |
| Site web | www.gigafibre.ca | apps-www-gigafibre-1 | Aucun |
| GPS tracking | tracker.targointernet.com | traccar | Basic auth |
### Réseaux Docker
| Réseau | Services connectés |
|--------|-------------------|
| `proxy` | Traefik, targo-hub, ops, dispatch, erpnext, n8n, authentik, oktopus, website, traccar |
| `erpnext_erpnext` | ERPNext (backend, DB, redis, workers), targo-hub, n8n |
| `fonoster_default` | Fonoster/Routr SIP (asterisk, postgres, nats, routr) |
| `authentik-client_authentik-client` | Authentik client (server, worker, postgresql, redis) |
### Bases de données
| DB | Host | Usage |
|----|------|-------|
| PostgreSQL (ERPNext) | erpnext-db-1:5432 | Toutes les données métier |
| PostgreSQL (targo_cache) | erpnext-db-1:5432 | Cache devices + hosts (targo-hub) |
| PostgreSQL (Fonoster) | fn-postgres:5432 | SIP routing (trunks, agents) |
| MongoDB (Oktopus) | oktopus-mongo-1:27017 | TR-069 ACS device management |
### SSO (Authentik)
- **Staff** : auth.targo.ca — protège ops, dispatch, n8n, hub
- **Client** : id.gigafibre.ca — protège le portail client
- Authentification via Traefik forwardAuth middleware
---
## 3. ERPNext — Modèle de données
ERPNext est le coeur du système. Tous les CRUD passent par son API REST.
### Doctypes custom (module FSM)
| Doctype | Rôle | Champs clés |
|---------|------|-------------|
| **Dispatch Job** | Tâche planifiée | tech, date, heure, durée, status, tags, published, is_recurring, recurrence_rule |
| **Dispatch Technician** | Ressource humaine/matérielle | fullName, phone, resource_type, weekly_schedule, extra_shifts, tags |
| **Dispatch Tag** | Compétence/catégorie | tag_name, color, category |
| **Dispatch Tag Link** | Lien tag↔job/tech | tag, level (1-5), required |
| **Dispatch Preset** | Preset de groupe partagé | preset_name, preset_type, preset_data (JSON) |
| **Dispatch Offer** | Offre de travail (pool Uber) | job, mode, pricing, status, responses |
| **Service Location** | Adresse de service | address, city, GPS, OLT port, network_id |
| **Service Equipment** | Équipement client | serial, MAC, IP, firmware, OLT info |
### Doctypes ERPNext standard enrichis
| Doctype | Champs custom ajoutés |
|---------|----------------------|
| Customer | legacy_customer_id, stripe_id, is_commercial, is_bad_payer, ppa_enabled |
| Subscription | custom_description, actual_price, service_location |
| Issue | linked dispatch jobs, legacy ticket ID |
| Sales Invoice | QR code, portal payment link |
---
## 4. Ops App — Application principale
### Stack technique
- **Framework** : Vue 3 (Composition API, `<script setup>`)
- **UI** : Quasar v2.19 (q-table, q-dialog, q-select, q-notify...)
- **State** : Pinia (2 stores : auth + dispatch)
- **Build** : Vite + Quasar CLI, output PWA
- **Cartes** : Mapbox GL JS
- **Style** : SCSS, thème adaptatif (dark pour dispatch, light pour le reste)
- **Déploiement** : `npx quasar build``scp dist/spa/* root@96.125.196.67:/opt/ops-app/`
### Pages (12)
| Page | Fonction |
|------|----------|
| DashboardPage | KPIs, contrôle scheduler, déclenchement facturation |
| ClientsPage | Liste clients avec recherche |
| ClientDetailPage | Vue 360° client : contacts, abonnements, équipements, tickets, factures |
| TicketsPage | Liste tickets avec filtres, détail en slide-over |
| **DispatchPage** | **Timeline dispatch complète (voir section 5)** |
| EquipePage | Gestion d'équipe |
| NetworkPage | Infrastructure réseau |
| TelephonyPage | Téléphonie/PBX |
| RapportsPage | Rapports et analytics |
| SettingsPage | Paramètres admin |
| OcrPage | OCR de factures (Gemini vision) |
| AgentFlowsPage | Workflows d'agent IA |
### Architecture composables (40 fichiers)
Chaque domaine métier est encapsulé dans un composable réutilisable :
```
composables/
├── useScheduler.js — Calcul des segments timeline (shifts, absences, jobs)
├── useMap.js — Intégration Mapbox, routes, géocodage
├── useDragDrop.js — Drag-and-drop sur le timeline
├── useBottomPanel.js — Panel jobs non-assignés
├── useResourceFilter.js — Filtrage ressources (tags, groupes, recherche)
├── useTagManagement.js — CRUD tags/compétences
├── usePeriodNavigation.js — Navigation jour/semaine/mois
├── useAutoDispatch.js — Dispatch automatique par compétences
├── useBestTech.js — Matching technicien optimal
├── useJobOffers.js — Pool d'offres Uber-style
├── useAbsenceResize.js — Resize absences par drag
├── useSelection.js — Multi-sélection (lasso)
├── useUndo.js — Undo/redo (Ctrl+Z)
├── useContextMenus.js — Menus contextuels
├── useHelpers.js — Utilitaires (RRULE, dates, couleurs)
├── useInlineEdit.js — Édition inline Odoo-style
├── useClientData.js — Chargement données client
├── useConversations.js — Chat/messages
├── useDeviceStatus.js — Statut devices GenieACS
├── useGpsTracking.js — Tracking GPS temps réel (Traccar)
├── useSSE.js — Server-sent events
├── usePhone.js — Intégration téléphonie
├── useAddressSearch.js — Autocomplétion adresse (Mapbox)
└── ...
```
### API modules (9 fichiers)
| Module | Cible | Fonction |
|--------|-------|----------|
| erp.js | ERPNext via nginx proxy | CRUD générique (listDocs, getDoc, updateDoc, searchDocs) |
| dispatch.js | ERPNext | Jobs, technicians, tags, publish |
| offers.js | ERPNext | Offres de travail (pool Uber) |
| presets.js | ERPNext | Presets de groupes partagés |
| sms.js | n8n webhook | Envoi SMS via Twilio |
| traccar.js | Traccar proxy | GPS tracking |
| ocr.js | Ollama proxy | OCR vision par IA |
| auth.js | ERPNext | Auth token, session |
| service-request.js | ERPNext | Requêtes de service |
### Composants partagés
| Composant | Fonction |
|-----------|----------|
| DetailModal.vue | Modal slide-over multi-doctype (facture, ticket, équipement, abonnement) |
| TagEditor.vue | Éditeur de tags universel avec couleurs, niveaux, autocomplete |
| RecurrenceSelector.vue | Sélecteur récurrence Google Calendar (RRULE) |
| InlineField.vue | Champ éditable inline (double-clic, Odoo-style) |
| UnifiedCreateModal.vue | Modal création unifiée (ticket, tâche, bon de travail) |
| ProjectWizard.vue | Assistant création projet/offre |
| ConversationPanel.vue | Panel de conversation (chat, SMS) |
---
## 5. Dispatch — Fonctionnalités détaillées
Le dispatch est le module le plus riche de l'application. C'est un planificateur de ressources complet avec timeline, cartes, et intelligence artificielle.
### 5.1 Vues
| Vue | Description |
|-----|-------------|
| **Jour** | Timeline horizontale par technicien, segments de jobs drag-and-drop |
| **Semaine** | Grille 7 jours × techniciens, résumé capacité/charge |
| **Mois** | Calendrier mensuel avec disponibilité par technicien sélectionné |
### 5.2 Timeline (vue jour)
- Chaque technicien = une rangée horizontale (6h → 22h)
- **Segments de jobs** : blocs colorés par type de service, drag-and-drop pour réassigner/redimensionner
- **Absences** : blocs rouges (vacances, maladie) — redimensionnables par drag des bords
- **Capacité** : barre de charge sous chaque rangée (vert < 80%, jaune < 100%, rouge > 100%)
- **Multi-sélection** : lasso ou Ctrl+clic pour sélectionner plusieurs jobs
- **Menu contextuel** : clic droit → déplacer, copier, désaffecter, offrir aux ressources
- **Undo/redo** : Ctrl+Z / Ctrl+Shift+Z
### 5.3 Mode planification
Activé par un toggle dans la toolbar. Ajoute une couche visuelle :
- **Shifts réguliers** : blocs de fond bleus translucides montrant les plages horaires de chaque technicien
- **Shifts de garde** : blocs ambrés avec hachures diagonales
- **Vue semaine** : bandes vertes (disponible) et jaunes (garde) sous les headers de jours
- **Vue mois** : blocs colorés par type (vert=disponible, jaune=garde, rouge=absence)
- **Clic sur un shift** → ouvre le modal d'édition d'horaire du technicien
### 5.4 Éditeur d'horaire technicien
Modal permettant de configurer pour chaque technicien :
- **Horaire hebdomadaire** : lundi → dimanche, heure début/fin, jour on/off
- **Presets rapides** : Temps plein (8-16), Soirs (16-00), Nuits (00-08)
- **Shifts de garde/urgence** : shifts additionnels avec :
- Label personnalisé
- Heures de début/fin
- **Récurrence RRULE** via le composant RecurrenceSelector (Google Calendar-style)
- Date de début
- Les shifts sont stockés en JSON dans le champ `extra_shifts` du Dispatch Technician
### 5.5 RecurrenceSelector (Google Calendar-style)
Composant réutilisable offrant des options contextuelles basées sur la date de référence :
- "Ne se répète pas"
- "Tous les jours"
- "Toutes les semaines le [jour]"
- "Tous les mois le [Nème jour]"
- "Tous les ans le [date]"
- "Tous les jours de semaine (lunven)"
- **"Personnalisé..."** → éditeur complet :
- Fréquence : jour(s) / semaine(s) / mois / an(s)
- Intervalle (chaque N)
- Sélecteur de jours (pour hebdomadaire)
- Jour du mois (pour mensuel)
- Preview en temps réel du résultat
### 5.6 Système de tags/compétences
Chaque tag a un **niveau de compétence (1-5)** :
- Sur les techniciens : niveau de maîtrise (1=base, 5=expert)
- Sur les jobs : niveau minimum requis + flag obligatoire/optionnel
- **Auto-dispatch** : cherche le technicien avec compétence >= requise, choisit le plus bas adéquat (préserver les experts pour les jobs complexes)
- Tags existants : Fibre, Téléphonie, Fusionneur, Monteur, Installation, TV, Caméra IP, Urgence, Rive-Sud, Montréal...
### 5.7 Pool d'offres (Uber-style)
Système d'offres de travail inspiré d'Uber pour les ressources internes et externes :
- **3 modes** : Broadcast (tous), Targeted (techniciens spécifiques), Pool (compétences requises)
- **Tarification** : déplacement (150$) + taux horaire (125$/h) configurable
- **Flow** : créer offre → notifier par SMS → technicien accepte/décline → assignation automatique
- **Détection de surcharge** : alerte pulsante quand un technicien dépasse sa capacité
- **Panel latéral** : vue des offres actives avec statut de chaque réponse
### 5.8 Presets de groupes de ressources
- Sauvegarde de combinaisons de filtres de ressources (ex: "Équipe Montréal", "Techniciens fibre")
- **Stockés dans ERPNext** (Dispatch Preset doctype) → partagés entre superviseurs
- Barre rapide de presets sous la recherche
- Deux types : preset de groupe (filtre par groupe) et preset d'IDs (sélection spécifique)
### 5.9 Draft/Publish (brouillon/publié)
- Nouveau champ `published` sur Dispatch Job
- Jobs créés en mode brouillon (hachures diagonales)
- **Modal "Publier & Envoyer"** : sélection période + techniciens → publication en masse + envoi SMS résumé horaire
- Légende visuelle : solide = publié, hachuré = brouillon
### 5.10 Carte Mapbox
- Affichage des jobs géolocalisés avec couleurs par statut
- Routes optimisées par technicien (Mapbox Directions API)
- Géofixation : clic sur la carte pour positionner un job
- Tracking GPS temps réel via Traccar
### 5.11 Récurrence de jobs
- Toggle "Récurrence" sur chaque job
- Sélecteur RecurrenceSelector pour définir le pattern
- Date de fin de récurrence
- Pauses saisonnières (ex: hiver)
- Ghost blocks pour les occurrences futures (matérialisables individuellement)
---
## 6. targo-hub — Backend Node.js
Serveur Express central servant de passerelle entre les frontends et les services externes.
### Modules (30)
| Module | Connexion | Fonction |
|--------|-----------|----------|
| helpers.js | ERPNext REST | Wrapper erpFetch, httpRequest |
| sse.js | Navigateurs (EventSource) | Broadcast temps réel |
| devices.js | GenieACS NBI + PostgreSQL | Statut devices, cache, poller (5min) |
| device-extractors.js | — | Parsing TR-069 → objet résumé |
| device-hosts.js | GenieACS NBI | Topologie mesh WiFi |
| olt-snmp.js | OLT via SNMP v2c | Polling ONU, transitions d'état |
| twilio.js | Twilio API | SMS entrant/sortant, tokens voice |
| agent.js | Gemini API | Assistant IA SMS (tool-calling) |
| conversation.js | Disque local (JSON) | Persistence conversations |
| auth.js | Authentik API | Permissions RBAC (cache 60s) |
| pbx.js | 3CX API | Poller call logs (30s) |
| provision.js | ERPNext + n8n | Pré-autorisation OLT, scan/swap |
| telephony.js | Fonoster/Routr PostgreSQL | CRUD SIP (trunks, agents) |
| email.js | Nodemailer | Envoi emails |
| ical.js | — | Génération iCalendar |
| checkout.js | Stripe | Commandes, abonnements |
| magic-link.js | ERPNext | Authentification sans mot de passe |
| otp.js | Twilio SMS | Code OTP par SMS |
### SSE Topics
| Topic | Audience | Événements |
|-------|----------|------------|
| `customer:{name}` | Agents ops | Updates client temps réel |
| `conv:{token}` | Agents ops | Messages conversation |
| `conv-client:{token}` | Client web | Messages client |
| `conversations` | Agents ops | Feed global conversations |
| `sms-incoming` | Agents ops | Alerte nouveau SMS |
---
## 7. Applications secondaires
### Field App (apps/field/)
App mobile PWA pour les techniciens terrain :
- Liste des tâches du jour
- Scanner code-barres/QR (équipements)
- Diagnostic réseau et devices
- Mode offline avec sync différée
### Portail Client (apps/client/)
Self-service client :
- Consultation factures et paiements
- Gestion abonnements
- Tickets de support
- Catalogue produits/services
- Authentification via Authentik client (id.gigafibre.ca)
### Site Web (apps/website/)
Site vitrine React/Vite/Tailwind :
- Pages produits (Internet, TV, Téléphonie)
- Vérification d'éligibilité par adresse
- Commande en ligne
- FAQ et support
---
## 8. Migration depuis le legacy
### Données migrées
| Type | Volume | Script |
|------|--------|--------|
| Clients | 6 600+ | import_customers.py |
| Abonnements | ~8 000 | import_services_and_enrich.py |
| Factures | 115 000+ | import_invoices.py |
| Paiements | ~90 000 | import_payments.py |
| Tickets | 144 155 | migrate_tickets.py |
| Messages tickets | 448 379 | import_ticket_msgs.py |
| Équipements | 4 930+ | migrate_provisioning_data.py |
| Adresses | ~7 000 | migrate_locations.py |
### Pipeline de migration
```
Legacy MariaDB → Python scripts → ERPNext REST API → PostgreSQL
Ops App (lecture/écriture)
```
---
## 9. Intégrations externes
| Service | Usage | Protocole |
|---------|-------|-----------|
| **GenieACS** (10.5.2.115) | TR-069 ACS, 7 560 CPEs | NBI REST (LAN, no auth) |
| **Twilio** | SMS entrant/sortant, voix | REST API (Basic auth) |
| **Mapbox** | Cartes, géocodage, routes | JS SDK + Directions API |
| **Gemini AI** | OCR factures, assistant SMS | REST (Bearer token) |
| **Stripe** | Paiements en ligne | Checkout Sessions + webhooks |
| **Traccar** | GPS tracking techniciens | REST API (Basic auth) |
| **3CX PBX** | Historique appels | REST API (Basic auth) |
| **Fonoster/Routr** | SIP trunking, voix | PostgreSQL direct |
| **n8n** | Webhooks SMS, automatisations | HTTP webhooks |
| **DocuSeal** | Signatures électroniques | Container Docker |
| **Cloudflare** | DNS gigafibre.ca | REST API |
---
## 10. Déploiement
### Ops App
```bash
cd apps/ops
npx quasar build # Build PWA
scp -r dist/spa/* root@96.125.196.67:/opt/ops-app/ # Deploy (pas de restart nécessaire)
```
### targo-hub
```bash
scp services/targo-hub/server.js services/targo-hub/lib/*.js root@96.125.196.67:/opt/targo-hub/
ssh root@96.125.196.67 'docker restart targo-hub'
```
### ERPNext Custom Fields
```bash
python erpnext/setup_fsm_doctypes.py # Crée/met à jour les custom fields
```
---
## 11. Conventions de code
| Aspect | Convention |
|--------|-----------|
| Framework | Vue 3 Composition API, `<script setup>` exclusivement |
| State | Pinia stores (pas de Vuex) |
| UI | Composants Quasar (q-table, q-dialog, q-notify...) |
| Style | SCSS, variables CSS custom (--sb-*, --ops-*) |
| Thème | Light par défaut, dark pour dispatch uniquement |
| Langue UI | Français (labels, messages) |
| Langue code | Anglais (variables, fonctions, commentaires) |
| API | REST via authFetch (token injecté par nginx) |
| RRULE | RFC 5545 — FREQ/INTERVAL/BYDAY/BYMONTHDAY via buildRRule/parseRRule |
| Nommage | camelCase (JS), kebab-case (composants), UPPER_SNAKE (constantes) |
| Composables | Préfixe `use` (useScheduler, useMap, useResourceFilter...) |
---
## 12. Architecture des flux de données
```
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Browser │────▶│ nginx │────▶│ ERPNext │
│ (Ops SPA) │ │ (proxy+ │ │ REST API │
│ │ │ token) │ │ :8000 │
└──────┬───────┘ └──────────────┘ └──────┬──────┘
│ │
│ SSE + REST PostgreSQL
▼ │
┌──────────────┐ ┌──────────────┐ ┌──────▼──────┐
│ targo-hub │────▶│ GenieACS │ │ ERPNext DB │
│ :3300 │ │ NBI :7557 │ │ :5432 │
│ │────▶│ Twilio API │ └─────────────┘
│ │────▶│ Gemini AI │
│ │────▶│ 3CX PBX │
│ │────▶│ Authentik │
└──────────────┘ └──────────────┘
```
---
## 13. Points d'attention opérationnels
1. **Traefik v2.11** — ne PAS upgrader à v3 (incompatible Docker 29)
2. **HTTP→HTTPS redirect** ne doit pas intercepter le challenge ACME
3. **MongoDB (Oktopus)** requiert AVX — CPU type "host" dans Proxmox
4. **Multi-network Docker** — conteneurs doivent avoir `traefik.docker.network=proxy`
5. **ERPNext PostgreSQL** — bugs GROUP BY/HAVING patchés manuellement
6. **Token API** — ne JAMAIS appeler `generate_keys` (invalide le token existant)
7. **Deploy SPA** — copier le CONTENU de dist/spa/*, pas le dossier
8. **Netplan** — peut overrider systemd-networkd, à supprimer si problème réseau