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>
This commit is contained in:
louispaulb 2026-04-08 22:49:21 -04:00
parent 0c77afdb3b
commit 922572653a

493
docs/ECOSYSTEM-OVERVIEW.md Normal file
View File

@ -0,0 +1,493 @@
# 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