docs(evolution): intégration revue critique + réorganisation complète

Revue critique (claude.ai) intégrée :
- Point 3 : versionnage formules indices + date disponibilité effective
- Point 4 : critères sélection amorçage (stresser les mécanismes)
- Point 6 : réversibilité dans le spike technique
- Point 7 : SCOR/ISO en contrepoint, axes validation complémentaires
- Point 8 : interface concrète IRON (3 cas d'usage)
- Point 12 : projection qualitative/chiffrée selon confiance, rétro-analyse calibration
- Point 13 : deux sorties bus (situationnelle/structurelle), coût IA différé
- Contraintes transversales : décisions différées avec signaux déclencheurs

Réorganisation document :
- Vue 1 en en-tête (principe fondamental)
- Ordre de réalisation aligné sur les 4 vues
- Progression architecturale (Vue 1→4) en fin de document
- DAF et DAT mis à jour (8 fonctions, bus d'impact, structurel/situationnel)
- Vue 4 corrigée (veille propose, ne injecte pas ; flèche API restaurée ;
  sortie structurelle du bus)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Stéphan Peccini 2026-04-08 13:08:27 +02:00
parent e6ff714fca
commit 29a85bdcf7
No known key found for this signature in database
9 changed files with 382 additions and 125 deletions

View File

@ -0,0 +1,119 @@
# Instructions de révision — EVOLUTIONS.md (FabNum)
Document issu d'une revue critique du brainstorming FabNum. Les instructions sont organisées par point du document source. Elles portent sur le fond uniquement ; la forme sera traitée séparément.
## Contraintes transversales
Ajouter une mention explicite que deux questions sont des **décisions différées**, conditionnées au modèle de financement du projet :
- La portée de l'open source (moteur, graphe des essentiels, services).
- La dé-concentration du bus factor.
Pour chacune, identifier le ou les **signaux déclencheurs** qui imposeront l'arbitrage : premier prospect sérieux, premier financement, premier contributeur externe, demande client de garantie de continuité, SLA contractuel. L'objectif n'est pas de trancher maintenant mais de garantir que la décision ne sera pas prise par défaut ou dans l'urgence.
## Point 3 — Modèle de données structuré
### Versionnage des indices
Ajouter comme exigence de l'historisation : chaque valeur d'indice stockée porte la référence à la version de formule qui l'a calculée. Le cas de l'ISG (dont un indice constitutif vient de changer de méthode) illustre directement le besoin.
Deux implications à capturer :
- La coexistence de plusieurs versions de formule dans l'historique doit être supportée nativement. On ne recalcule pas rétroactivement avec la nouvelle formule, sinon on perd la trace de ce qu'on voyait à l'époque.
- Le versionnage de formule interagit avec le versionnage des données. Une valeur d'indice historisée est fonction de (formule_v, données_à_date). Pour rejouer proprement, il faut pouvoir reconstituer les deux.
### Horodatage « date de disponibilité effective »
Étendre l'historisation pour que chaque donnée porte non seulement la valeur et sa date de validité métier, mais aussi la date à laquelle elle est devenue connue (date de disponibilité effective). Sans cela, la rétro-analyse souffre d'un look-ahead bias : on rejouerait une crise passée avec des données que personne ne connaissait à l'époque.
Cette exigence s'applique à toutes les données qui entrent dans les indices, pas seulement aux stocks.
## Point 4 — Amorçage
Reformuler le choix du périmètre autour du principe : le périmètre est choisi **pour** stresser les mécanismes qualité, pas malgré eux. Si les minerais retenus passent tous les filtres sans déclencher d'arbitrage, les filtres n'ont pas été testés.
Critères de sélection à acter :
- Au moins un minerai aux sources opaques ou divergentes (candidats : germanium, gallium, terres rares côté chinois).
- Au moins un minerai avec débat méthodologique extraction/raffinage (candidats : lithium, cobalt — terrain déjà travaillé sur gallium et hafnium).
- Un minerai bien documenté comme témoin (candidats : cuivre, fer).
- Pour le composant : pas le plus simple, mais un dont la chaîne a des zones d'ombre.
## Point 6 — Stockage
Ajouter au spike technique un critère d'évaluation : **réversibilité par rapport aux décisions différées** (open source, modèle commercial). L'objectif n'est pas de trancher à la place du modèle de financement, mais d'éviter de fermer prématurément des portes qu'on ne voulait pas fermer.
Exemple de tension à capturer : Neo4j Community est indolore à faire évoluer vers Enterprise, mais un passage à PostgreSQL+AGE ou ArangoDB ne l'est pas. Inversement, PostgreSQL+AGE laisse plus d'options ouvertes côté licence au prix d'une maturité graphe moindre.
## Point 7 — Validation du modèle de niveaux
Séparer clairement les deux méthodes de validation, qui portent sur deux axes différents et sont **complémentaires, pas alternatives** :
- **Axe vertical (quels niveaux, quels intitulés génériques)** — validé par revue de littérature. Références pertinentes pour la décomposition matière : USGS mineral commodity summaries et flux de matières, études JRC sur les matières premières critiques, travaux de l'IEA sur les chaînes de valeur énergie-matière, analyses de cycle de vie matière (ACV).
- **Axe horizontal (jusqu'où remonter dans la profondeur des dépendances)** — validé par démonstration via les marges d'erreur cumulées. Pas de bibliographie nécessaire sur cet axe, c'est un argument analytique.
Préciser que SCOR et ISO 28000 peuvent être mentionnés mais en contrepoint uniquement : ils traitent de la gestion process de la supply chain, pas de la décomposition matière. Les utiliser comme benchmark principal ferait porter la validation sur le mauvais objet.
## Point 8 — Services, sécurisation et profils de visibilité
Ajouter un paragraphe (pas un point à part entière) sur l'interface concrète avec IRON. Le couplage est actuellement mentionné en une ligne dans les contraintes transversales mais on ne sait pas comment il se matérialise. FabNum ne se substitue pas à IRON, il le complète : FabNum fournit le diagnostic de fragilité technique de la chaîne, IRON évalue la capacité organisationnelle à encaisser et contourner (distinction Hamant résilience/robustesse).
Décrire deux ou trois usages concrets d'appel croisé. Pistes à explorer :
- IRON consomme des analyses FabNum via l'API comme intrants de l'évaluation Y-axis ou Z-axis.
- FabNum produit en sortie une liste de dépendances critiques qu'IRON utilise dans son diagnostic.
- Un score IRON peut en retour contextualiser une analyse FabNum : pour cette organisation donnée, telle dépendance est critique parce que leur robustesse sur ce point est faible.
Sans cette explicitation, le couplage reste déclaratif et risque de ne jamais être implémenté.
## Point 12 — Stocks et projection temporelle
### Résultat qualitatif par défaut
Reformuler pour dire explicitement que la projection temporelle produit un résultat **qualitatif** (court / moyen / long terme, ou équivalent à calibrer) et non une valeur en mois. Remplacer l'exemple actuel (« ~8 mois avant impact ») par une formulation du type « impact court terme (semaines), moyen terme (quelques mois), long terme (au-delà) » avec l'indice de confiance associé.
Cohérent avec le principe directeur du point 3 : « on travaille avec des estimations, pas des mesures exactes ».
### Indice de confiance hérité
L'indice de confiance de la projection hérite par propagation de l'indice de fiabilité des données de stock mobilisées. Ce n'est pas un nouvel indice à concevoir.
### Rétro-analyse comme mécanisme de calibration
La rétro-analyse mentionnée dans le MVP (Spruce Pine, quotas chinois) prend un double rôle : preuve de concept des indices **et** mécanisme de calibration du moteur de projection. On rejoue une crise passée dont on connaît le déroulement réel, on observe ce que le moteur aurait prédit avec les données de l'époque, on ajuste les seuils court/moyen/long terme.
À articuler avec la rétro-analyse des indices : pour une crise passée donnée, rejouer avec **les deux** versions de formule quand c'est pertinent — formule de l'époque (qu'aurions-nous vu venir avec les outils d'alors ?) et formule actuelle (le moteur actuel capte-t-il bien le signal ?). Si la nouvelle formule ne capte pas mieux une crise passée que l'ancienne, la révision n'a rien apporté.
## Point 13 — Bus d'impact
### Deux sorties possibles, tri par l'expert
Rendre explicite que le bus d'impact a **deux sorties possibles** et que le tri entre elles fait partie de la décision de l'expert :
- Sortie situationnelle — impact temporaire sur les capacités réelles (inondation, blocage logistique, grève).
- Sortie structurelle — modification de la capacité nominale elle-même (fermeture définitive de mine, ouverture d'un nouvel opérateur, quota devenu politique permanente, reconfiguration durable d'une route).
L'IA du bus propose, l'expert arbitre entre les deux couches. Sans cette précision, un développeur (ou Claude Code au moment de l'implémentation) risque de coder le bus comme un pipeline mono-sortie vers le situationnel, et une fermeture de mine atterrirait comme un impact « -100% permanent » au lieu d'une modification du graphe structurel.
### Coût opérationnel de l'IA
Mentionner que le coût opérationnel de l'IA est un élément à chiffrer **au moment où la Vue 4 devient l'étape courante**, pas avant et pas après. Cela évite deux écueils symétriques : chiffrer trop tôt (purement spéculatif) ou découvrir tardivement que le modèle économique du bus ne boucle pas.
Ajouter que l'expérience du générateur de rapport actuel (modèles gratuits) fournit une base empirique pour extrapoler l'ordre de grandeur le moment venu. Cela ancre l'estimation future dans du concret plutôt que dans un calcul théorique.
## Vue 4 — Schéma à corriger
Trois corrections sur la figure :
1. **Flèche Écosystème veille 360° → Bus d'impact** : actuellement étiquetée « injecte des événements », ce qui contredit le texte du point 13. La veille propose, elle n'injecte pas. Redessiner comme une flèche « propose des événements » vers l'Expert (ou vers une file d'attente validée par l'expert), symétrique à la flèche « propose des sources » qui existe déjà.
2. **Flèche Écosystème veille 360° → API** : perdue par rapport à la Vue 3. Ce canal ne disparaît pas en Vue 4, il s'ajoute au canal de proposition. L'écosystème 360° a deux usages en régime complet : consommateur d'analyses via API, pourvoyeur d'événements et de sources via validation expert. Les deux doivent apparaître.
3. **Flèche Expert → Graphe structurel** (via Moteur) : absente. La flèche « valide les impacts » Expert → Bus d'impact est présente et correcte, mais il manque le chemin par lequel les modifications structurelles validées hors cycle trimestriel (fermeture de mine, nouvel opérateur) atteignent le graphe structurel. Sans ce chemin, la sortie structurelle du bus n'a pas de destination visible.
## Points hors périmètre de la révision
Deux remarques initiales ont été écartées après discussion et ne sont pas à traiter dans la révision du document :
- **Bus factor et régime de validation du bus d'impact** : le document est précisément écrit pour lever le bus factor. Maintenir le régime « validation expert obligatoire » tel quel.
- **FabNum comme « nième outil de criticité »** : formulation incorrecte. Le paysage public des outils de criticité supply chain appliqués au numérique est très peu couvert ; les rares outils opérationnels pointus sont gouvernementaux ou propriétaires non publiés. FabNum occupe un espace réel.

View File

@ -5,9 +5,11 @@ Document de brainstorming — capture les réflexions et décisions prises lors
**Date** : 2026-04-02
**Statut** : En cours de réflexion (quoi/pourquoi, pas encore le comment)
## Architecture globale
## Principe fondamental
![Architecture globale FabNum](architecture-globale.png){ width=100% }
FabNum v2 est un **moteur d'analyse** des risques géopolitiques sur les chaînes d'approvisionnement, exposé via une **API**. L'interface actuelle Streamlit est abandonnée au profit d'un frontend consommant l'API. L'administration se fait par scripts.
![Vue 1 — Le moteur](architecture-vue1.png){ width=100% }
## Contraintes transversales
@ -19,9 +21,13 @@ Document de brainstorming — capture les réflexions et décisions prises lors
- **Intégration écosystème** — FabNum est un composant d'un écosystème plus large de veille stratégique 360° sur la polycrise. Il sera requêté par d'autres outils pour fournir des analyses et rapports.
- **Couplage** — FabNum se couple avec la méthodologie [IRON](https://conseil.peccini.fr/iron/) et le livre blanc "Voyage vers la robustesse".
- **Personas cibles** — COMEX (vision stratégique, synthèses), Métiers (analyse opérationnelle), DSI (dépendances SI).
- **Open source** — la question de ce qui sera open source (moteur, graphe des essentiels) reste à trancher.
- **Choix technologiques structurants** — base de données, framework API, frontend expert : à définir rapidement en début d'implémentation.
**Décisions différées** — conditionnées au modèle de financement, à ne pas trancher maintenant mais à ne pas laisser arriver par défaut ou dans l'urgence :
- **Portée de l'open source** (moteur, graphe des essentiels, services). Signaux déclencheurs : premier prospect sérieux, premier financement, demande client de garantie de continuité.
- **Dé-concentration du bus factor**. Signaux déclencheurs : premier contributeur externe, SLA contractuel, premier financement permettant de diversifier.
---
## Point 1 — Recentrage de FabNum : moteur + API + séparation des rôles
@ -114,6 +120,11 @@ Un **indice de fiabilité de la donnée** agrège plusieurs facteurs : granulari
**Historisation** — chaque donnée, chaque valeur d'indice, chaque état du graphe est horodaté et conservé. Nécessaire pour la détection de tendances, les alertes de variation, et la rétro-analyse (backtesting des indices sur des crises passées : Spruce Pine, quotas chinois, etc.).
Exigences complémentaires de l'historisation :
- **Versionnage des formules d'indices** — chaque valeur d'indice stockée porte la référence à la version de formule qui l'a calculée (ex : l'ISG a changé de méthode de calcul suite à l'évolution d'un indice constitutif). On ne recalcule pas rétroactivement avec la nouvelle formule : on conserve ce qu'on voyait à l'époque. La coexistence de plusieurs versions de formule dans l'historique est supportée nativement. Une valeur historisée est fonction de (formule_version, données_à_date).
- **Date de disponibilité effective** — chaque donnée porte non seulement sa valeur et sa date de validité métier, mais aussi la date à laquelle elle est devenue connue. Sans cela, la rétro-analyse souffre d'un look-ahead bias : on rejouerait une crise passée avec des données que personne ne connaissait à l'époque. S'applique à toutes les données entrant dans les indices.
Les spécifications servent aussi de **cahier des charges pour la recherche de sources** : si une donnée essentielle n'a pas de source, on sait précisément ce qu'on cherche.
### Pourquoi
@ -157,7 +168,11 @@ Alimenter la base de données structurée (point 3) à partir des fiches actuell
### Décisions prises
- **Qualification progressive** — chaque donnée et chaque source est passée au crible des filtres qualité (tier de confiance, vérification citation, périmètre). Ce qui passe est conservé comme donnée de référence, ce qui ne passe pas est remplacé ou supprimé. Ce n'est pas "test puis jeter", c'est un processus de qualification.
- Le périmètre d'amorçage (tout le corpus ou un sous-ensemble) reste à décider.
- **Périmètre choisi pour stresser les mécanismes qualité** — si les minerais retenus passent tous les filtres sans déclencher d'arbitrage, les filtres n'ont pas été testés. Critères de sélection :
- Au moins un minerai aux sources opaques ou divergentes (candidats : germanium, gallium, terres rares côté chinois)
- Au moins un minerai avec débat méthodologique extraction/transformation (candidats : lithium, cobalt)
- Un minerai bien documenté comme témoin (candidats : cuivre, fer)
- Un composant dont la chaîne a des zones d'ombre (pas le plus simple)
- Les fiches existantes ne sont pas modifiées à cette étape.
- Cet amorçage sert aussi de validation des chantiers précédents.
@ -224,7 +239,7 @@ Cette architecture composable permet de gérer la complexité sans surcharger le
### Décisions prises
- Le DOT n'est plus le stockage primaire.
- Le choix technologique (base graphe type Neo4j Community, PostgreSQL+AGE, ArangoDB, ou autre) reste ouvert. Toutes les options sont open source.
- Le choix technologique (base graphe type Neo4j Community, PostgreSQL+AGE, ArangoDB, ou autre) reste ouvert. Toutes les options sont open source. Critère supplémentaire du spike : **réversibilité par rapport aux décisions différées** (open source, modèle commercial). Neo4j Community évolue facilement vers Enterprise, mais un passage à PostgreSQL+AGE ne l'est pas. Inversement, PostgreSQL+AGE laisse plus d'options ouvertes côté licence au prix d'une maturité graphe moindre.
- **Backup** : stratégie de sauvegarde à définir, mais simplifiée par la cadence d'évolution modérée du graphe.
- **Cadence de mise à jour** : mensuelle au démarrage (pour roder le workflow), puis trimestrielle une fois stabilisé. Alertes veille hors cadence pour les événements critiques.
- L'architecture multi-graphes (essentiel/connexe) est identifiée comme point futur à part entière.
@ -242,10 +257,10 @@ Revoir et valider les niveaux de décomposition de la chaîne de valeur. Deux ax
### Méthode de validation
La validation doit être **argumentée**, par au moins une des approches suivantes :
La validation porte sur **deux axes complémentaires** (pas alternatifs) :
- **Revue de littérature** — benchmark avec les modèles de chaînes d'approvisionnement existants, incluant les standards du domaine (SCOR model, ISO 28000, Open Supply Hub, Responsible Minerals Initiative).
- **Démonstration par les marges d'erreur** — montrer qu'avec les niveaux d'erreur cumulés le long de la chaîne, ajouter des niveaux n'améliorerait pas la précision des résultats.
- **Axe vertical (quels niveaux, quels intitulés génériques)** — validé par **revue de littérature**. Références pertinentes pour la décomposition matière : USGS mineral commodity summaries et flux de matières, études JRC sur les matières premières critiques, travaux IEA sur les chaînes de valeur énergie-matière, analyses de cycle de vie matière (ACV), Open Supply Hub, Responsible Minerals Initiative. Note : SCOR et ISO 28000 traitent de la gestion process de la supply chain, pas de la décomposition matière — à mentionner en contrepoint uniquement, pas comme benchmark principal.
- **Axe horizontal (jusqu'où remonter dans la profondeur des dépendances)** — validé par **démonstration via les marges d'erreur** cumulées. Montrer qu'ajouter des niveaux n'améliorerait pas la précision des résultats. Pas de bibliographie nécessaire, c'est un argument analytique.
### Pourquoi
@ -319,6 +334,12 @@ Définir les services exposés par l'API, leur sécurisation et les niveaux de v
- Rôles (ce qu'on peut faire) et profils (ce qu'on peut voir) sont deux axes distincts.
- Moteur stateless côté données client (objectif), agent local client ou export manuel comme alternatives.
**Interface concrète avec IRON** — FabNum ne se substitue pas à IRON, il le complète. FabNum fournit le diagnostic de fragilité technique de la chaîne, IRON évalue la capacité organisationnelle à encaisser et contourner (distinction Hamant résilience/robustesse). Usages concrets d'appel croisé :
- IRON consomme des analyses FabNum via l'API comme intrants de l'évaluation Y-axis ou Z-axis.
- FabNum produit en sortie une liste de dépendances critiques qu'IRON utilise dans son diagnostic.
- Un score IRON peut en retour contextualiser une analyse FabNum : pour une organisation donnée, telle dépendance est critique parce que leur robustesse sur ce point est faible.
---
## Point 9 — Multi-sectoriel et architecture des graphes
@ -426,13 +447,14 @@ Le niveau 3 ne sera pas atteignable pour tous les opérateurs, mais peut l'être
Intégrer les **niveaux de stock** comme donnée du graphe pour permettre des **scénarios de projection temporelle** : en cas de rupture d'approvisionnement, estimer le délai d'impact le long de la chaîne de valeur.
- **Stock comme attribut de nœud** — chaque nœud pertinent (opération, composant) porte une estimation de stock (en mois de consommation, tonnes, unités).
- **Moteur de projection** — simulation de rupture à un point du graphe et propagation temporelle : "la Chine coupe le germanium → les fibres optiques sont impactées dans X mois, les serveurs dans Y mois".
- **Moteur de projection** — simulation de rupture à un point du graphe et propagation temporelle. Le résultat est **qualitatif ou chiffré selon l'indice de confiance** : si la confiance est suffisante, une fourchette chiffrée ("impact dans 4-8 mois") ; sinon, un résultat qualitatif ("impact court terme / moyen terme / long terme") avec l'indice de confiance associé. L'indice de confiance de la projection hérite par propagation de l'indice de fiabilité des données de stock mobilisées — ce n'est pas un nouvel indice à concevoir.
- **Scénarios what-if** — un service de calcul dynamique, pas juste une requête sur le graphe.
- **Rétro-analyse comme calibration** — rejouer des crises passées (Spruce Pine, quotas chinois) dont on connaît le déroulement réel, observer ce que le moteur aurait prédit avec les données de l'époque (en respectant la date de disponibilité effective), ajuster les seuils court/moyen/long terme. Pour une crise donnée, rejouer avec les deux versions de formule quand c'est pertinent : formule de l'époque (qu'aurions-nous vu venir ?) et formule actuelle (le moteur actuel capte-t-il mieux le signal ?).
### Pourquoi
- Passe FabNum de l'analyse **statique** (photo de la criticité à un instant T) à l'analyse **dynamique** (projection temporelle en cas de rupture).
- Valeur très forte pour les clients : "votre SI dépend du germanium via les fibres optiques, vous avez ~8 mois avant impact en cas de coupure chinoise".
- Valeur très forte pour les clients : "votre SI dépend du germanium via les fibres optiques, impact estimé à moyen terme (4-8 mois) avec un indice de confiance de 0.4".
- Les crises récentes (quotas chinois, Spruce Pine) montrent que le délai d'impact est une information critique pour la prise de décision.
### Difficultés identifiées
@ -482,11 +504,18 @@ Le graphe situationnel reflète ainsi en permanence la **situation mondiale rée
**Fonctionnement :**
- La **veille 360°** se connecte au bus et lui injecte des événements.
- La **veille 360°** se connecte au bus et lui **propose** des événements (elle n'injecte pas directement).
- L'**IA** analyse l'événement, identifie les nœuds concernés et propose des impacts chiffrés (nœud impacté, type d'impact, pourcentage de réduction, durée estimée).
- Un **expert** valide ou corrige avant injection. Pas d'injection automatique non contrôlée.
- Le **moteur** se connecte au bus et consomme le graphe situationnel. Il n'a pas besoin de comprendre les événements — il travaille sur un graphe avec des capacités réelles.
**Deux sorties possibles du bus**, triées par l'expert :
- **Sortie situationnelle** — impact temporaire sur les capacités réelles (inondation, blocage logistique, grève). Alimente le graphe situationnel.
- **Sortie structurelle** — modification de la capacité nominale elle-même (fermeture définitive de mine, ouverture d'un nouvel opérateur, quota devenu politique permanente, reconfiguration durable d'une route). Alimente le graphe structurel hors cycle trimestriel.
L'IA propose la catégorie, l'expert tranche. Sans cette distinction, un développeur coderait le bus comme un pipeline mono-sortie vers le situationnel, et une fermeture de mine serait un impact "-100% permanent" au lieu d'une modification structurelle.
**Rôle de l'IA :**
La traduction événement → impact est un problème de **raisonnement** (comprendre l'événement, identifier les nœuds concernés, estimer la sévérité), pas d'algorithme. Un LLM avec accès au graphe et aux données contextuelles est le bon outil. Le code seul ne peut pas gérer l'infinie variété des événements possibles.
@ -519,7 +548,9 @@ Les indices se calculent sur les deux couches :
- Deux couches de graphe : **structurel** (trimestriel) et **situationnel** (continu, rythme décisionnel).
- Les indices se calculent sur les deux couches (structurel vs situationnel).
- L'IA est un composant clé du bus (traduction et suivi), avec validation humaine obligatoire.
- Le bus a **deux sorties** (situationnelle et structurelle) — l'expert tranche.
- L'IVC situationnel dépend de la demande inter-sectorielle — proportionnel au démarrage, dynamique à terme.
- **Coût opérationnel de l'IA** — à chiffrer au moment où la Vue 4 devient l'étape courante, pas avant. L'expérience du générateur de rapport actuel (modèles gratuits) fournit une base empirique pour extrapoler l'ordre de grandeur.
- Point identifié comme horizon — dépend de la granularité géographique (point 11) et des stocks (point 12).
---
@ -559,43 +590,54 @@ Ce n'est **pas un composant actif** mais une **propriété du moteur** : s'il es
## Ordre de réalisation logique
L'ordre des points dans ce document reflète l'ordre de la discussion, pas l'ordre de réalisation. L'analyse des dépendances donne :
L'ordre des points dans ce document reflète l'ordre de la discussion, pas l'ordre de réalisation. Le séquencement ci-dessous s'aligne sur les 4 vues architecturales présentées en fin de document.
**Phase 1 — Fondations (parallélisable) :**
### Vue 1 — Le moteur (phases 1 à 4)
Phase 1 — Fondations (parallélisable) :
- **Point 7** — Validation du modèle de niveaux (fondation théorique, prérequis au modèle de données)
- **Point 6 (spike)** — Spike technique sur 2-3 bases candidates (Neo4j Community, PostgreSQL+AGE, ArangoDB) avec un mini-graphe de test. En parallèle du point 7 car les critères de sélection (multi-graphes, schéma évolutif, requêtage, historisation, open source) sont indépendants du nombre exact de niveaux. Tests sur le serveur via Docker (16 Go RAM), installation native ensuite.
- **Point 6 (spike)** — Spike technique sur 2-3 bases candidates (Neo4j Community, PostgreSQL+AGE, ArangoDB) avec un mini-graphe de test. En parallèle du point 7.
**Phase 2 — Modèle et stockage :**
Phase 2 — Modèle et stockage :
1. **Point 3** — Modèle de données structuré (dépend des niveaux validés). Énergie et eau ne nécessitent pas de modélisation spéciale — ce sont des attributs d'opération comme les parts de marché, couverts nativement par le modèle extensible.
2. **Point 6 (implémentation)** — Mise en place du stockage retenu après le spike.
- **Point 3** — Modèle de données structuré (dépend des niveaux validés). Conçu dès le départ pour supporter les deux couches (structurel/situationnel) et l'asservissement au bus d'impact (point 14).
- **Point 6 (implémentation)** — Mise en place du stockage retenu après le spike.
**Phase 3 — Données et sources :**
Phase 3 — Données et sources :
1. **Point 2** — Gestion des sources (peut démarrer en parallèle dès la phase 2 pour l'identification/catégorisation)
2. **Point 4** — Amorçage et qualification sur un échantillon représentatif : 3 minerais + 1 composant + 1 produit final (couvre tous les niveaux du graphe). Puis audit d'exhaustivité des minerais après l'amorçage.
- **Point 2** — Gestion des sources (peut démarrer en parallèle dès la phase 2 pour l'identification/catégorisation)
- **Point 4** — Amorçage et qualification sur un échantillon représentatif : 3 minerais + 1 composant + 1 produit final. Puis audit d'exhaustivité des matières premières.
**Phase 4 — Fiches et API :**
Phase 4 — Fiches et API :
1. **Point 5** — Templates et génération des fiches
2. **Point 1** — API REST et rôles
3. **Point 8** — Services, sécurisation, profils (sous-spécification dédiée pour la personnalisation client)
- **Point 5** — Templates et génération des fiches
- **Point 1** — API REST et rôles
- **Point 8** — Services, sécurisation, profils
*Horizon (l'architecture doit les rendre possibles sans les implémenter d'emblée) :*
### Vue 2 — Veille sur les sources et propagation
- **Point 2 (veille)** — Activation de la veille sur les sources (huginn), vérification des citations. Cycle structurel trimestriel.
- **Propagation d'impact** — Le moteur gagne la capacité de simulation manuelle ("que se passe-t-il si ce nœud est coupé ?").
### Vue 3 — Veille stratégique 360°
- **Intégration écosystème 360°** — La veille stratégique se connecte sur deux points : requête l'API et propose des sources (validées par l'expert avant intégration).
### Vue 4 — Architecture complète
- **Point 11** — Granularité géographique fine (prérequis à la précision du bus d'impact)
- **Point 10** — Ressources transversales (énergie, eau)
- **Point 11** — Granularité géographique fine
- **Point 12** — Stocks et projection temporelle
- **Point 13** — Bus d'impact (traducteur d'événements → impacts chiffrés, IA assistée)
- **Point 14** — Combinatoire multi-impacts (contrainte de conception du moteur, pas un développement séparé)
- **Point 9** — Multi-sectoriel
- **Point 13** — Bus d'impact (traducteur d'événements → impacts chiffrés, IA assistée, mémoire situationnelle). Scission de la base en graphe structurel / graphe situationnel.
- **Point 14** — Combinatoire multi-impacts (native si le moteur est asservi au bus dès la conception)
- **Point 9** — Multi-sectoriel (le plus lointain)
## MVP (jalon interne)
**Définition** : moteur fonctionnel avec données réelles dans une vraie base, requêtable, données sourcées avec indice de fiabilité. Pas de frontend, pas de produit fini — un jalon de validation interne.
**Périmètre** : phases 1 + 2 + 3 (validation niveaux → spike techno → modèle de données → base → amorçage 3 minerais + 1 composant + 1 produit final).
**Périmètre** : Vue 1 complète (points 7 → 6 → 3 → 2 → 4 → 5 → 1 → 8 : validation niveaux → spike techno → modèle de données → base → amorçage 3 minerais + 1 composant + 1 produit final → fiches → API).
**Critère de succès** : on peut requêter la base et retrouver les mêmes analyses qu'aujourd'hui (ex : Sankey du germanium), avec des données sourcées et un indice de fiabilité.
@ -605,9 +647,39 @@ L'ordre des points dans ce document reflète l'ordre de la discussion, pas l'ord
\newpage
## Planification temporelle
## Progression architecturale
![Planification temporelle](planification-temporelle.png){ width=100% }
L'architecture de FabNum v2 se construit par étapes. Chaque vue ajoute un bloc fonctionnel sans remettre en cause les précédents.
### Vue 1 — Le moteur
Le socle : un moteur d'analyse requêtable via API, alimenté par des sources externes qualifiées. L'administrateur gère le graphe par scripts, les experts et clients consomment via l'API.
![Vue 1 — Le moteur](architecture-vue1.png){ width=100% }
\newpage
### Vue 2 — Veille sur les sources et propagation d'impact
Les sources ne sont plus statiques — elles sont surveillées en continu (huginn). Le moteur gagne la capacité de **propagation d'impact** : l'expert peut simuler manuellement "que se passe-t-il si ce nœud est coupé ?" et observer la propagation dans le graphe. Les clients peuvent contextualiser leurs requêtes.
![Vue 2 — Veille et propagation](architecture-vue2.png){ width=100% }
\newpage
### Vue 3 — Veille stratégique 360°
Le monde extérieur interagit avec FabNum. L'écosystème de veille 360° se connecte sur deux points : il **requête l'API** pour obtenir des analyses et il **propose des sources** qui sont validées par l'expert avant intégration.
![Vue 3 — Veille 360°](architecture-vue3.png){ width=100% }
\newpage
### Vue 4 — Architecture complète (bus d'impact, mémoire situationnelle, IA)
Le **bus d'impact** traduit les événements du monde réel en impacts chiffrés sur le graphe, assisté par l'IA et validé par l'expert. Il maintient une **mémoire situationnelle** : le graphe reflète en permanence la situation mondiale réelle. La base de données se scinde en **graphe structurel** (capacités nominales, trimestriel) et **graphe situationnel** (capacités réelles avec impacts, continu). Les indices se calculent sur les deux couches.
![Vue 4 — Architecture complète](architecture-vue4.png){ width=100% }
\newpage

Binary file not shown.

View File

@ -80,21 +80,24 @@ digraph architecture_vue4 {
// Relations utilisateurs
expert -> api [label="consulte\nanalyse", color="#2E7D32"];
expert -> bus [label="valide\nles impacts", color="#E65100", style=bold];
expert -> sources [label="valide et\nalimente", color="#2E7D32", style=bold];
client -> api [label="consulte\nles résultats", color="#C62828"];
admin -> moteur [label="administre\n(scripts)", color="#E65100", style=bold, penwidth=2];
// Écosystème 360°
ecosysteme -> bus [label="injecte\ndes événements", color="#6A1B9A", penwidth=2];
ecosysteme -> expert [label="propose\ndes sources", color="#6A1B9A", style=dashed, penwidth=2];
// Écosystème 360° — trois interactions
ecosysteme -> api [label="requête\nanalyses", color="#6A1B9A"];
ecosysteme -> expert [label="propose événements\net sources", color="#6A1B9A", style=dashed, penwidth=2];
// Expert → Bus (événements validés)
expert -> bus [label="valide\nles impacts", color="#E65100", style=bold];
// Bus ↔ IA
bus -> ia_bus [label="événement\nà analyser", color="#E65100", dir=both];
// Bus → Moteur + BDD situationnel
// Bus → Moteur + BDD (deux sorties)
bus -> moteur [label="impacts\nchiffrés", color="#BF360C", penwidth=2];
bus -> bdd_situa [label="met à jour\nles impacts", color="#BF360C", style=dashed];
bus -> bdd_situa [label="MAJ\nsituationnel", color="#BF360C", style=dashed];
bus -> bdd_struct [label="MAJ structurel\n(fermeture mine,\nnouvel opérateur)", color="#BF360C", style=dashed];
// API ↔ Moteur
api -> moteur [label="transmet\nles requêtes", color="#4527A0", dir=both];

Binary file not shown.

Before

Width:  |  Height:  |  Size: 474 KiB

After

Width:  |  Height:  |  Size: 456 KiB

View File

@ -1,14 +1,14 @@
digraph macro_daf {
rankdir=TB;
fontname="Arial";
node [fontname="Arial", fontsize=10, style=filled, shape=record];
node [fontname="Arial", fontsize=10, style=filled, shape=box];
edge [fontname="Arial", fontsize=9];
label="FabNum — Macro-DAF (Diagramme d'Activités Fonctionnel)\n\n";
label="FabNum — Macro-DAF (Dossier d'Architecture Fonctionnel)\n\n";
labelloc=t;
fontsize=16;
compound=true;
// Fonctions métier — flux principal
// F1. Modéliser
subgraph cluster_F1 {
label="F1. MODÉLISER LA CHAÎNE DE VALEUR";
style=filled; color="#E3F2FD"; fontsize=12; fontcolor="#1565C0";
@ -16,12 +16,14 @@ digraph macro_daf {
F1_1 [label="F1.1\nValider les niveaux\nde décomposition", fillcolor="#BBDEFB"];
F1_2 [label="F1.2\nDéfinir les intitulés\ngénériques", fillcolor="#BBDEFB"];
F1_3 [label="F1.3\nDéfinir les critères\nd'arrêt (profondeur)", fillcolor="#BBDEFB"];
F1_4 [label="F1.4\nGérer chaînes\nprincipales / connexes", fillcolor="#BBDEFB"];
F1_4 [label="F1.4\nGérer chaînes\nessentielles / connexes", fillcolor="#BBDEFB"];
F1_5 [label="F1.5\nGérer les matières\ncomposées (NMC...)", fillcolor="#BBDEFB"];
F1_1 -> F1_2 -> F1_3 -> F1_4;
F1_1 -> F1_2 -> F1_3 -> F1_4 -> F1_5;
acteur_F1 [label="Acteur : Admin", shape=ellipse, fillcolor="#E3F2FD", fontsize=9];
}
// F2. Structurer et qualifier
subgraph cluster_F2 {
label="F2. STRUCTURER ET QUALIFIER LES DONNÉES";
style=filled; color="#E8F5E9"; fontsize=12; fontcolor="#2E7D32";
@ -29,56 +31,61 @@ digraph macro_daf {
F2_1 [label="F2.1\nSpécifier données\n(essentielles / info)", fillcolor="#C8E6C9"];
F2_2 [label="F2.2\nDéfinir périmètre\nmesuré", fillcolor="#C8E6C9"];
F2_3 [label="F2.3\nIdentifier et catégoriser\nles sources", fillcolor="#C8E6C9"];
F2_4 [label="F2.4\nAttribuer tiers\nde confiance", fillcolor="#C8E6C9"];
F2_4 [label="F2.4\nAttribuer tiers\nde confiance\n(par domaine)", fillcolor="#C8E6C9"];
F2_5 [label="F2.5\nQualifier données\n(filtres qualité)", fillcolor="#C8E6C9"];
F2_6 [label="F2.6\nArbitrer divergences\nentre sources", fillcolor="#C8E6C9"];
F2_6 [label="F2.6\nArbitrer divergences\n(tier 1 par défaut,\nconvergence → alerte)", fillcolor="#C8E6C9"];
F2_7 [label="F2.7\nCalculer indice\nde fiabilité", fillcolor="#C8E6C9"];
F2_1 -> F2_2 -> F2_3 -> F2_4 -> F2_5 -> F2_6 -> F2_7;
acteur_F2 [label="Acteur : Admin", shape=ellipse, fillcolor="#E8F5E9", fontsize=9];
}
// F3. Surveiller et maintenir
subgraph cluster_F3 {
label="F3. SURVEILLER ET MAINTENIR";
label="F3. SURVEILLER ET MAINTENIR (cycle structurel — trimestriel)";
style=filled; color="#FFF3E0"; fontsize=12; fontcolor="#E65100";
F3_1 [label="F3.1\nVeiller sur\nles sources\n(huginn)", fillcolor="#FFE0B2"];
F3_2 [label="F3.2\nDétecter variations\nanormales (alertes)", fillcolor="#FFE0B2"];
F3_3 [label="F3.3\nContrôler\ncitations", fillcolor="#FFE0B2"];
F3_3 [label="F3.3\nContrôler\ncitations\n(verify-citations)", fillcolor="#FFE0B2"];
F3_4 [label="F3.4\nHistoriser données\net indices", fillcolor="#FFE0B2"];
F3_5 [label="F3.5\nAuditer exhaustivité\ndes minerais", fillcolor="#FFE0B2"];
F3_5 [label="F3.5\nAuditer exhaustivité\ndes matières premières", fillcolor="#FFE0B2"];
F3_1 -> F3_2;
F3_3 -> F3_4;
acteur_F3 [label="Acteurs : Admin (gouv.)\nServices internes (auto.)", shape=ellipse, fillcolor="#FFF3E0", fontsize=9];
}
// F4. Calculer les indices
subgraph cluster_F4 {
label="F4. CALCULER LES INDICES DE CRITICITÉ";
style=filled; color="#FCE4EC"; fontsize=12; fontcolor="#C62828";
F4_1 [label="F4.1\nCalculer IHH, ICS\nIVC, ISG\n(+ futurs)", fillcolor="#F8BBD0"];
F4_1 [label="F4.1\nCalculer IHH, ICS\nIVC, ISG (+ futurs)\nstructurels et situationnels", fillcolor="#F8BBD0"];
F4_2 [label="F4.2\nPré-calculer à\nchaque MAJ graphe", fillcolor="#F8BBD0"];
F4_3 [label="F4.3\nMéta-indices\ndynamiques\n(sur sélection)", fillcolor="#F8BBD0"];
F4_4 [label="F4.4\nRétro-analyser\n(backtesting)", fillcolor="#F8BBD0"];
F4_5 [label="F4.5\nPropager les impacts\net projeter\ntemporellement", fillcolor="#F8BBD0"];
F4_1 -> F4_2;
F4_3 -> F4_4 [style=dashed];
F4_3 -> F4_4;
acteur_F4 [label="Acteur : Services internes", shape=ellipse, fillcolor="#FCE4EC", fontsize=9];
}
// F5. Produire les fiches
subgraph cluster_F5 {
label="F5. PRODUIRE LES FICHES";
style=filled; color="#F3E5F5"; fontsize=12; fontcolor="#6A1B9A";
F5_1 [label="F5.1\nGénérer depuis\ndonnées via templates", fillcolor="#E1BEE7"];
F5_2 [label="F5.2\nAdapter par niveau\n(minerai, composant...)", fillcolor="#E1BEE7"];
F5_2 [label="F5.2\nAdapter par niveau\n(matière première,\ncomposant, composé...)", fillcolor="#E1BEE7"];
F5_3 [label="F5.3\nAdapter par usage\n(expertise, synthèse,\nAPI/JSON)", fillcolor="#E1BEE7"];
F5_1 -> F5_2 -> F5_3;
acteur_F5 [label="Acteur : Services internes", shape=ellipse, fillcolor="#F3E5F5", fontsize=9];
}
// F6. Exposer et servir
subgraph cluster_F6 {
label="F6. EXPOSER ET SERVIR";
style=filled; color="#E0F2F1"; fontsize=12; fontcolor="#00695C";
@ -87,29 +94,44 @@ digraph macro_daf {
F6_2 [label="F6.2\nConsultation\nfiches", fillcolor="#B2DFDB"];
F6_3 [label="F6.3\nAnalyse vulnérabilité\net scénarios", fillcolor="#B2DFDB"];
F6_4 [label="F6.4\nExport\n(PDF, JSON, DOT)", fillcolor="#B2DFDB"];
F6_5 [label="F6.5\nPersonnalisation\nclient (projection SI)", fillcolor="#B2DFDB"];
F6_5 [label="F6.5\nContextualisation\nclient", fillcolor="#B2DFDB"];
F6_6 [label="F6.6\nIntégration\nécosystème 360°", fillcolor="#B2DFDB"];
F6_7 [label="F6.7\nScénarios multi-impacts\n(combinatoire)", fillcolor="#B2DFDB"];
acteur_F6 [label="Acteurs : Expert, Service\nCOMEX, Métiers, DSAI", shape=ellipse, fillcolor="#E0F2F1", fontsize=9];
acteur_F6 [label="Acteurs : Expert, Client\nCOMEX, Métiers, DSI", shape=ellipse, fillcolor="#E0F2F1", fontsize=9];
}
// Transversal
// F7. Capter et traduire les événements
subgraph cluster_F7 {
label="F7. SÉCURISER ET CONTRÔLER (transversal)";
label="F7. CAPTER ET TRADUIRE LES ÉVÉNEMENTS (bus d'impact)";
style=filled; color="#FBE9E7"; fontsize=12; fontcolor="#BF360C";
F7_1 [label="F7.1\nRecevoir événements\n(veille 360°,\nsignaux faibles)", fillcolor="#FFCCBC"];
F7_2 [label="F7.2\nTraduire en impacts\nchiffrés (IA)", fillcolor="#FFCCBC"];
F7_3 [label="F7.3\nValidation expert\navant injection", fillcolor="#FFCCBC"];
F7_4 [label="F7.4\nMaintenir la mémoire\nsituationnelle\n(accumule, archive)", fillcolor="#FFCCBC"];
F7_5 [label="F7.5\nMettre à jour\nle graphe situationnel", fillcolor="#FFCCBC"];
F7_1 -> F7_2 -> F7_3 -> F7_4 -> F7_5;
acteur_F7 [label="Acteurs : Veille 360° (input)\nIA (traduction)\nExpert (validation)", shape=ellipse, fillcolor="#FBE9E7", fontsize=9];
}
// F8. Sécuriser et contrôler (transversal)
subgraph cluster_F8 {
label="F8. SÉCURISER ET CONTRÔLER (transversal)";
style=filled; color="#ECEFF1"; fontsize=12; fontcolor="#37474F";
F7_1 [label="F7.1 Auth\n(user / API key)", fillcolor="#CFD8DC"];
F7_2 [label="F7.2 Rôles\n(admin/expert/service)", fillcolor="#CFD8DC"];
F7_3 [label="F7.3 Profils\nvisibilité", fillcolor="#CFD8DC"];
F7_4 [label="F7.4 Rate\nlimiting", fillcolor="#CFD8DC"];
F7_5 [label="F7.5 Monitoring\nobservabilité", fillcolor="#CFD8DC"];
F8_1 [label="F8.1 Auth\n(user / API key)", fillcolor="#CFD8DC"];
F8_2 [label="F8.2 Rôles\n(admin/expert/service)", fillcolor="#CFD8DC"];
F8_3 [label="F8.3 Profils\nvisibilité", fillcolor="#CFD8DC"];
F8_4 [label="F8.4 Rate limiting\n+ Monitoring", fillcolor="#CFD8DC"];
F7_1 -> F7_2 -> F7_3;
acteur_F7 [label="Acteurs : Admin (config)\nSystème (exécution)", shape=ellipse, fillcolor="#ECEFF1", fontsize=9];
F8_1 -> F8_2 -> F8_3;
acteur_F8 [label="Acteurs : Admin (config)\nSystème (exécution)", shape=ellipse, fillcolor="#ECEFF1", fontsize=9];
}
// Flux principal
F1_4 -> F2_1 [lhead=cluster_F2, ltail=cluster_F1, penwidth=2, color="#333333"];
F1_5 -> F2_1 [lhead=cluster_F2, ltail=cluster_F1, penwidth=2, color="#333333"];
F2_7 -> F3_1 [lhead=cluster_F3, ltail=cluster_F2, penwidth=2, color="#333333"];
F3_4 -> F4_1 [lhead=cluster_F4, ltail=cluster_F3, penwidth=2, color="#333333"];
F4_2 -> F5_1 [lhead=cluster_F5, ltail=cluster_F4, penwidth=2, color="#333333"];
@ -118,7 +140,13 @@ digraph macro_daf {
// F3 en continu
F3_2 -> F3_1 [style=dashed, color="#E65100", label="boucle\ncontinue"];
// F7 transversal
F7_3 -> F5_1 [style=dotted, color="#37474F", lhead=cluster_F5, label="filtre"];
F7_3 -> F6_1 [style=dotted, color="#37474F", lhead=cluster_F6, label="filtre"];
// F7 alimente F4 (impacts → calcul)
F7_5 -> F4_5 [lhead=cluster_F4, ltail=cluster_F7, penwidth=2, color="#BF360C", label="impacts\nchiffrés"];
// F7 boucle situationnelle
F7_4 -> F7_1 [style=dashed, color="#BF360C", label="mise à jour\ncontinue"];
// F8 transversal
F8_3 -> F5_1 [style=dotted, color="#37474F", lhead=cluster_F5, label="filtre"];
F8_3 -> F6_1 [style=dotted, color="#37474F", lhead=cluster_F6, label="filtre"];
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 437 KiB

After

Width:  |  Height:  |  Size: 670 KiB

View File

@ -1,9 +1,9 @@
digraph macro_dat {
rankdir=TB;
fontname="Arial";
node [fontname="Arial", fontsize=10, style=filled, shape=record];
edge [fontname="Arial", fontsize=9];
label="FabNum — Macro-DAT (Diagramme d'Activités Technique)\n\n";
node [fontname="Arial", fontsize=10, style="filled,rounded", shape=box, penwidth=1.5];
edge [fontname="Arial", fontsize=9, penwidth=1.2];
label="FabNum — Macro-DAT (Dossier d'Architecture Technique)\n\n";
labelloc=t;
fontsize=16;
compound=true;
@ -13,9 +13,22 @@ digraph macro_dat {
label="COUCHE STOCKAGE";
style=filled; color="#E3F2FD"; fontsize=13; fontcolor="#1565C0";
base_graphe [label="Base graphe\n(Neo4j / PG+AGE / ArangoDB)|• Nœuds (tous niveaux)\n• Arêtes + attributs\n• Multi-graphes\n• Schéma évolutif\n• Open source", fillcolor="#BBDEFB"];
historisation [label="Historisation|• Snapshots horodatés\n• Versions données\n• Versions indices\n• Audit trail", fillcolor="#BBDEFB"];
sources_db [label="Référentiel sources|• Sources catégorisées\n• Tiers de confiance\n (par domaine)\n• Liens source↔donnée", fillcolor="#BBDEFB"];
bdd_struct [
label="Graphe structurel\n\nCapacités nominales\nActeurs, pays, parts de marché\nIndices structurels\nMise à jour trimestrielle"
fillcolor="#BBDEFB"
];
bdd_situa [
label="Graphe situationnel\n\nImpacts actifs\nCapacités réelles\nIndices situationnels\nHistorique des situations"
fillcolor="#90CAF9"
];
historisation [
label="Historisation\n\nSnapshots horodatés\nVersions données + indices\nAudit trail\nRétro-analyse"
fillcolor="#BBDEFB"
];
sources_db [
label="Référentiel sources\n\nSources catégorisées\nTiers de confiance (par domaine)\nLiens source ↔ donnée\nIndice de fiabilité"
fillcolor="#BBDEFB"
];
}
// ==================== COUCHE MOTEUR ====================
@ -26,41 +39,64 @@ digraph macro_dat {
subgraph cluster_calcul {
label="Calcul";
style=filled; color="#C8E6C9";
calcul_indices [label="Calcul indices|IHH, ICS, IVC, ISG\n+ futurs (eau, énergie)\nPré-calcul à chaque MAJ", fillcolor="#A5D6A7"];
meta_indices [label="Méta-indices|Calcul dynamique\nsur sous-graphe\nsélectionné", fillcolor="#A5D6A7"];
calcul_indices [label="Calcul indices\n\nIHH, ICS, IVC, ISG\n+ futurs (eau, énergie)\nStructurels ET situationnels\nPré-calcul à chaque MAJ", fillcolor="#A5D6A7"];
meta_indices [label="Méta-indices\n\nCalcul dynamique\nsur sous-graphe\nsélectionné", fillcolor="#A5D6A7"];
propagation [label="Propagation\nd'impact\n\nSimulation manuelle\nou via bus\nProjection temporelle\n(stocks)", fillcolor="#A5D6A7"];
}
subgraph cluster_qualite {
label="Qualité données";
style=filled; color="#C8E6C9";
arbitrage [label="Arbitrage sources|Tier 1 par défaut\nConvergence → alerte\nSeuils variation", fillcolor="#A5D6A7"];
qualification [label="Qualification|Filtres qualité\nIndice fiabilité\nPérimètre mesuré", fillcolor="#A5D6A7"];
arbitrage [label="Arbitrage sources\n\nTier 1 par défaut\nConvergence → alerte\nSeuils variation", fillcolor="#A5D6A7"];
qualification [label="Qualification\n\nFiltres qualité\nIndice fiabilité\nPérimètre mesuré", fillcolor="#A5D6A7"];
}
subgraph cluster_requetage {
label="Requêtage";
style=filled; color="#C8E6C9";
chemins [label="Traversée graphe|Chemins critiques\nFiltrage multi-critères\nSous-graphes", fillcolor="#A5D6A7"];
projection [label="Projection SI|Mapping SI client\nsur graphe FabNum\n(stateless)", fillcolor="#A5D6A7"];
chemins [label="Traversée graphe\n\nChemins critiques\nFiltrage multi-critères\nSous-graphes", fillcolor="#A5D6A7"];
projection_client [label="Contextualisation\nclient\n\nMapping contexte client\nsur graphe FabNum\n(stateless)", fillcolor="#A5D6A7"];
scenarios [label="Scénarios\nmulti-impacts\n\nCombinatoire N événements\nComparaison scénarios\nContextualisé client", fillcolor="#A5D6A7"];
}
subgraph cluster_generation {
label="Génération";
style=filled; color="#C8E6C9";
templates [label="Templates fiches|Niveau × usage\nExpertise / Synthèse\nAPI / JSON", fillcolor="#A5D6A7"];
import_export [label="Import / Export|DOT (legacy)\nJSON\nPDF\nBackup / Restore", fillcolor="#A5D6A7"];
templates [label="Templates fiches\n\nNiveau × usage\nExpertise / Synthèse\nAPI / JSON", fillcolor="#A5D6A7"];
import_export [label="Import / Export\n\nDOT (legacy)\nJSON\nPDF\nBackup / Restore", fillcolor="#A5D6A7"];
}
}
// ==================== BUS D'IMPACT ====================
subgraph cluster_bus {
label="BUS D'IMPACT";
style=filled; color="#FBE9E7"; fontsize=13; fontcolor="#BF360C";
memoire [
label="Mémoire situationnelle\n\nImpacts actifs\nHistorique événements\nAccumule, met à jour, archive"
fillcolor="#FFCCBC"
];
traducteur [
label="Traducteur IA\n\nÉvénement → impacts chiffrés\nNœuds impactés, % réduction\nDurée estimée"
fillcolor="#FFAB91"
];
validation [
label="Validation expert\n\nPropose → valide\nPas d'injection automatique"
fillcolor="#FFCCBC"
];
traducteur -> validation -> memoire;
}
// ==================== SERVICES INTERNES ====================
subgraph cluster_services_internes {
label="SERVICES INTERNES (non exposés)";
style=filled; color="#FFF3E0"; fontsize=13; fontcolor="#E65100";
veille [label="Veille sources\n(huginn)|Détection MAJ\nNouvelles sources\nDisparitions", fillcolor="#FFE0B2"];
verif_citations [label="Vérification\ncitations|verify-citations\n(à faire évoluer)", fillcolor="#FFE0B2"];
recalcul [label="Recalcul\nindices|Déclenché par\nMAJ graphe\n(mensuel → trim.)", fillcolor="#FFE0B2"];
alertes [label="Alertes|Variations anormales\nConvergence sources\nÉvénements climat.", fillcolor="#FFE0B2"];
veille [label="Veille sources\n(huginn)\n\nDétection MAJ\nNouvelles sources\nDisparitions", fillcolor="#FFE0B2"];
verif_citations [label="Vérification\ncitations\n\nverify-citations", fillcolor="#FFE0B2"];
recalcul [label="Recalcul indices\n\nDéclenché par MAJ\nstructurel + situationnel", fillcolor="#FFE0B2"];
alertes [label="Alertes\n\nVariations anormales\nConvergence sources", fillcolor="#FFE0B2"];
}
// ==================== API REST ====================
@ -71,77 +107,76 @@ digraph macro_dat {
subgraph cluster_securite {
label="Sécurité";
style=filled; color="#E1BEE7";
auth [label="Authentification|User / API key\nRôles (admin/expert/service)", fillcolor="#CE93D8"];
profils [label="Profils visibilité|Chaîne principale / +connexes\nIndices complets / partiels\nPrédéfinis / sur mesure", fillcolor="#CE93D8"];
rate_limit [label="Rate limiting\n+ Monitoring|Logging structuré\nMétriques\nAlerting", fillcolor="#CE93D8"];
auth [label="Auth + Rôles\n(user / API key)", fillcolor="#CE93D8"];
profils [label="Profils visibilité", fillcolor="#CE93D8"];
rate_limit [label="Rate limiting\nMonitoring", fillcolor="#CE93D8"];
}
subgraph cluster_endpoints {
label="Endpoints";
style=filled; color="#E1BEE7";
ep_graphe [label="/graphe/*|Requêtage\n(expert / simplifié)", fillcolor="#CE93D8"];
ep_fiches [label="/fiches/*|Consultation\n(tous formats)", fillcolor="#CE93D8"];
ep_analyse [label="/analyse/*|Vulnérabilités\nScénarios", fillcolor="#CE93D8"];
ep_indices [label="/indices/*|Méta-indices\ndynamiques", fillcolor="#CE93D8"];
ep_export [label="/export/*|PDF, JSON, DOT", fillcolor="#CE93D8"];
ep_admin [label="/admin/*|CRUD graphe\nGestion sources\nTiers, arbitrage", fillcolor="#CE93D8"];
ep_graphe [label="/graphe/*\nstructurel + situationnel", fillcolor="#CE93D8"];
ep_fiches [label="/fiches/*\ntous formats", fillcolor="#CE93D8"];
ep_analyse [label="/analyse/*\nvulnérabilités, scénarios", fillcolor="#CE93D8"];
ep_indices [label="/indices/*\nstructurels + situationnels", fillcolor="#CE93D8"];
ep_export [label="/export/*\nPDF, JSON, DOT", fillcolor="#CE93D8"];
ep_admin [label="/admin/*\nCRUD, sources", fillcolor="#CE93D8"];
}
}
// ==================== CONSOMMATEURS ====================
subgraph cluster_consommateurs {
label="CONSOMMATEURS";
style=filled; color="#ECEFF1"; fontsize=13; fontcolor="#37474F";
frontend [label="Frontend expert|COMEX : synthèses\nMétiers : analyse opérat.\nDSAI : dépendances SI", fillcolor="#CFD8DC", shape=house];
services_ext [label="Services externes|Génération IA rapports\nAgent local client\nExport manuel", fillcolor="#CFD8DC", shape=house];
ecosysteme [label="Écosystème 360°|Veille stratégique\nIRON\nAlertes croisées", fillcolor="#CFD8DC", shape=house];
}
frontend [label="Frontend expert\n\nAnalyse, simulation,\nqualification", fillcolor="#CFD8DC", shape=house];
client_app [label="Client\n\nCOMEX, Métiers, DSI\nContextualisé", fillcolor="#CFD8DC", shape=house];
ecosysteme [label="Écosystème 360°\n\nVeille stratégique\nIRON, alertes", fillcolor="#CFD8DC", shape=house];
// Admin
admin [label="Admin (scripts)|CRUD graphe\nGestion sources\nTiers, arbitrage\nBackup / restore", fillcolor="#FFCC80", shape=hexagon];
admin [label="Admin (scripts)\n\nCRUD graphe structurel\nGestion sources\nTiers, arbitrage", fillcolor="#FFCC80", shape=hexagon];
// Veille 360°
veille360 [label="Veille 360°\n\nÉvénements géopolitiques\nclimatiques, économiques\nSignaux faibles", fillcolor="#CE93D8", shape=house];
// ==================== LIENS ====================
// Stockage → Moteur
base_graphe -> chemins [color="#1565C0"];
base_graphe -> calcul_indices [color="#1565C0"];
historisation -> meta_indices [style=dashed, color="#1565C0"];
bdd_struct -> chemins [color="#1565C0"];
bdd_struct -> calcul_indices [color="#1565C0"];
bdd_situa -> propagation [color="#1565C0"];
bdd_situa -> scenarios [color="#1565C0"];
sources_db -> arbitrage [color="#1565C0"];
sources_db -> qualification [color="#1565C0"];
// Bus → Stockage + Moteur
memoire -> bdd_situa [label="MAJ\nsituationnel", color="#BF360C"];
memoire -> propagation [label="impacts\nchiffrés", color="#BF360C", penwidth=2];
// Veille 360° → Bus
veille360 -> traducteur [label="événements", color="#6A1B9A", penwidth=2];
// Moteur → Services internes
calcul_indices -> recalcul [color="#E65100"];
arbitrage -> alertes [color="#E65100"];
qualification -> verif_citations [color="#E65100", style=dashed];
// Moteur → API
chemins -> ep_graphe [color="#6A1B9A"];
meta_indices -> ep_indices [color="#6A1B9A"];
templates -> ep_fiches [color="#6A1B9A"];
import_export -> ep_export [color="#6A1B9A"];
projection -> ep_graphe [color="#6A1B9A", style=dashed];
calcul_indices -> ep_analyse [color="#6A1B9A"];
// Sécurité → Endpoints
auth -> ep_graphe [style=dotted, color="#6A1B9A"];
profils -> ep_graphe [style=dotted, color="#6A1B9A"];
propagation -> ep_analyse [color="#6A1B9A"];
scenarios -> ep_analyse [color="#6A1B9A"];
// API → Consommateurs
ep_graphe -> frontend [color="#37474F", penwidth=1.5];
ep_fiches -> frontend [color="#37474F", penwidth=1.5];
ep_analyse -> frontend [color="#37474F", penwidth=1.5];
ep_export -> services_ext [color="#37474F", penwidth=1.5];
ep_graphe -> ecosysteme [color="#37474F", penwidth=1.5];
ep_indices -> ecosysteme [color="#37474F", penwidth=1.5];
ep_graphe -> services_ext [color="#37474F", penwidth=1.5];
ep_graphe -> frontend [color="#37474F"];
ep_analyse -> frontend [color="#37474F"];
ep_fiches -> client_app [color="#37474F"];
ep_analyse -> client_app [color="#37474F"];
ep_graphe -> ecosysteme [color="#37474F"];
ep_indices -> ecosysteme [color="#37474F"];
// Admin
admin -> ep_admin [color="#E65100", penwidth=2];
admin -> base_graphe [color="#E65100", penwidth=2, label="accès\ndirect"];
admin -> bdd_struct [color="#E65100", penwidth=2, label="accès\ndirect"];
// Services internes → Stockage (boucle)
veille -> sources_db [color="#E65100", style=dashed, label="MAJ\nsources"];
recalcul -> base_graphe [color="#E65100", style=dashed, label="MAJ\nindices"];
// Services internes → Stockage
veille -> sources_db [color="#E65100", style=dashed, label="MAJ sources"];
recalcul -> bdd_struct [color="#E65100", style=dashed];
recalcul -> bdd_situa [color="#E65100", style=dashed];
alertes -> admin [color="#E65100", style=dashed, label="notification"];
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 672 KiB

After

Width:  |  Height:  |  Size: 741 KiB