Code/docs/ARCHITECTURE.md
Stéphan Peccini f812fac89e
feat: Amelioration structure - tests, documentation et qualite du code
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>
2026-02-07 19:00:49 +01:00

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 principale
  • sankey.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:

  1. Utilisateur sélectionne un produit ou composant (niveau 0 ou 1)
  2. Extraction des chemins via graph_utils.extraire_chemins_depuis()
  3. Génération du diagramme de Sankey
  4. 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:

  1. Parcours du graphe pour identifier tous les nœuds
  2. 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
  3. Commit des fiches sur Gitea (dépôt DEPOT_FICHES)
  4. 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 :

  1. Sélectionner une chaîne d'approvisionnement
  2. Afficher la criticité globale et par étape
  3. Présenter les préconisations spécifiques et génériques
  4. 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érarchique
    • ihh_pays, ihh_acteurs : Indices de concentration
    • isg : Indice de stabilité géopolitique
    • ivc : 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 Gitea
  • GITEA_TOKEN : Token d'authentification API
  • ORGANISATION : Organisation Gitea
  • DEPOT_FICHES : Nom du dépôt pour les fiches markdown
  • DEPOT_CODE : Nom du dépôt contenant le graphe DOT
  • DOT_FILE : Nom du fichier DOT du graphe
  • ENV : 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 web
  • networkx : Manipulation de graphes
  • pandas : Manipulation de données
  • altair : Visualisations
  • pydot : Parsing de fichiers DOT

API:

  • requests : Requêtes HTTP pour Gitea
  • python-dateutil : Parsing de dates ISO

Tests:

  • pytest : Framework de tests
  • pytest-cov : Couverture de code
  • pytest-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.