Optimisation sûre (vérifiée, 0 régression) : - helpers.js : `cors()` partagé (en-têtes CORS génériques) au lieu de 2 copies locales. - address-conformity.js : réutilise `pool` (address-db) + `cors` (helpers) au lieu de redéfinir un Pool + cors → 1 seul client pg local partagé pour rqa_addresses/fiber. - address-validate.js : utilise helpers.cors. docs/architecture/VISION.md (NOUVEAU) — vision + plan de modularisation + roadmap d'optimisation, fondé sur un audit chiffré (hub 58 modules/23k lignes, Ops 45k lignes, god-files identifiés). Découpe en 9 domaines (bounded contexts), principe « source de vérité + validation à la saisie + lien stable » (modèle Adresses généralisé à Client/Device/Service), optimisations P0/P1/P2, métriques de succès. Complète les docs architecture existants + ENGINEERING_PRACTICES. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
8.4 KiB
Vision, modularisation & optimisation — Plateforme TARGO / Gigafibre
Document stratégique. Complète
overview.md,app-design.md,data-model.md,module-interactions.mdet../ENGINEERING_PRACTICES.md. Objectif : passer d'une croissance organique (god-files, modules plats) à une architecture modulaire par domaine avec des sources de vérité fiables — pour livrer vite ET sûr.
0. Vision en une phrase
Un hub d'orchestration léger (Node) au-dessus d'ERPNext (ERP/source de données), organisé en domaines métier autonomes (bounded contexts), chacun avec sa source de vérité canonique, sa validation à la saisie et ses liens stables — pendant qu'on éteint progressivement le legacy.
1. État actuel (audit chiffré, 2026-06-07)
| Composant | Volume | Plus gros fichiers (god-files) |
|---|---|---|
| targo-hub (Node) | 58 modules, ~23 000 lignes, 52 routes (lazy-require) | campaigns 2366 · payments 1376 · network-intel 1221 · contracts 1091 · roster 1040 · tech-mobile 961 · dispatch 852 |
| Ops SPA (Vue3/Quasar) | ~45 000 lignes | ProjectWizard 2891 · DispatchPage 2162 · PlanificationPage 1863 · NetworkPage 1829 · ClientDetailPage 1715 |
Forces : hub mono-process simple (routage path.startsWith + require paresseux), ERPNext comme socle
données, frappe_pg (PostgreSQL), intégrations riches (legacy MariaDB, Ministra, GenieACS, OLT SNMP, Stripe,
Mailjet, Authentik, Karrio), base d'adresses RQA locale (5,24 M) déjà branchée.
Dettes techniques (priorisées plus bas) :
- God-files : 5 fichiers front >1700 lignes, 2 back >1300 — mélangent UI/état/règles métier/I/O.
- Modules plats sans frontière de domaine : 58 fichiers
lib/*.jsau même niveau ; couplage implicite. - Helpers réimplémentés :
norm()(accents),cors(),haversine(),stripHtml()dupliqués dans ~6 modules (address-*, legacy-dispatch-sync, roster, serviceability, tech-absence-sms). (cors/pool : consolidés ✅) - Pas de tests ni de CI/CD (déploiement =
scpmanuel +docker restart). - Observabilité inégale :
catch {}muets par endroits ; heartbeat/réconciliation présents seulement sur le pont legacy.erp.create/updatene throw pas → des erreurs ont déjà été comptées comme succès.
2. Principe directeur : Domaines + Source de vérité
Deux règles structurent toute la suite :
(A) Découper par DOMAINE (bounded context), pas par fichier. Chaque domaine expose une interface
publique étroite (un index + des services) ; le reste est interne. Le routage du hub délègue au domaine.
(B) Chaque entité a UNE source de vérité + validation à la saisie + lien stable. On ne re-cherche pas
avec un processus complexe à chaque fois : on résout une fois, on persiste le lien canonique, le
downstream lit le lien. Modèle de référence : les adresses (cf. reference/ + page Conformité) —
rqa_addresses (RQA local) ← aq_address_id/linked_address/address_validation_status sur Service Location.
3. Carte des domaines cible
Regroupement des 58 modules hub + pages Ops en 9 domaines. (Refactor par déplacement progressif, pas big-bang.)
| Domaine | Hub (lib/…) | Ops (pages/modules) | Source de vérité |
|---|---|---|---|
| Identité & Accès | auth, (Authentik) | usePermissions, MainLayout | Authentik + Capabilities |
| CRM / Clients | store, address-db/validate/conformity, address-search | Clients, ClientDetail | Customer (ERPNext) · Adresse = RQA |
| Dispatch & Terrain | dispatch, roster, tech-mobile, legacy-dispatch-sync, (geo/routing Mapbox) | Dispatch, Planification, RendezVous, module tech | Dispatch Job · Shift/Roster |
| Réseau & Infra | network-intel, olt-snmp, devices, outage-monitor, oktopus, (genieacs) | Network | GenieACS (CPE) · OLT · device |
| Facturation & Paiements | payments, contracts, acceptance, store/checkout | Rapports, ContratBLB | Legacy billing (autoritaire jusqu'au cutover) → ERPNext |
| Marketing & Campagnes | campaigns, offers, ai (traduction) | module campaigns | Campaign · Gift (Giftbit) |
| IA & Agent | ai, agent, voice-agent, flow-runtime, conversation | Copilote, AgentFlows | Agent flows |
| Intégrations & Legacy | erp, legacy DB, Ministra, Karrio, Giftbit | — | Adaptateurs (anti-corruption layer) |
| Plateforme | helpers, config, observabilité | composables partagés, components/shared | — |
Cible d'arborescence hub (itératif) : lib/<domaine>/<module>.js + lib/<domaine>/index.js (interface
publique) ; lib/util/ (norm, cors, geo, html) ; server.js route vers require('./lib/<domaine>').
Cible Ops : src/modules/<domaine>/ (pages + composants + composables + api du domaine), comme
modules/campaigns et modules/tech le font déjà — étendre ce pattern à dispatch, roster, clients, network.
4. Optimisations priorisées
P0 — Hygiène (sûr, rapide, vérifiable au build)
- Extraire les helpers partagés dans
lib/util/:norm(accents),cors✅,haversineKm,stripHtml,tzDate. Remplacer les ~6 réimplémentations. (cors + pool address déjà consolidés.) - Uniformiser le contrat handler :
erp.create/updaterenvoient{ok}→ tout appelant DOIT vérifierr.ok(déjà corrigé dans le pont ; auditer payments/contracts/store). - Supprimer le code mort +
catch {}muets →log(). - Boundary I/O : un seul client
pgpartagé pour les lectures locales (address-db.pool, réutilisé ✅).
P1 — Décomposition des god-files (par domaine, sans changer le comportement)
- Front :
ProjectWizard(2891),DispatchPage(2162),PlanificationPage(1863),ClientDetailPage(1715) → extraire des composables (use*) + sous-composants (détail/sections). PlanificationPage : sortir packedDay/route-planner, le panneau d'assignation, l'éditeur de journée en composables dédiés. - Back :
campaigns(2366) etpayments(1376) → sous-modules de domaine (envoi, matching, suivi / facturation, rapprochement).
P2 — Fiabilité & vélocité
- Tests (vitest) sur les modules à risque : paiements, pont legacy, conformité adresses, roster solver.
- CI/CD : remplacer
scp + docker restartmanuel par un pipeline (Gitea Actions) build+déploiement+santé. - Observabilité closed-loop : généraliser le pattern
_lastRun//status+ réconciliation (déjà sur le pont) aux jobs critiques ; clés Uptime-Kuma.
5. Source de vérité — généralisation du pattern « Adresses »
| Entité | Source de vérité | Lien stable | État |
|---|---|---|---|
| Adresse | rqa_addresses (RQA local) + fiber_availability |
aq_address_id + linked_address |
✅ FAIT (16 561 liées ; page Conformité) |
| Client | ERPNext Customer | legacy_account_id |
partiel (matching legacy) |
| Appareil/CPE | GenieACS (serial/MAC réels) | MAC ↔ Service Equipment | piège connu (TPLG vs serial réel) |
| Service TV | Ministra (SID = id ligne service legacy) |
legacy_activation_url |
read-only (pas de 2e chemin d'écriture) |
| Facturation | Legacy (autoritaire) jusqu'au cutover | — | scheduler ERPNext en pause |
Prochaine application directe : finir le matching Client (legacy_account_id) et Device (MAC↔GenieACS) sur le même modèle (résoudre une fois → persister → lire le lien).
6. Roadmap par phases
- Phase 1 — Hygiène & fondations : helpers partagés, code mort,
r.okpartout, CI/CD minimal, tests des modules critiques. (Risque faible, gros gain de fiabilité.) - Phase 2 — Modularisation : déplacer hub
lib/*→lib/<domaine>/; décomposer les god-files front/back. - Phase 3 — Sources de vérité : généraliser (Client, Device, Service) + observabilité closed-loop partout.
- Phase 4 — Vision produit : cutover facturation legacy→ERPNext ; app terrain Capacitor (GPS live des unités, remplace le relevé manuel sur la carte) ; portail client self-service (abonnement + RDV + paiement).
7. Métriques de succès
- 0 fichier > 800 lignes (front et back).
- 0 helper dupliqué (
norm/cors/geo/htmlcentralisés). - 100 % des entités clés avec source de vérité + validation à la saisie + lien persisté.
- Déploiement par pipeline (0
scpmanuel) ; tests verts sur les modules critiques. - Tout job inter-systèmes : idempotent + observable + réconcilié (cf. ENGINEERING_PRACTICES).