# Rapport d'analyse Ruff - Projet FabNum

**Date** : 2026-02-07
**Branche** : `refactor/ameliorations-structure`

## Statistiques globales

| Categorie | Nombre | Auto-fixable |
|-----------|--------|--------------|
| **Total problemes detectes** | 615 | 322 (52%) |
| **Docstrings manquantes** | 52 | Non |
| **Arguments non documentes** | 2 | Non |
| **Annotations depreciees** | 118 | Oui |
| **Imports mal tries** | 48 | Oui |
| **Style docstrings** | 68 | Oui |
| **Nommage variables** | 83 | Non |

## Top 10 des problemes detectes

1. **UP006** (118) : Annotations de type depreciees (Tuple → tuple, List → list)
2. **N803** (83) : Noms d'arguments non conformes (G → graph)
3. **D212** (68) : Style docstrings (resume sur premiere ligne)
4. **D103** (52) : **Docstrings manquantes dans fonctions publiques**
5. **I001** (48) : Imports mal tries ou non formattes
6. **UP007** (29) : Union types deprecies (Optional[X] → X | None)
7. **PTH123** (24) : Utiliser pathlib au lieu de open()
8. **RET504** (17) : Assignation inutile avant return
9. **RET505** (14) : else inutile apres return
10. **UP015** (14) : Mode 'r' redondant dans open()

## Docstrings manquantes (54 fonctions)

### Fichiers prioritaires (logique metier critique)

#### utils/gitea.py (5 fonctions)
- `lire_reponse()` - Ligne 11
- `ecrire_reponse()` - Ligne 16
- `verifier_cache_valide()` - Ligne 45
- `lire_contenu_repo()` - Ligne 58
- `get_json()` - Ligne 80

#### utils/graph_utils.py (5 fonctions)
- `recuperer_donnees()` - Ligne 20
- `recuperer_donnees_2()` - Ligne 35
- `calculer_ihh()` - Ligne 59
- `obtenir_operations_et_pays()` - Ligne 106
- `calculer_nombre_pays()` - Ligne 251

#### app/plan_d_action/utils/data/plan_d_action.py (12 fonctions)
- `construire_plan_d_action()` - Ligne 17
- `obtenir_dernier_niveau_operation()` - Ligne 38
- `recuperer_minerais_operation()` - Ligne 78
- `determiner_action_operation()` - Ligne 142
- `obtenir_operations_concernees()` - Ligne 200
- `calculer_criticite_minerai()` - Ligne 241
- `recuperer_pays_minerai()` - Ligne 271
- `calculer_isg_moyen()` - Ligne 281
- `calculer_ics_moyen()` - Ligne 291
- `obtenir_risques_critiques()` - Ligne 307
- `calculer_score_risque()` - Ligne 329
- `generer_recommandations()` - Ligne 355

#### app/fiches/utils/tickets/core.py (7 fonctions)
- `creer_ticket()` - Ligne 12
- `modifier_ticket()` - Ligne 24
- `supprimer_ticket()` - Ligne 49
- `lister_tickets()` - Ligne 81
- `get_ticket()` - Ligne 94
- `ticket_exists()` - Ligne 98
- `get_all_tickets()` - Ligne 102

#### app/fiches/utils/tickets/display.py (4 fonctions)
- `afficher_ticket()` - Ligne 14
- `afficher_liste_tickets()` - Ligne 26
- `formater_date()` - Ligne 55
- `afficher_badge_statut()` - Ligne 70

### Fichiers secondaires

#### utils/persistance.py (6 fonctions)
- `charger_config()` - Ligne 11
- `sauver_config()` - Ligne 15
- `get_cache_path()` - Ligne 146
- `read_cache()` - Ligne 149
- `write_cache()` - Ligne 152
- `clear_cache()` - Ligne 155

#### utils/visualisation.py (4 fonctions)
- `afficher_graphique_altair()` - Ligne 9
- `creer_graphes()` - Ligne 82
- `lancer_visualisation_ihh_ics()` - Ligne 156
- `lancer_visualisation_ihh_ivc()` - Ligne 174

#### Autres (11 fonctions)
- app/analyse/interface.py : 1 fonction (ligne 81)
- app/fiches/interface.py : 1 fonction (ligne 20)
- app/fiches/utils/tickets/creation.py : 1 fonction (ligne 174)
- app/personnalisation/interface.py : 1 fonction (ligne 12)
- app/personnalisation/utils/ajout.py : 1 fonction (ligne 7)
- app/personnalisation/utils/import_export.py : 1 fonction (ligne 6)
- app/plan_d_action/utils/data/pda_interface.py : 3 fonctions (lignes 3, 130, 172)

## Arguments non documentes (2 fonctions)

1. **app/analyse/sankey.py:557** - `afficher_sankey()`
   - Manque : filtrer_ics, filtrer_ivc, niveau_arrivee, niveau_depart, noeuds_arrivee, noeuds_depart

2. **app/fiches/utils/dynamic/indice/ics.py:67** - `build_dynamic_sections()`
   - Manque : md_raw

## Corrections automatiques disponibles

Ruff peut corriger automatiquement **322 problemes** (52%) :

### Corrections rapides (5 min)
```bash
# Trier les imports
ruff check app/ utils/ --select I001 --fix

# Corriger le style des docstrings
ruff check app/ utils/ --select D212,D202 --fix

# Moderniser les annotations de type
ruff check app/ utils/ --select UP006,UP007 --fix
```

### Corrections a valider (15 min)
```bash
# Simplifier les returns
ruff check app/ utils/ --select RET504,RET505,RET507 --fix

# Supprimer code inutile
ruff check app/ utils/ --select UP015,PIE790 --fix
```

## Plan d'action recommande

### Phase 1 : Corrections automatiques (20 min)
1. Executer les corrections auto-fixables
2. Verifier que les tests passent
3. Commit

### Phase 2 : Docstrings critiques (3-4h)
Priorite par importance metier :

1. **utils/gitea.py** (30 min)
   - Critique : synchronisation avec backend Gitea

2. **utils/graph_utils.py** (45 min)
   - Critique : calculs des indices IHH, IVC, etc.

3. **app/plan_d_action/utils/data/plan_d_action.py** (1h30)
   - Critique : logique metier du plan d'action

4. **app/fiches/utils/tickets/*** (1h)
   - Important : systeme de tickets

5. **Autres fichiers** (30 min)
   - Moins critique mais necessaire

### Phase 3 : Corrections manuelles (1-2h)
1. Renommer G → graph (83 occurrences)
2. Remplacer open() par pathlib (24 occurrences)
3. Nettoyer les else inutiles (14 occurrences)

### Phase 4 : Validation finale (30 min)
1. Executer tous les tests
2. Verifier avec Ruff qu'il ne reste que des warnings acceptables
3. Commit final

## Temps total estime : 6-8h

## Commandes utiles

### Voir tous les problemes
```bash
ruff check app/ utils/
```

### Voir uniquement les docstrings
```bash
ruff check app/ utils/ --select D
```

### Corriger automatiquement
```bash
ruff check app/ utils/ --fix
```

### Verifier un fichier specifique
```bash
ruff check app/plan_d_action/utils/data/plan_d_action.py
```

### Statistiques
```bash
ruff check app/ utils/ --statistics
```

## Notes

- Les modules IA/, batch_ia/, pgpt/ sont exclus de l'analyse (priorite basse)
- La convention de docstrings est Google Style
- Longueur de ligne maximale : 120 caracteres
- Tests pytest integres dans la configuration
