Code/docs/plans/2026-03-02-audit-qualite-design.md
Stéphan Peccini 6d2e877341
feat(audit): audit qualité complet — 907→0 erreurs ruff + fix multiselect labels
- Correction des 907 erreurs ruff (pathlib, imports, nommage, simplifications, docstrings)
- Fix déduplication labels dans multiselect nœuds d'arrivée (analyse)
- Expansion 1→N label→IDs pour le Sankey (Pays d'opération)
- Ajout CLAUDE.md et document de design de l'audit
- Mise à jour .gitignore (artefacts tests exploratoires)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 11:52:01 +01:00

7.2 KiB

Audit qualite, securite et simplicite - FabNum

Date : 2 mars 2026 Objectif : Bilan de sante complet du projet

Contexte

FabNum est une application Streamlit (Python 3.14) d'analyse de chaines de valeur numeriques. Le projet comprend ~11 200 lignes de code Python reparties sur 6 modules applicatifs, 7 utilitaires, 4 composants UI et des scripts auxiliaires (IA, batch, generation).

Etat actuel

Metrique Valeur
Securite (Bandit) 0 vulnerabilite
Dependances (pip-audit --local) 0 vulnerabilite
Qualite (ruff) 907 erreurs
Tests 67 tests, 100% passent
Couverture 16%
Bugs averes 1 (F821 nom indefini)
CLAUDE.md Absent

Plan par phases

Phase 1 : Critique (bugs et erreurs dangereuses)

Objectif : Corriger les problemes qui causent ou masquent des bugs.

Regle Nb Description
F821 1 Nom indefini ingested_section_ids dans scripts/generer_analyse.py:471
E722 5 except: nu (masque toutes les exceptions y compris KeyboardInterrupt)
B904 1 raise sans from dans un except (perte de contexte d'erreur)
W605 1 Sequence d'echappement invalide dans une chaine

Total : 8 erreurs. Effort : ~30 minutes. Verification : ruff check . --exclude venv,pgpt,.git --select F821,E722,B904,W605

Phase 2 : Nettoyage automatique (ruff --fix)

Objectif : Appliquer les 330 corrections automatiques sans risque.

Commande : ruff check . --exclude venv,pgpt,.git --fix

Principales corrections :

  • W293 (125) : Espaces sur lignes vides
  • I001 (41) : Imports non tries
  • D212 (38) : Docstrings multi-lignes mal formatees
  • F401 (27) : Imports inutilises
  • UP006 (27) : Annotations type obsoletes (List -> list, Dict -> dict)
  • RET505 (16) : Else superflu apres return
  • W291 (15) : Espaces en fin de ligne
  • Autres (41) : UP009, UP015, F541, D202, W292, UP007, UP024, SIM114, SIM300, UP012

Verification apres fix : relancer les 67 tests pour confirmer aucune regression.

Phase 3 : Qualite manuelle (577 erreurs restantes)

Objectif : Ameliorer la qualite du code manuellement, par sous-chantiers.

3a. Modernisation pathlib (~220 erreurs)

Remplacer les appels os.path.* et os.makedirs par pathlib.Path. Regles : PTH118, PTH123, PTH110, PTH208, PTH103, PTH120, PTH122, PTH112, PTH100, PTH119, PTH204, PTH207, PTH113.

Approche : traiter fichier par fichier, en commencant par utils/ puis app/.

3b. Nommage (88 erreurs)

N803 : noms d'arguments invalides. Decision a prendre : G (convention NetworkX pour les graphes) est utilise partout. Options :

  • Ignorer N803 globalement pour les arguments nommes G, G_temp, G_temp_ivc
  • Renommer en graph partout (refactoring lourd) Recommandation : ajouter G a la liste des noms acceptes dans la config ruff.

3c. Documentation (90 erreurs)

  • D103 (35) : Fonctions publiques sans docstring
  • D415 (26) : Docstrings sans ponctuation finale
  • D200 (14) : Docstrings multi-lignes inutiles
  • D205 (12) : Ligne vide manquante apres resume de docstring
  • D417 (2) : Parametres non documentes
  • D301 (1) : Sequence d'echappement dans docstring

3d. Code inutilise (~53 erreurs)

  • B007 (30) : Variables de boucle inutilisees (remplacer par _)
  • ARG001 (11) : Arguments de fonction inutilises
  • ARG002 (7) : Arguments de methode inutilises
  • F841 (5) : Variables locales inutilisees

3e. Imports (46 erreurs)

  • E402 (29) : Imports pas en haut de fichier Note : certains sont voulus dans Streamlit (imports apres st.set_page_config) Decision : ajouter # noqa: E402 pour les cas legitimes
  • UP035 (17) : Imports deprecies (typing.List -> list, etc.)

3f. Simplifications (~59 erreurs)

  • RET504 (23) : Assignation inutile avant return
  • SIM108 (7) : If/else remplacable par expression ternaire
  • SIM105 (6) : Try/except remplacable par contextlib.suppress
  • SIM102 (5) : If imbriques collapsibles
  • SIM201 (4) : Negation de comparaison (not x == y -> x != y)
  • RET503 (4) : Return implicite
  • Autres (10) : C401, C408, C405, E701, E741, PIE810, SIM103, SIM117, SIM210, UP038

Phase 4 : Couverture de tests (16% -> 40%)

Objectif : Couvrir les modules critiques qui sont a 0%.

Priorite haute :

  • utils/persistance.py (0%, 112 lignes) : coeur de la gestion de session
  • app/fiches/utils/dynamic/minerai/minerai.py (4%, 585 lignes) : module le plus gros
  • app/fiches/generer.py (12%, 113 lignes) : generation de fiches

Priorite moyenne :

  • app/personnalisation/ (0%, ~253 lignes)
  • app/plan_d_action/ (0%, ~67 lignes interface)
  • app/visualisations/ (0%, ~133 lignes)

Priorite basse :

  • app/ia_nalyse/ (0%, 114 lignes) : depend d'un service externe
  • utils/translations.py (28%)
  • utils/visualisation.py (0%)

Note : les modules Streamlit sont difficiles a tester unitairement. Strategie : tester la logique metier en l'isolant de l'interface Streamlit.

Phase 5 : Simplification / Refactoring

Objectif : Decouper les gros fichiers pour ameliorer la maintenabilite.

Candidats :

  • minerai.py (~585 lignes) : decouper par type de section (header, body, indices, etc.)
  • modification.py (~341 lignes) : separer logique de donnees et interface
  • fabnum.py (217 lignes) : extraire get_total_bytes_for_session et charger_theme dans un module utils/session.py ou similaire

Phase bonus : Documentation projet

  • Creer un CLAUDE.md avec les conventions du projet (structure, nommage, outils, commandes de dev, decisions architecturales)

Ordre d'execution recommande

  1. Phase 1 (critique) - a faire immediatement
  2. Phase 2 (auto-fix) - dans la foulee
  3. Phase 3b (nommage - decision sur G) - debloquer avant le reste
  4. Phase 3a (pathlib) - le plus gros chantier, fichier par fichier
  5. Phase 3d (code inutilise) - rapide
  6. Phase 3e (imports) - rapide
  7. Phase 3f (simplifications) - au fil de l'eau
  8. Phase 3c (documentation) - au fil de l'eau
  9. Phase 4 (tests) - en parallele des phases 3
  10. Phase 5 (refactoring) - une fois les tests en place
  11. Phase bonus (CLAUDE.md) - a tout moment

Criteres de succes

Metrique Avant Objectif Resultat
Erreurs ruff 907 < 50 0
Couverture tests 16% >= 40% 35% (448 tests)
Bugs averes 1 0 0
CLAUDE.md Absent Present Present

Resultats de l'audit (2 mars 2026)

Phase 1 : COMPLETE

  • 8 erreurs critiques corrigees (F821, E722, B904, W605)

Phase 2 : COMPLETE

  • 330 corrections automatiques appliquees avec ruff --fix

Phase 3 : COMPLETE

  • 907 -> 0 erreurs ruff
  • Migration complete vers pathlib (PTH)
  • Ajout N803 aux ignores (convention NetworkX G)
  • Corrections manuelles via 5 agents paralleles (RET, SIM, B007, D*, PTH)

Phase 4 : COMPLETE (35% au lieu de 40% vise)

  • 67 -> 448 tests (+381 tests, x6.7)
  • 14 modules a 100% de couverture
  • Modules non-testes : principalement interface Streamlit (difficile a tester unitairement)
  • La couverture restante concerne des modules UI fortement couples a Streamlit

Phase 5 : ANALYSEE (refactoring deporte)

  • Candidats identifies : minerai.py (577L), modification.py (341L), fabnum.py (212L)
  • Decision : refactoring deporte car fortement couple a Streamlit, risque eleve pour benefice limite dans le cadre de l'audit
  • Recommandation : refactorer incrementalement lors des evolutions fonctionnelles

Bonus : COMPLETE

  • CLAUDE.md cree avec conventions du projet