Cette mise a jour complete ameliore significativement la qualite et la maintenabilite du projet. 1. Extension de la couverture de tests Couverture globale passee de 8% a 16% (+100%) - Ajout de 25 nouveaux tests (total: 67 tests, 100% passent) - Nouveaux fichiers de tests: * tests/unit/test_gitea.py (17 tests) * tests/unit/test_fiches_tickets.py (8 tests) Etat de la couverture par module: - utils/gitea.py: 100% - utils/widgets.py: 100% - utils/logger.py: 94% - app/fiches/utils/tickets/core.py: 77% - utils/graph_utils.py: 59% 2. Documentation d'architecture complete Creation de 3 nouveaux documents (30 Ko total): - docs/ARCHITECTURE.md (15 Ko) * Architecture complete du projet * Flux de donnees detailles * Indices de vulnerabilite (IHH, ISG, ICS, IVC) * Structure du graphe NetworkX - docs/MODULES.md (15 Ko) * Guide des 11 modules principaux * Exemples de code (15+ snippets) * Bonnes pratiques * Guide de depannage - docs/README.md (4 Ko) * Index de toute la documentation Contenu documente: - 5 modules applicatifs - 6 modules utilitaires - 4 indices de vulnerabilite avec formules et seuils - Conventions de code 3. Reorganisation de la documentation Structure finale optimisee: - Racine: README.md (mis a jour) + Instructions.md - docs/: 11 documents organises par categorie Fichiers deplaces vers docs/: - README_connexion.md -> docs/CONNEXION.md - GUIDE_LOGS.md -> docs/ - GUIDE_RUFF.md -> docs/ - RAPPORT_RUFF.md -> docs/ - RAPPORT_CORRECTIONS_AUTO.md -> docs/ - REFACTORING_REPORT.md -> docs/ - VERIFICATION_LOGS.md -> docs/ - TODO_IA_BATCH.md -> docs/ 4. Ajout de docstrings 52 fonctions documentees en style Google (100%) Documentation en francais avec Args, Returns, Raises 5. Corrections automatiques Ruff Application de 347 corrections automatiques: - Formatage du code (line-length: 120) - Organisation des imports - Simplifications syntaxiques - Suppressions de code mort - Ameliorations de performance 6. Configuration qualite du code Nouveaux fichiers: - pyproject.toml: configuration Ruff complete - .vscode/settings.json: integration Ruff avec formatOnSave - GUIDE_RUFF.md: documentation du linter - GUIDE_LOGS.md: documentation du logging - .gitignore: ajout htmlcov/ pour rapports de couverture Etat final du projet: - Linter: Ruff configure (15 regles actives) - Tests: 67 tests (100% passent) - Couverture de code: 16% - Docstrings: 52/52 (100%) - Documentation: 11 fichiers organises Impact: - Tests plus robustes et maintenables - Documentation technique complete - Meilleure organisation des fichiers - Workflow optimise avec Ruff - Code pret pour integration continue References: - Architecture: docs/ARCHITECTURE.md - Guide modules: docs/MODULES.md - Tests: tests/unit/ - Configuration: pyproject.toml Co-Authored-By: Claude <noreply@anthropic.com>
14 KiB
Architecture FabNum
Vue d'ensemble
FabNum est une application Streamlit d'analyse de risques géopolitiques pour les chaînes d'approvisionnement numériques. Le projet permet de visualiser et d'analyser les vulnérabilités des chaînes d'approvisionnement à travers plusieurs indices de concentration et de criticité.
Structure du projet
FabNum/
├── app/ # Modules applicatifs Streamlit
│ ├── analyse/ # Analyse des chaînes d'approvisionnement
│ ├── fiches/ # Génération et gestion des fiches techniques
│ ├── ia_nalyse/ # Interface d'analyse IA
│ ├── personnalisation/ # Personnalisation du graphe
│ ├── plan_d_action/ # Analyse de criticité et recommandations
│ └── visualisations/ # Visualisations (graphes, diagrammes)
├── utils/ # Utilitaires partagés
│ ├── gitea.py # Intégration API Gitea
│ ├── graph_utils.py # Manipulation des graphes NetworkX
│ ├── logger.py # Système de logging
│ ├── persistance.py # Gestion de la persistence (session Streamlit)
│ ├── translations.py # Système de traduction i18n
│ ├── visualisation.py # Visualisations Altair
│ └── widgets.py # Widgets HTML personnalisés
├── assets/ # Ressources statiques
├── tests/ # Tests unitaires et d'intégration
│ ├── unit/ # Tests unitaires
│ ├── integration/ # Tests d'intégration
│ └── conftest.py # Configuration pytest et fixtures
├── config.py # Configuration globale
└── main.py # Point d'entrée Streamlit
Modules principaux
1. Module analyse - Analyse des chaînes d'approvisionnement
Responsabilité: Analyse et visualisation des chemins d'approvisionnement depuis un produit vers les minerais critiques.
Fichiers clés:
interface.py: Interface utilisateur principalesankey.py: Génération de diagrammes de Sankey pour visualiser les flux
Données manipulées:
- Graphe NetworkX des dépendances produit → composant → minerai
- Indices IHH, ISG, ICS, IVC pour chaque nœud
Flux de données:
- Utilisateur sélectionne un produit ou composant (niveau 0 ou 1)
- Extraction des chemins via
graph_utils.extraire_chemins_depuis() - Génération du diagramme de Sankey
- Affichage des vulnérabilités détectées
2. Module fiches - Génération de fiches techniques
Responsabilité: Génération dynamique de fiches markdown pour chaque élément du graphe (produits, composants, minerais).
Architecture:
fiches/
├── generer.py # Génération des fiches markdown
├── interface.py # Interface de visualisation des fiches
└── utils/
├── dynamic/ # Générateurs de sections dynamiques
│ ├── indice/ # Sections pour IHH, ISG, ICS, IVC
│ ├── assemblage_fabrication/ # Sections production
│ ├── minerai/ # Sections spécifiques aux minerais
│ └── utils/ # Utilitaires (pastilles, formatage)
├── fiche_utils.py # Utilitaires génériques
└── tickets/ # Gestion des tickets Gitea
├── core.py # API Gitea (77% couverture)
├── display.py # Affichage des tickets
└── creation.py # Création de tickets
Flux de génération de fiches:
- Parcours du graphe pour identifier tous les nœuds
- Pour chaque nœud, génération de sections markdown dynamiques :
- Indicateurs de vulnérabilité (IHH, ISG)
- Données de concentration (ICS, IVC)
- Chemins critiques
- Recommandations
- Commit des fiches sur Gitea (dépôt
DEPOT_FICHES) - Synchronisation avec le système de tickets
Intégration Gitea:
- Stockage centralisé des fiches markdown
- Système de tickets pour le suivi des vulnérabilités
- Labels automatiques : opération (Extraction, Traitement, Fabrication, Assemblage) + item (Minerai, Composant)
3. Module plan_d_action - Analyse de criticité
Responsabilité: Calcul de criticité des chaînes d'approvisionnement et génération de recommandations.
Architecture:
plan_d_action/
├── interface.py # Interface utilisateur
└── utils/
├── data/
│ ├── plan_d_action.py # Logique métier de criticité
│ ├── pda_interface.py # Composants UI pour le plan d'action
│ ├── data_processing.py # Traitement des données
│ ├── data_utils.py # Utilitaires données
│ └── config.py # Configuration des seuils
└── interface/
├── selection.py # Sélection des chaînes
├── visualization.py # Visualisations
├── export.py # Export des résultats
└── ...
Calcul de criticité:
La criticité d'une chaîne est calculée selon les poids de vulnérabilité à chaque étape :
def calcul_poids_chaine(
poids_A: int, # Assemblage (0-3)
poids_F: int, # Fabrication (0-3)
poids_T: int, # Traitement (0-3)
poids_E: int, # Extraction (0-3)
poids_M: int # Substitution minerai (0-3)
) -> tuple[str, dict, int]:
"""
Retourne: (criticite_chaine, niveau_criticite, poids_total)
Criticité:
- "Très critique" : poids_total >= 12
- "Critique" : 9 <= poids_total < 12
- "Moyenne" : 6 <= poids_total < 9
- "Faible" : poids_total < 6
"""
Seuils de vulnérabilité (définis dans config.yaml) :
- IHH (concentration géographique/acteurs) : < 15 (vert), 15-25 (orange), > 25 (rouge)
- ISG (instabilité géopolitique) : < 40 (vert), 40-70 (orange), > 70 (rouge)
- ICS (criticité supply-side) : < 15 (vert), 15-60 (orange), > 60 (rouge)
- IVC (vulnérabilité demand-side) : < 15 (vert), 15-60 (orange), > 60 (rouge)
Tableau de bord:
La fonction tableau_de_bord() permet de :
- Sélectionner une chaîne d'approvisionnement
- Afficher la criticité globale et par étape
- Présenter les préconisations spécifiques et génériques
- Exporter le plan d'action en markdown
4. Module utils - Utilitaires partagés
gitea.py - Intégration Gitea (100% couverture)
API principale:
def charger_instructions_depuis_gitea(nom_fichier: str) -> str | None:
"""Charge un fichier depuis Gitea avec cache local basé sur timestamp."""
def charger_schema_depuis_gitea(fichier_local: str) -> str | None:
"""Charge le fichier DOT du graphe depuis Gitea."""
def charger_arborescence_fiches() -> dict:
"""Charge l'arborescence complète des fiches markdown."""
Fonctionnalités:
- Cache local avec vérification de timestamp (évite les téléchargements inutiles)
- Authentification automatique via
GITEA_TOKEN - Gestion des erreurs réseau avec fallback sur le cache
graph_utils.py - Manipulation de graphes (59% couverture)
Fonctions principales:
def extraire_chemins_depuis(G: nx.DiGraph, noeud_depart: str) -> list[list[str]]:
"""Extrait tous les chemins depuis un nœud vers les feuilles."""
def extraire_chemins_vers(G: nx.DiGraph, noeud_cible: str, niveau_demande: int) -> list[list[str]]:
"""Extrait les chemins vers un nœud cible depuis le niveau demandé."""
def recuperer_donnees(graph: nx.DiGraph, noeuds: list[str]) -> pd.DataFrame:
"""Récupère les données IHH/ICS pour des nœuds operation-minerai."""
def recuperer_donnees_2(graph: nx.DiGraph, minerais: list[str]) -> list[dict]:
"""Récupère les données IVC/IHH pour les minerais (extraction + réserves)."""
def charger_graphe(dot_file: str = "schema_temp.txt") -> nx.DiGraph:
"""Charge le graphe depuis un fichier DOT."""
Structure du graphe:
-
Niveaux:
- 0 : Produits finaux
- 1 : Composants
- 2 : Minerais
- 10 : Opérations (Assemblage, Fabrication, Traitement, Extraction, Réserves)
- 11 : Pays d'opération
- 99 : Pays géographiques
-
Attributs de nœuds:
niveau: Niveau hiérarchiqueihh_pays,ihh_acteurs: Indices de concentrationisg: Indice de stabilité géopolitiqueivc: Indice de vulnérabilité (minerais)ics: Indice de criticité supply-side (arêtes)
persistance.py - Gestion de session (0% couverture)
Gère la persistence d'état via st.session_state :
def get_session_id() -> str:
"""Récupère l'ID de session Streamlit."""
def update_session_paths(session_id: str, paths: list):
"""Met à jour les chemins en session."""
def get_champ_statut(cle: str) -> Any:
"""Récupère une valeur du session_state."""
logger.py - Système de logging (94% couverture)
def setup_logger(name: str, level: str = "INFO", log_to_file: bool = False) -> logging.Logger:
"""Configure un logger avec handler console et optionnellement fichier."""
def get_logger(name: str) -> logging.Logger:
"""Récupère ou crée un logger."""
Flux de données principal
1. Chargement initial
main.py
→ config.py (variables d'environnement)
→ utils/gitea.charger_schema_depuis_gitea()
→ utils/graph_utils.charger_graphe()
→ Graphe NetworkX en st.session_state
2. Navigation utilisateur (module Analyse)
app/analyse/interface.py
→ Sélection produit/composant
→ graph_utils.extraire_chemins_depuis()
→ analyse/sankey.py pour visualisation
→ Affichage des vulnérabilités (IHH, ICS, IVC)
3. Génération de fiches (module Fiches)
app/fiches/generer.py
→ Parcours du graphe
→ Pour chaque nœud:
→ utils/dynamic/indice/*.py (génération sections)
→ utils/dynamic/minerai/minerai.py (sections minerai)
→ Commit vers Gitea (DEPOT_FICHES)
→ Création/mise à jour tickets
4. Plan d'action (module Plan d'action)
app/plan_d_action/interface.py
→ utils/data/plan_d_action.analyser_chaines()
→ Calcul des poids A/F/T/E/M
→ Détermination de la criticité
→ utils/data/plan_d_action.tableau_de_bord()
→ Affichage préconisations et export
Configuration et environnement
Fichiers de configuration
config.py - Configuration globale:
GITEA_URL = os.getenv("GITEA_URL")
GITEA_TOKEN = os.getenv("GITEA_TOKEN")
ORGANISATION = os.getenv("ORGANISATION")
DEPOT_FICHES = os.getenv("DEPOT_FICHES")
DEPOT_CODE = os.getenv("DEPOT_CODE")
DOT_FILE = os.getenv("DOT_FILE")
ENV = os.getenv("ENV") # Branche Gitea (dev/main)
config.yaml - Seuils de vulnérabilité:
seuils:
IHH:
vert: {max: 15}
orange: {min: 15, max: 25}
rouge: {min: 25}
ISG:
vert: {max: 40}
orange: {min: 40, max: 70}
rouge: {min: 70}
ICS:
vert: {max: 15}
orange: {min: 15, max: 60}
rouge: {min: 60}
IVC:
vert: {max: 15}
orange: {min: 15, max: 60}
rouge: {min: 60}
Variables d'environnement requises
GITEA_URL: URL de l'instance GiteaGITEA_TOKEN: Token d'authentification APIORGANISATION: Organisation GiteaDEPOT_FICHES: Nom du dépôt pour les fiches markdownDEPOT_CODE: Nom du dépôt contenant le graphe DOTDOT_FILE: Nom du fichier DOT du grapheENV: Branche Gitea à utiliser (dev/main)
Tests
Couverture actuelle
Couverture globale: 16%
Modules testés:
utils/gitea.py: 100% ✓utils/widgets.py: 100% ✓utils/logger.py: 94% ✓app/fiches/utils/tickets/core.py: 77% ✓utils/graph_utils.py: 59%
Structure des tests
tests/
├── conftest.py # Fixtures globales
│ ├── simple_graph() # Graphe simple pour tests
│ ├── complex_graph() # Graphe avec chemins multiples
│ └── sample_config_yaml() # Config YAML de test
├── unit/
│ ├── test_gitea.py # Tests utils/gitea.py
│ ├── test_fiches_tickets.py # Tests app/fiches/utils/tickets/core.py
│ ├── test_graph_utils.py # Tests utils/graph_utils.py
│ ├── test_logger.py # Tests utils/logger.py
│ └── test_widgets.py # Tests utils/widgets.py
└── integration/
└── (à venir)
Exécuter les tests
# Tous les tests
pytest -v
# Avec couverture
pytest --cov=utils --cov=app --cov-report=html
# Tests spécifiques
pytest tests/unit/test_gitea.py -v
Dépendances principales
Core:
streamlit: Framework webnetworkx: Manipulation de graphespandas: Manipulation de donnéesaltair: Visualisationspydot: Parsing de fichiers DOT
API:
requests: Requêtes HTTP pour Giteapython-dateutil: Parsing de dates ISO
Tests:
pytest: Framework de testspytest-cov: Couverture de codepytest-mock: Mocking
Qualité de code:
ruff: Linter et formatter Python moderne
Conventions de code
Style
- Formatage: Ruff (line-length: 120)
- Docstrings: Google style
- Langue: Français pour les docstrings et l'UI, anglais pour le code
Nommage
- Fonctions:
snake_case - Classes:
PascalCase - Constantes:
UPPER_SNAKE_CASE - Fichiers:
snake_case.py
Organisation des imports
# 1. Standard library
import os
from datetime import datetime
# 2. Third-party
import pandas as pd
import streamlit as st
# 3. Local
from config import GITEA_URL
from utils.graph_utils import charger_graphe
Roadmap et améliorations futures
Tests
- Augmenter la couverture de
app/plan_d_action(actuellement 0%) - Tests d'intégration pour les flux complets
- Tests de performance pour les graphes volumineux
Documentation
- Documentation d'architecture (ce fichier)
- Guide utilisateur
- API documentation (docstrings complètes)
- Diagrammes de séquence pour les flux critiques
Fonctionnalités
- Export des analyses en PDF
- Alertes automatiques sur nouvelles vulnérabilités
- Comparaison historique des indices
- Interface d'administration pour gérer les seuils
Infrastructure
- CI/CD avec Gitea Actions
- Déploiement automatique
- Monitoring et logging centralisé
Contact et contribution
Ce projet est développé par Stéphan Peccini Conseil dans le cadre de l'Observatoire des Polycrises.
Pour contribuer ou signaler des bugs, veuillez consulter le dépôt Gitea de l'organisation.