chore(rgpd): replace CHCB/Bayonne refs in docs (D-12)
Anonymise les références aux entités réelles (CHCB, villes basques, Saint-Denis, Réunion, etc.) dans la documentation projet, les maquettes HTML/Python, les notes de coordination et les audits. Conserve docs/coordination/decisions/2026-06-02_dom_mvp-pivots-strategiques.md (table de mapping de référence) et docs/coordination/inbox/for-claude/ intacts. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
412
docs/coordination/audits/2026-05-28_qwen_audit-complet.md
Normal file
412
docs/coordination/audits/2026-05-28_qwen_audit-complet.md
Normal file
@@ -0,0 +1,412 @@
|
||||
# Audit complet — Projet Anonymisation de documents médicaux
|
||||
|
||||
**Date** : 28 mai 2026
|
||||
**Audit réalisé par** : Qwen Code
|
||||
**Répertoire analysé** : `/home/dom/ai/anonymisation/`
|
||||
|
||||
---
|
||||
|
||||
## Sommaire
|
||||
|
||||
1. [Synthèse globale](#1-synthèse-globale)
|
||||
2. [Risques critiques](#2-risques-critiques)
|
||||
3. [Risques importants](#3-risques-importants)
|
||||
4. [Appréciations positives](#4-appréciations-positives)
|
||||
5. [Recommandations prioritaires](#5-recommandations-priorisées)
|
||||
6. [Métriques](#6-métriques)
|
||||
7. [Rapport détaillé par domaine](#7-rapport-détaillé-par-domaine)
|
||||
|
||||
---
|
||||
|
||||
## 1. Synthèse globale
|
||||
|
||||
| Domaine | Appréciation | Risque |
|
||||
|---|---|---|
|
||||
| Architecture | ⚠️ Moyen | **Élevé** |
|
||||
| Core (`anonymizer_core_refactored_onnx.py`) | ⚠️ Fonctionnel mais fragile | **Élevé** |
|
||||
| Qualité du code | ⚠️ Moyen | **Moyen** |
|
||||
| Tests | ✅ Bon | **Moyen** |
|
||||
| Documentation | ✅ Très bon | **Faible** |
|
||||
| Sécurité / Conformité | ✅ Bon sur le papier, ⚠️ dans le code | **Moyen** |
|
||||
| Build / CI/CD | ⚠️ Moyen | **Moyen** |
|
||||
| Gestion du code mort | ❌ Problématique | **Moyen** |
|
||||
|
||||
---
|
||||
|
||||
## 2. Risques critiques
|
||||
|
||||
### 2.1 Fuites PII silencieuses (`except Exception: pass`)
|
||||
|
||||
Le core de 4 770 lignes contient **~47 clauses `except Exception`**, dont ~20 sont des silences purs (`pass`). Les plus dangereux :
|
||||
|
||||
| Localisation | Ligne(s) | Problème |
|
||||
|---|---|---|
|
||||
| `extract_text_with_fallback_ocr` | ~1118-1156 | Chaque passe d'extraction PDF (PyMuPDF, pdfplumber, pdfminer, docTR) capture l'exception sans log. Si PyMuPDF échoue silencieusement, on ne sait jamais pourquoi. |
|
||||
| `redact_pdf_vector` → `apply_redactions()` | ~3938 | Si la rédaction PDF échoue, le PDF de sortie peut être **non anonymisé** sans aucun avertissement. |
|
||||
| `_rasterize_page` (police DejaVu) | ~3991 | Fallback de police silencieux. |
|
||||
| `process_pdf` (VLM et NER) | ~4137, 4202 | Dégradation gracieuse acceptable, mais aucun log même en debug. |
|
||||
| Rédaction vectorielle dans `process_pdf` | ~4655 | Tout le bloc de rédaction est dans un `try/except: pass`. Le PDF peut ne pas être généré. |
|
||||
|
||||
**Impact** : Un document contenant des données de santé personnelles (PHI) pourrait être délivré non anonymisé. Dans le contexte médical, c'est un risque réglementaire majeur (RGPD, hébergement HDS).
|
||||
|
||||
**Recommandation** : Remplacer systématiquement `except Exception: pass` par `except Exception as e: log.warning("...", exc_info=e)` sur les chemins critiques. Minimum : logguer l'erreur.
|
||||
|
||||
### 2.2 Chemin absolu hardcodé dans le `.spec`
|
||||
|
||||
```python
|
||||
# anonymisation_onefile.spec
|
||||
app_dir = 'C:\\Users\\dom\\ai\\anonymisation'
|
||||
```
|
||||
|
||||
Le build PyInstaller ne fonctionne que sur la machine de `dom`. Tout rebuild sur une autre machine échouera ou produira un binaire cassé.
|
||||
|
||||
**Recommandation** : Utiliser `Path(__file__).parent` ou une variable d'environnement.
|
||||
|
||||
### 2.3 Regex recompilées à chaque ligne
|
||||
|
||||
Des regex sont compilées inline dans `_mask_line_by_content`, appelée pour **chaque ligne de chaque page** :
|
||||
|
||||
```python
|
||||
_re_ville_date = re.compile(r"...", re.MULTILINE)
|
||||
_re_lieu = re.compile(r"(...)")
|
||||
_re_ville_res = re.compile(r"(...)")
|
||||
_stop_rx = re.compile(_MEDICAL_STOP_WORDS, re.IGNORECASE)
|
||||
```
|
||||
|
||||
Sur un document de 50 pages / 2 000 lignes → **2 000 recompilations inutiles**. Dégradation estimée : **3-5x** sur gros documents.
|
||||
|
||||
**Recommandation** : Compiler ces regex au niveau module (une seule fois) en variables globales.
|
||||
|
||||
---
|
||||
|
||||
## 3. Risques importants
|
||||
|
||||
### 3.1 Deux build systems parallèles incohérents
|
||||
|
||||
| Système | Point d'entrée | Fonctionnalités |
|
||||
|---|---|---|
|
||||
| PyInstaller (`.spec`) | `launcher.py` | Splash, single-instance, téléchargement modèles |
|
||||
| Nuitka (`build_windows.bat`) | `Pseudonymisation_Gui_V5.py` | Direct GUI, sans setup |
|
||||
|
||||
Les deux produisent des expériences utilisateur différentes et ciblent des points d'entrée différents.
|
||||
|
||||
### 3.2 Core double
|
||||
|
||||
| Fichier | Lignes | Statut |
|
||||
|---|---|---|
|
||||
| `anonymizer_core_refactored.py` | 388 | Version incomplète, sans NER ONNX |
|
||||
| `anonymizer_core_refactored_onnx.py` | 4 770 | Version active |
|
||||
|
||||
Un développeur pourrait importer le mauvais fichier par erreur.
|
||||
|
||||
### 3.3 ~2 000 lignes de code mort
|
||||
|
||||
| Fichier | Lignes | Statut |
|
||||
|---|---|---|
|
||||
| `pseudonymisation_pipeline_gui_v3.py` | 439 | GUI V3 abandonnée |
|
||||
| `Pseudonymisation_Gui_Models_V4.py` | 390 | GUI V4 abandonnée |
|
||||
| `pseudonymisation_pipeline_robuste.py` | 627 | RobustEngine non utilisé dans le pipeline principal |
|
||||
| `Pseudonymisation_Pipeline_Robuste_Patch.py` | 167 | Patch probablement obsolète |
|
||||
| `anonymizer_core_refactored.py` | 388 | Core incomplet |
|
||||
|
||||
### 3.4 `_search_whole_word` — complexité N²
|
||||
|
||||
`page.get_text("words")` est appelé **une fois par token** à chercher dans PyMuPDF :
|
||||
|
||||
```python
|
||||
for w in page.get_text("words"):
|
||||
wt = w[4].strip(".,;:!?()[]{}\"'«»-–—/\\")
|
||||
if wt.lower() == p_lower:
|
||||
rects.append(fitz.Rect(...))
|
||||
```
|
||||
|
||||
Pour 500 noms × 30 pages = **15 000 appels** à `get_text("words")`.
|
||||
|
||||
### 3.5 Injection via regex utilisateur
|
||||
|
||||
Les `regex_overrides` du YAML ne sont pas validés. Un pattern comme `(.*)` avec `DOTALL` pourrait capturer tout le document. Aucune sandboxing n'est appliquée.
|
||||
|
||||
### 3.6 Données sensibles en mémoire
|
||||
|
||||
Le fichier garde toutes les PII en mémoire (`anon.audit`) avec les valeurs originales non masquées. Pas de `del` ou de nettoyage explicite après usage. En cas de crash ou de dump mémoire, les données non anonymisées sont exposées.
|
||||
|
||||
### 3.7 Données de test exposées
|
||||
|
||||
Les répertoires `test_*/` et `corpus_validation/` contiennent des fichiers `.audit.jsonl` et `.pseudonymise.txt` qui sont des **sorties réelles d'anonymisation** (potentiellement avec des données sensibles résiduelles). Ils ne devraient pas être versionnés.
|
||||
|
||||
---
|
||||
|
||||
## 4. Appréciations positives
|
||||
|
||||
### 4.1 Documentation riche et structurante
|
||||
|
||||
- `cadrage-projet-anonymisation.md` — document de cadrage complet avec priorités, gates de release, gouvernance
|
||||
- `AIPD-anonymisation.md` — analyse d'impact sur la protection des données
|
||||
- `conformite-rgpd-ia-act.md` — conformité RGPD et IA Act
|
||||
- `annotation_guide.md` — guide d'annotation
|
||||
- `protocole-validation-humaine.md` — protocole de validation humaine
|
||||
- `spec-regles-administration.md` — spécifications des règles d'administration
|
||||
|
||||
### 4.2 Corpus de test solide
|
||||
|
||||
- **27 documents réels** annotés manuellement dans `tests/ground_truth/`
|
||||
- **4 couches de tests** : unitaires, regression synthétique, corpus réel, validation humaine
|
||||
- **13 tests unitaires** pytest dans `tests/unit/`
|
||||
- **Score de référence : 97.0/100 [Grade A]**
|
||||
- Baseline enregistrée : 0 fuite audit, 0 fuite regex, 0 fuite INSEE haute
|
||||
|
||||
### 4.3 Architecture de configuration saine
|
||||
|
||||
- Séparation `dictionnaires.default.yml` / `dictionnaires.yml` (overlay runtime)
|
||||
- 5 profils utilisateur dans `profiles.default.yml` (standard_local, chuxx_strict, partage_recherche, dossier_audit, demo)
|
||||
- Règles admin avec cycle de vie (draft/candidate/active) dans `admin_rules.default.yml`
|
||||
- Schéma JSON de validation dans `schemas/admin_rules.schema.json`
|
||||
|
||||
### 4.4 Pipeline d'anonymisation bien conçu
|
||||
|
||||
- 5 passes d'extraction avec fallback (pdfplumber → pdfminer → PyMuPDF → docTR OCR → tesseract)
|
||||
- Propagation globale des PII sur toutes les pages
|
||||
- Rescan de sécurité post-anonymisation
|
||||
- Gazetteers Aho-Corasick pour FINESS, villes, noms de famille
|
||||
- NER multi-modèles : EDS-Pseudo (F1=0.97), CamemBERT-bio ONNX, GLiNER, VLM Ollama
|
||||
|
||||
### 4.5 Évaluation structurée
|
||||
|
||||
- **5 axes** : LEAK_AUDIT, LEAK_REGEX, LEAK_INSEE, FP_DENSITY, FP_MEDICAL
|
||||
- Scoring pondéré avec notation A+ → F
|
||||
- Comparaison automatique avec baseline
|
||||
- Export JSON des résultats
|
||||
|
||||
### 4.6 Absence de dépendances circulaires
|
||||
|
||||
Le graphe d'import est propre et acyclique. Les managers (`eds_pseudo_manager`, `gliner_manager`, `camembert_ner_manager`, `vlm_manager`, `ner_manager_onnx`) sont des feuilles du graphe (n'importent rien de local).
|
||||
|
||||
### 4.7 Build Windows mature
|
||||
|
||||
- Signature Authenticode optionnelle
|
||||
- Inno Setup pour l'installateur
|
||||
- PyInstaller (onefile/onedir) + Nuitka
|
||||
- Workflows GitHub Actions pour le build automatique
|
||||
|
||||
---
|
||||
|
||||
## 5. Recommandations priorisées
|
||||
|
||||
### Priorité 1 — Sécurité (à faire immédiatement)
|
||||
|
||||
| # | Action | Effort | Impact |
|
||||
|---|---|---|---|
|
||||
| 1.1 | Remplacer `except Exception: pass` par `except Exception as e: log.warning(...)` sur les chemins critiques (rédaction PDF, rescan) | 2h | 🔴 Élimine le risque de fuite silencieuse |
|
||||
| 1.2 | Corriger le chemin absolu dans `.spec` (utiliser `Path(__file__).parent`) | 15min | 🔴 Build reproductible |
|
||||
| 1.3 | Ajouter un mécanisme de wipe des PII en mémoire après la rédaction PDF (`del anon.audit`) | 30min | 🟡 Conformité RGPD — dump mémoire |
|
||||
|
||||
### Priorité 2 — Nettoyage du code mort
|
||||
|
||||
| # | Action | Effort | Impact |
|
||||
|---|---|---|---|
|
||||
| 2.1 | Supprimer ou archiver les 3 GUI mortes (V3, V4, Robuste) | 30min | 🟡 Réduit la confusion |
|
||||
| 2.2 | Supprimer `anonymizer_core_refactored.py` ou le renommer `anonymizer_core_refactored_legacy.py` | 15min | 🟡 Évite l'import accidentel |
|
||||
| 2.3 | Déplacer les `test_*/` de la racine vers `tests/data/` | 30min | 🟡 Repository propre |
|
||||
| 2.4 | Supprimer `ano.zip`, `*.log` de la racine | 15min | 🟡 Hygiène |
|
||||
| 2.5 | Nettoyer les répertoires vides (`test_doctr_fix/`) | 10min | 🟡 Hygiène |
|
||||
|
||||
### Priorité 3 — Performance
|
||||
|
||||
| # | Action | Effort | Impact |
|
||||
|---|---|---|---|
|
||||
| 3.1 | Compiler les regex de `_mask_line_by_content` au niveau module (une seule fois) | 1h | 🟢 3-5x plus rapide sur gros documents |
|
||||
| 3.2 | Factoriser `_search_whole_word` pour appeler `get_text("words")` une seule fois par page | 2h | 🟢 Réduction significative du temps de redaction |
|
||||
| 3.3 | Extraire `_collect_rects_for_hits()` commune à vector/raster | 3h | 🟡 Réduit la duplication (~400 lignes → ~250) |
|
||||
|
||||
### Priorité 4 — Qualité et maintenance
|
||||
|
||||
| # | Action | Effort | Impact |
|
||||
|---|---|---|---|
|
||||
| 4.1 | Ajouter `pytest.ini` ou `pyproject.toml` avec config pytest | 30min | 🟡 Tests exécutables proprement |
|
||||
| 4.2 | Ajouter un workflow GitHub Actions pour les tests (pas juste le build) | 2h | 🟡 Non-régression automatique |
|
||||
| 4.3 | Ajouter `ruff` ou `flake8` dans la CI | 1h | 🟡 Qualité syntaxique |
|
||||
| 4.4 | Regrouper les ~40 magic numbers dans un bloc de constantes | 2h | 🟡 Configurable sans lire le code |
|
||||
| 4.5 | Unifier le nommage (tout en `snake_case`) | 4h | 🟡 Cohérence du projet |
|
||||
| 4.6 | Factoriser les 3 fonctions Aho-Corasick en une classe générique | 3h | 🟡 ~150 lignes de duplication éliminées |
|
||||
|
||||
### Priorité 5 — Alignement Linux/Windows
|
||||
|
||||
| # | Action | Effort | Impact |
|
||||
|---|---|---|---|
|
||||
| 5.1 | Faire pointer `install.sh` vers `launcher.py` au lieu de la GUI directement | 30min | 🟡 Expérience Linux identique à Windows |
|
||||
| 5.2 | Tester le pipeline complet sur Linux (pas juste Windows) | 4h | 🟡 Portabilité |
|
||||
|
||||
---
|
||||
|
||||
## 6. Métriques
|
||||
|
||||
| Métrique | Valeur |
|
||||
|---|---|
|
||||
| Lignes de code Python (hors venv) | ~14 270 |
|
||||
| Fichiers Python à la racine | 33 |
|
||||
| Fichiers Python morts estimés | ~6 (~2 000 lignes) |
|
||||
| Tests unitaires | 13 fichiers |
|
||||
| Documents ground truth | 27 |
|
||||
| Score qualité baseline | 97.0/100 [Grade A] |
|
||||
| `except Exception: pass` dans le core | ~20 |
|
||||
| Magic numbers dans le core | ~25 |
|
||||
| Versions de GUI coexistantes | 4 (1 active) |
|
||||
| Dépendances circulaires | 0 |
|
||||
| Fichiers `tools/` (scripts divers) | ~42 |
|
||||
| Workflows GitHub Actions | 2 (build uniquement) |
|
||||
|
||||
---
|
||||
|
||||
## 7. Rapport détaillé par domaine
|
||||
|
||||
### 7.1 Core (`anonymizer_core_refactored_onnx.py`)
|
||||
|
||||
**Fonctions trop longues :**
|
||||
|
||||
| Fonction | Lignes estimées | Complexité |
|
||||
|---|---|---|
|
||||
| `process_pdf` | ~200 | Très élevée : orchestration, regex, NER, rescan, nettoyage, whitelist, PDF |
|
||||
| `anonymise_document_regex` | ~180 | Très élevée : 10+ phases, logique NER-first, noms, tables |
|
||||
| `_extract_trackare_identity` | ~250 | Extrêmement élevée : 20+ patterns regex, nested functions |
|
||||
| `_mask_ville_gazetteers` | ~150 | Élevée : Aho-Corasick + énumérations + contexte géo + point fixe |
|
||||
| `redact_pdf_raster` | ~170 | Élevée : search, OCR, images, barcode, parallélisation |
|
||||
|
||||
**Code dupliqué :**
|
||||
|
||||
- `redact_pdf_vector` et `redact_pdf_raster` — structure quasi-identique (~200 lignes chacune), même pattern `by_page`, même déduplication, même fallback `_search_whole_word`
|
||||
- Regex multiline répétées (phase 0a à 0h-bis) — 8+ blocs identiques de pattern scanning
|
||||
- `_mask_finess_establishments`, `_mask_finess_addresses`, `_mask_ville_gazetteers` — 3 fonctions Aho-Corasick avec la même structure
|
||||
|
||||
**Types et annotations :** Aucune fonction n'a de type hints sur les paramètres ou le retour, à l'exception des dataclasses. Le type `cfg: Dict[str, Any]` est utilisé partout — un `TypedDict` ou dataclass rendrait le code auto-documenté.
|
||||
|
||||
**Imports inline :** Des `import re as _re`, `import numpy as np`, `from pyzbar.pyzbar import decode`, `from PIL import ImageFont` sont exécutés à l'intérieur de fonctions, parfois dans des boucles.
|
||||
|
||||
### 7.2 Architecture
|
||||
|
||||
**Graphe de dépendances :**
|
||||
|
||||
```
|
||||
launcher.py (point d'entrée Windows)
|
||||
|
|
||||
+-> anonymizer_core_refactored_onnx.py (CORE PRINCIPAL, 4 770 lignes)
|
||||
| +-> config_defaults.py
|
||||
| +-> admin_rules.py -> config_defaults.py
|
||||
| +-> detectors/hospital_filter.py
|
||||
| +-> ner_manager_onnx.py
|
||||
| +-> camembert_ner_manager.py
|
||||
| +-> eds_pseudo_manager.py
|
||||
| +-> gliner_manager.py
|
||||
| +-> vlm_manager.py
|
||||
|
|
||||
+-> Pseudonymisation_Gui_V5.py (GUI ACTIVE, 1 804 lignes)
|
||||
+-> anonymizer_core_refactored_onnx.py (déjà chargé)
|
||||
+-> ner_manager_onnx.py
|
||||
+-> eds_pseudo_manager.py
|
||||
+-> vlm_manager.py
|
||||
+-> config_defaults.py
|
||||
|
||||
server.py (API FastAPI, point d'entrée microservice)
|
||||
+-> anonymizer_core_refactored_onnx.py
|
||||
+-> config_defaults.py
|
||||
+-> tous les managers (try/except import)
|
||||
```
|
||||
|
||||
**Incohérences de nommage :**
|
||||
|
||||
| Convention | Fichiers concernés |
|
||||
|---|---|
|
||||
| `snake_case.py` | Majorité : `launcher.py`, `server.py`, `config_defaults.py`, etc. |
|
||||
| `PascalCase.py` | `Pseudonymisation_Gui_V5.py`, `Pseudonymisation_Gui_Models_V4.py`, `Pseudonymisation_Pipeline_Robuste_Patch.py` |
|
||||
|
||||
Le répertoire `Pseudonymiseur/` (majuscule, nom français) coexiste avec `ano/` (abréviation anglaise).
|
||||
|
||||
### 7.3 Tests
|
||||
|
||||
**Points forts :**
|
||||
|
||||
- Architecture de test à 4 couches bien documentée
|
||||
- 27 documents réels annotés manuellement — corpus sérieux
|
||||
- Manifest de regression synthétique avec critères `must_contain` / `must_not_contain`
|
||||
- Baseline de qualité enregistrée : score global 97.0/100
|
||||
|
||||
**Points faibles :**
|
||||
|
||||
- Pas de configuration pytest formelle (pas de `pytest.ini` ou `pyproject.toml`)
|
||||
- 3 fichiers de test flottent à la racine du projet au lieu d'être dans `tests/`
|
||||
- 42 fichiers dans `tools/` mêlant tests, analyses et utilitaires — pas de séparation claire
|
||||
- Pas de mesure de couverture de code (`pytest-cov` non configuré)
|
||||
- Pas de workflow CI pour les tests automatiques
|
||||
|
||||
### 7.4 Configuration
|
||||
|
||||
**Architecture saine :**
|
||||
|
||||
| Fichier | Rôle |
|
||||
|---|---|
|
||||
| `dictionnaires.default.yml` | Template versionné — whitelist, blacklist, regex_overrides, phrases préservées |
|
||||
| `dictionnaires.yml` | Surcharge locale — actuellement vide (`{}`) |
|
||||
| `profiles.default.yml` | 5 profils : standard_local, chuxx_strict, partage_recherche, dossier_audit, demo |
|
||||
| `profiles.yml` | Surcharge locale — 2 profils créés depuis la GUI |
|
||||
| `admin_rules.default.yml` | Règles administrables avec cycle de vie (draft/candidate/active) |
|
||||
| `admin_rules.yml` | Surcharge locale — vide (`rules: []`) |
|
||||
|
||||
**Point d'attention :** `admin_rules` n'est pas encore branché au pipeline principal — le fichier est un "contrat cible" pour un futur moteur.
|
||||
|
||||
### 7.5 CI/CD
|
||||
|
||||
**Workflows existants :**
|
||||
|
||||
| Workflow | Déclencheur | Environnement | Méthode |
|
||||
|---|---|---|---|
|
||||
| `build-windows.yml` | Tag `v*` ou manuel | `windows-latest`, Python 3.12 | Nuitka (standalone folder) |
|
||||
| `build-portable.yml` | Tag `v*` ou manuel | `windows-latest`, Python 3.12 | Python embarqué embeddable zip |
|
||||
|
||||
**Ce qui manque :**
|
||||
|
||||
- **Pas de workflow de test** (pas de `pytest` sur PR/push)
|
||||
- **Pas de linting** (pas de ruff, flake8, mypy)
|
||||
- **Pas de vérification de qualité** (pas de `evaluate_quality.py` dans la CI)
|
||||
- **Pas de build Linux** (uniquement Windows)
|
||||
- **Pas de vérification de sécurité** (dependabot, Trivy, etc.)
|
||||
|
||||
### 7.6 Régression
|
||||
|
||||
**Suite de regression :**
|
||||
|
||||
- 29 fichiers baseline dans `regression_tests/baseline/`
|
||||
- Script `check_regression.py` avec 7 types de fuites connues et 5 types de faux positifs identifiés
|
||||
|
||||
**Problème :** Le script utilise un **chemin absolu en dur** vers les sorties :
|
||||
```
|
||||
/home/dom/Téléchargements/II-1 Ctrl_T2A_2025_CHUXX_DocJustificatifs (1)/anonymise_audit_30
|
||||
```
|
||||
Ce chemin n'est pas portable.
|
||||
|
||||
### 7.7 `detectors/`
|
||||
|
||||
Un seul fichier : `detectors/hospital_filter.py`
|
||||
|
||||
La méthode `should_filter()` retourne **toujours `False``. Les coordonnées hospitalières ont été validées comme devant être masquées car elles identifient indirectement le patient (contrôle humain du 2026-03-12). Le filtre est donc essentiellement inactivé, sauf pour les épisodes Trackare via `filter_detections()`.
|
||||
|
||||
Ce répertoire semble être un emplacement prévu pour de futurs detecteurs mais qui n'a pas été étoffé.
|
||||
|
||||
---
|
||||
|
||||
## 8. Résumé exécutif
|
||||
|
||||
Le projet dispose d'une **bonne base conceptuelle** : pipeline d'anonymisation bien pensé, documentation de qualité professionnelle, corpus de test sérieux avec score de 97/100. L'architecture de configuration (default/overlay) et le graphe de dépendances (acyclique) sont propres.
|
||||
|
||||
Cependant, l'**évolution organique** a accumulé :
|
||||
|
||||
- Des **risques de sécurité** silencieux (`except: pass` sur les chemins critiques de rédaction PDF)
|
||||
- ~**2 000 lignes de code mort** (GUI V3/V4, core incomplet, patch obsolète)
|
||||
- Des **incohérences** de nommage et de build (PyInstaller vs Nuitka, chemins absolus)
|
||||
- Des **problèmes de performance** évitables (regex recompilées, appels N² à PyMuPDF)
|
||||
|
||||
**Les 3 actions prioritaires** qui apportent le plus de valeur immédiatement :
|
||||
|
||||
1. **Sécuriser les chemins critiques** : logguer les exceptions au lieu de les ignorer sur la rédaction PDF et le rescan
|
||||
2. **Nettoyer le code mort** : supprimer les GUI abandonnées et le core incomplet
|
||||
3. **Rendre le build reproductible** : corriger le chemin absolu dans le `.spec`
|
||||
|
||||
Ces 3 actions combinées représentent moins de 3h de travail et éliminent les risques les plus sérieux.
|
||||
Reference in New Issue
Block a user