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:
@@ -0,0 +1,167 @@
|
||||
# Pseudonymisation v11.0 — MVP livraison bêta Province Bêta
|
||||
|
||||
**Date** : 2026-06-02
|
||||
**Audience** : bêta-testeur Province Bêta
|
||||
**Build** : `13730d1` — 2026-05-29 (rebuild prévu dimanche 01/06)
|
||||
**Canal** : OwnCloud
|
||||
|
||||
---
|
||||
|
||||
## Nouveautés de cette version (par rapport à v10)
|
||||
|
||||
### 🔴 Sécurité RGPD — quarantaine différentielle (Q-1)
|
||||
|
||||
**Changement majeur** : un document n'est livré « anonymisé » que si **toutes** les étapes critiques ont réussi.
|
||||
|
||||
- **Quarantaine automatique** : les documents dont l'extraction de texte échoue, dont la rédaction PDF échoue, ou dont le rescan de sécurité détecte des PII résiduelles sont automatiquement isolés dans un dossier `quarantaine/`.
|
||||
- **Quarantaine partielle** : si le texte est correctement anonymisé mais que le PDF ne peut pas être rédigé (chiffrement, annotations corrompues), le texte `.pseudonymise.txt` sort normalement et le PDF va en quarantaine avec un fichier d'explication.
|
||||
- **Quarantaine totale** : si le texte extrait est inférieur à 100 caractères (document vide ou OCR raté), le document entier va en quarantaine — aucun fichier de sortie n'est généré.
|
||||
- **`quarantaine/INDEX.md`** : résumé lisible de tous les documents en quarantaine avec raisons et suggestions, généré à la fin de chaque batch.
|
||||
- **`errors.log`** : journal cumulatif de toutes les erreurs du batch, format JSON par ligne pour analyse.
|
||||
- **`<document>.log`** : log détaillé du traitement de chaque document (étapes, détections, warnings).
|
||||
|
||||
### Pré-flight texte vide (B-3)
|
||||
|
||||
- Avant tout traitement, le programme vérifie que le document contient au moins **100 caractères de texte extrait**. En dessous, le document est considéré comme non-OCRisé ou vide et envoyé directement en quarantaine.
|
||||
- Évite le scénario où un document scanné non-OCRisé sort « anonymisé » alors qu'aucun texte n'a été traité.
|
||||
|
||||
### Tolérance zéro PII résiduelles (rescan check)
|
||||
|
||||
- Après anonymisation, un **rescan de sécurité** vérifie l'absence de PII résiduelles (emails, téléphones, NIR, IBAN, noms INSEE en MAJUSCULES, FINESS, RPPS, etc.).
|
||||
- Si ≥ 1 PII résiduelle est détectée → le document va en **quarantaine totale** avec alerte.
|
||||
- Réutilise les patterns de détection de `evaluation/leak_scanner.py` (patterns complets et validés).
|
||||
|
||||
### Traçabilité — métadonnées de sortie (B-1)
|
||||
|
||||
- **XMP metadata** dans les PDF de sortie : version de l'application, commit SHA, profil appliqué, horodatage. Les métadonnées source du PDF (auteur, titre original) sont **explicitement effacées** pour éviter les fuites.
|
||||
- **Entrée `type=metadata`** en première ligne de chaque `.audit.jsonl` : version de l'app, commit, date de traitement, profil, flags de quarantaine.
|
||||
- Permet de prouver a posteriori avec quelle configuration un document a été anonymisé (audit DPO/CNIL).
|
||||
|
||||
### Fix détection — régression nom "GRAND" (C-8)
|
||||
|
||||
- Le nom de famille **GRAND** (INSEE valide, courant) était filtré à tort car le mot `"grand"` était présent dans la liste des stopwords médicaux.
|
||||
- **Fix** : `"grand"` retiré des stopwords. Les noms INSEE ambigus ne sont plus bloqués par le filtre stopwords.
|
||||
- Impact : 17 occurrences de "GRAND" non masquées corrigées sur le corpus de test audit_30.
|
||||
- 7 tests de non-régression ajoutés (`tests/unit/test_c8_grand_regression.py`).
|
||||
|
||||
---
|
||||
|
||||
## Corrections depuis v10 (changelog)
|
||||
|
||||
### Détection PII
|
||||
|
||||
| Commit | Description |
|
||||
|---|---|
|
||||
| `e0b526b` | Établissements multi-ligne, CHUXX en fin de phrase, ville après `[ETAB]` |
|
||||
| `c7e7107` | RPPS avec qualificateur (`RPPS prescripteur :`, `RPPS de garde :`) |
|
||||
| `7242b53` | Labels structurels Nom de jeune fille / Prénom / Ville |
|
||||
| `c24b7f6` | Quick wins : caractère ñ, numéro adhérent, NIR avant TEL |
|
||||
| `c3eb50b` | Masquer artefacts noms de fichiers DPI et variante BACTERIO N° venue |
|
||||
| `8e43d8d` | Accepter prénoms 3 chars après Dr/Mme (Ute, Eva, Léo…) |
|
||||
| `e2e2a7c` | Masquer tokens collés à ponctuation (`Douar,nécessitant`) |
|
||||
| `aa3db69` | RE_HOPITAL_VILLE accepte les ALL-CAPS (`CENTRE HOSPITALIER`) |
|
||||
| `51c7555` | Faux positifs pyzbar sur tableaux (carrés noirs sur dates/heures) |
|
||||
| `2f19f7c` | DR. Ute (3 chars), SAINT-GERMES composé, SODIUM MACO/BAX pharma |
|
||||
| `c157205` | Labels DPI masqués (Date, Note, Type, Heure) + whitelist désactivée |
|
||||
| `4d33610` | Cross-validation respecte bypass_stopwords pour noms forcés (Dr/Mme) |
|
||||
|
||||
### Architecture / Infrastructure
|
||||
|
||||
| Commit | Description |
|
||||
|---|---|
|
||||
| `df5dabf` | Admin rules branchées dans le pipeline ONNX |
|
||||
| `13730d1` | CLI `simulate_admin_rule` + fix email avant force_terms |
|
||||
| `8f6c462` | python-doctr rendu requis (OCR systématique) |
|
||||
| `6586b89` | Version + build date + commit affichés dans titre et status bar GUI |
|
||||
| `cf36357` | Couche 2 tests étendue à 10 cas + gate pytest avec xfail strict |
|
||||
|
||||
### Interface
|
||||
|
||||
| Commit | Description |
|
||||
|---|---|
|
||||
| `ab5a24f` | Refonte UI — logo aivanonym + palette magenta/pêche + onglets + v5.5 |
|
||||
| `0124457` | Étapes de chargement dans le splash natif PyInstaller |
|
||||
| `0a377bc` | Splash natif PyInstaller — couvre la décompression onefile |
|
||||
|
||||
### Configuration
|
||||
|
||||
| Commit | Description |
|
||||
|---|---|
|
||||
| `500ebc2` | Externalisation des dictionnaires (YAML, data/) |
|
||||
| `4b59253` | additional_stopwords exposés dans le panneau Paramètres avancés GUI |
|
||||
| `b5058b9` | GUI whitelist_phrases enfin lue et appliquée par le core |
|
||||
| `ea214db` | Nettoyage force_mask_terms — délégation aux gazetteers nationaux |
|
||||
|
||||
---
|
||||
|
||||
## Procédure d'utilisation
|
||||
|
||||
### Premier lancement
|
||||
|
||||
1. Décompresser l'archive ZIP dans `C:\Program Files\AIV Anonymisation\`
|
||||
2. Double-cliquer `Pseudonymisation.exe`
|
||||
3. **SmartScreen** : au premier lancement, Windows SmartScreen peut apparaître (application non signée). Cliquer **Informations complémentaires → Exécuter quand même**.
|
||||
- Voir `smartscreen-procedure.md` pour la procédure détaillée (Edge/Chrome/Firefox + DSI).
|
||||
|
||||
### Utilisation batch
|
||||
|
||||
1. Sélectionner un dossier source contenant les documents PDF
|
||||
2. Sélectionner un dossier de sortie (vide)
|
||||
3. Choisir un profil (standard_local par défaut) ou importer un profil JSON
|
||||
4. Cliquer **Anonymiser**
|
||||
5. À la fin du traitement :
|
||||
- Documents OK → `.pseudonymise.txt` + `.audit.jsonl` + `.redacted.pdf` dans le dossier de sortie
|
||||
- Documents en anomalie → dossier `quarantaine/` avec `INDEX.md` explicatif
|
||||
- Logs cumulatifs → `errors.log` dans le dossier de sortie
|
||||
|
||||
### En cas de quarantaine
|
||||
|
||||
1. Ouvrir le dossier `quarantaine/`
|
||||
2. Lire `INDEX.md` pour comprendre les raisons
|
||||
3. Lire les fichiers `.reason.txt` pour chaque document
|
||||
4. Ré-essayer manuellement si la raison le permet (ex: PDF chiffré → fournir version non chiffrée)
|
||||
|
||||
---
|
||||
|
||||
## Risques connus
|
||||
|
||||
| Risque | Impact | Mitigation |
|
||||
|---|---|---|
|
||||
| Pas de signature Authenticode | SmartScreen au premier lancement | Procédure documentée + SHA-256 fourni |
|
||||
| Performance sur très gros documents (>200 pages) | Temps de traitement long | Reporté v11.5 — pas de blocage fonctionnel |
|
||||
| OCR sur scans dégradés | Texte extrait insuffisant → quarantaine | Pré-flight détecte et isole automatiquement |
|
||||
| Faux positifs sur termes médicaux ambigus | Sur-masquage mineur | Whitelist manuelle configurable via GUI |
|
||||
|
||||
---
|
||||
|
||||
## Canal support post-livraison
|
||||
|
||||
- **Patches v11.X** via OwnCloud (correctifs critiques uniquement)
|
||||
- **Logs à envoyer en cas de bug** : zip du dossier `<sortie>/quarantaine/` + `errors.log` + profil utilisé
|
||||
- **Contact** : dbazin52@gmail.com
|
||||
|
||||
---
|
||||
|
||||
## Annexes
|
||||
|
||||
### Score qualité de référence
|
||||
|
||||
| Métrique | v10 | v11.0 | Cible |
|
||||
|---|---|---|---|
|
||||
| Score global | 97.0 | **99.8** | 100.0 |
|
||||
| Leak audit | 100.0 | 99.7 | 100.0 |
|
||||
| Leak regex | 100.0 | 100.0 | 100.0 |
|
||||
| FP score | 90.0 | **100.0** | 100.0 |
|
||||
|
||||
Documents testés : **audit_30** (29 documents, formats variés)
|
||||
|
||||
### Hash SHA-256
|
||||
|
||||
> *À fournir par Dom après rebuild EXE v11*
|
||||
|
||||
### Fichiers livrés
|
||||
|
||||
- `Pseudonymisation.exe` — exécutable Windows (PyInstaller onefile)
|
||||
- `config/profiles.yml` — profils par défaut (modifiables)
|
||||
- `config/dictionnaires.yml` — dictionnaires personnalisables
|
||||
- `smartscreen-procedure.md` — procédure de premier lancement
|
||||
@@ -0,0 +1,168 @@
|
||||
---
|
||||
from: qwen
|
||||
to: dom
|
||||
date: 2026-05-29T10:00:00+02:00
|
||||
topic: review-pseudocode-Q1-quarantaine
|
||||
status: open
|
||||
references:
|
||||
- file: inbox/for-dom/2026-05-29_claude_pseudocode-Q1-quarantaine.md
|
||||
- file: anonymizer_core_refactored_onnx.py
|
||||
- decision: decisions/2026-05-28_dom_no-ui-changes.md
|
||||
- decision: decisions/2026-05-28_dom_mvp-livraison-mardi.md
|
||||
priority: blocker
|
||||
---
|
||||
|
||||
# Review critique du pseudo-code Q-1 (rédigé par Claude)
|
||||
|
||||
## Contexte
|
||||
|
||||
Claude a rédigé le pseudo-code Q-1 en mon absence (Plan B). J'ai relu le fichier en détail et comparé avec le code source actuel. Voici ma review structurée.
|
||||
|
||||
---
|
||||
|
||||
## 1. Inventaire des `except: pass` — ✅ BON mais INCOMPLET
|
||||
|
||||
Claude en identifie **13** comme critiques. J'en ai compté **~40** `except Exception` dans le core, dont **~20 `pass` purs**. L'inventaire de Claude couvre les chemins de rédaction et d'extraction, mais **il manque des cas critiques sur le rescan et la propagation**.
|
||||
|
||||
### Cas manqués par Claude
|
||||
|
||||
| # | Fichier:ligne | Fonction | Contexte | Pourquoi critique |
|
||||
|---|---|---|---|---|
|
||||
| A | `:4291` | `process_pdf` | `selective_rescan()` | Le rescan de sécurité est dans un `try/except: pass`. Si le rescan rate, des PII résiduelles passent **sans vérification**. C'est le dernier garde-fou avant la sortie. → **Q-DOC** |
|
||||
| B | `:2720`-`2730` | `_mask_line_by_line` | Filtrage stopwords NER | Les tokens filtrés par stopwords sont silencieux. Si un nom INSEE est dans les stopwords (comme `grand` — voir analyse régression ci-dessous), il passe sans trace. → **L** (mais avec compteur de tokens filtrés) |
|
||||
| C | `:3857` | `_search_whole_word` | `page.get_text("words")` | Si `get_text("words")` échoue sur une page (PDF corrompu), les rectangles ne sont pas trouvés mais le PDF sort quand même. → **Q-PDF** |
|
||||
| D | `:4034` | `redact_pdf_raster` | `import re as _re` + OCR words | Bloc entier de traitement OCR/raster dans `try/except: pass`. Si le raster rate, le PDF de sortie n'a pas les masques raster. → **Q-PDF** |
|
||||
| E | `:1490` | `_mask_line_by_content` | Regex recompilées inline | Les `re.compile()` inline peuvent lever `re.error` sur des patterns mal formés. Actuellement silents. → **L** (warning + skip pattern) |
|
||||
|
||||
**Recommandation** : Ajouter A (rescan) et D (raster) comme **Q-PDF/Q-DOC** dans l'inventaire. B et C comme **L** avec compteur.
|
||||
|
||||
---
|
||||
|
||||
## 2. Mapping action L / Q-PDF / Q-DOC — ✅ PERTINENT avec réserves
|
||||
|
||||
### Décision A (texte Q-PDF : output_dir uniquement)
|
||||
|
||||
✅ **D'accord avec Claude.** Le texte sort dans `output_dir`, pas de doublon dans `quarantaine/`. L'`INDEX.md` fait le lien. Moins de confusion, un seul emplacement de vérité pour chaque artefact.
|
||||
|
||||
### Décision B (fallback raster si vector rate)
|
||||
|
||||
✅ **D'accord, mais avec une condition.** Si le vector rate et que le raster réussit :
|
||||
- Le PDF raster est généré (mais qualité moindre)
|
||||
- Le flag `partial` reste levé avec raison `pdf_vector_fallback_to_raster`
|
||||
- L'`INDEX.md` note que le PDF est en qualité raster (prévention opérateur)
|
||||
|
||||
C'est un compromis qualité/robustesse acceptable.
|
||||
|
||||
### Décision C (seuils 50/3)
|
||||
|
||||
⚠️ **À valider sur le corpus.** 50 caractères pour le pré-flight me semble **trop bas**. Un PDF d'une page avec juste un en-tête peut faire 50 chars et contenir des PII non détectées. Je proposerais :
|
||||
|
||||
- `SEUIL_TEXTE_MINI = 100` — sous ce seuil, c'est soit un PDF vide, soit un scan non-OCRisé
|
||||
- `SEUIL_RESCAN_RESIDUEL = 0` — tolérance zéro pour les PII résiduelles après rescan. Si le rescan en trouve ≥ 1 → quarantaine. Le seuil de 3 est trop permissif pour un objectif 99% RGPD.
|
||||
|
||||
### Ajout : seuil de confiance NER global
|
||||
|
||||
Manque un garde-fou sur la **confiance NER moyenne**. Si le NER retourne une confiance moyenne < 0.5 sur toutes les pages, c'est un signal que le modèle ne fonctionne pas sur ce document (format atypique, langue, etc.). → Flag quarantaine avec raison `ner_low_confidence`.
|
||||
|
||||
---
|
||||
|
||||
## 3. Structure dossier quarantaine — ✅ BONNE avec un ajustement
|
||||
|
||||
La structure proposée est bonne. Un ajustement :
|
||||
|
||||
**Ajouter `quarantaine/<docname>.pseudonymise.txt` en copie pour les Q-PDF (partial).**
|
||||
|
||||
Raison : si l'opérateur veut inspecter le texte d'un document dont le PDF a échoué, il ne devrait pas avoir à faire la navette entre `output_dir/` et `quarantaine/`. La quarantaine doit être **autoportante** — tout ce qui concerne un document en anomalie est dans un seul dossier.
|
||||
|
||||
Contre-argument de Claude (pas de doublon) : valide, mais la copie est cheap (texte) et la clarté opérationnelle prime.
|
||||
|
||||
---
|
||||
|
||||
## 4. Pseudo-code `process_pdf` — ✅ COUVERTURE BONNE
|
||||
|
||||
Le pseudo-code couvre les chemins principaux. **Deux gaps :**
|
||||
|
||||
### Gap 1 : pas de gestion du cas `used_ocr = True`
|
||||
|
||||
Quand l'OCR est activé (`used_ocr=True`), la confiance de l'OCR n'est pas vérifiée. docTR peut retourner un texte de très mauvaise qualité sur un scan flou. Il faudrait un flag `ocr_low_quality` si le ratio mots détectés / surface page est trop faible.
|
||||
|
||||
### Gap 2 : pas de gestion des tables
|
||||
|
||||
Les `tables_lines` extraites par PyMuPDF ne passent pas par le pré-flight. Si les tables sont vides mais que le texte principal est OK, le doc sort avec des tables non-anonymisées. → Ajouter un check `if tables_lines and sum(len(t) for t in tables_lines) == 0: log.warning("empty tables extracted")`.
|
||||
|
||||
---
|
||||
|
||||
## 5. B-1 Métadonnées — ✅ EXCELLENT
|
||||
|
||||
L'approche metadata dans `.audit.jsonl` + XMP PDF est la bonne. **Un ajout critique :**
|
||||
|
||||
⚠️ **Ne JAMAIS copier les métadonnées source du PDF dans la sortie.** Le pseudo-code de Claude le mentionne (§5.2), mais c'est à renforcer avec un `doc.metadata.clear()` explicite avant `doc.save()`. Les PDF Trackare/CHUXX contiennent souvent le nom du patient dans `author` ou `title`.
|
||||
|
||||
---
|
||||
|
||||
## 6. B-3 Pré-flight — ✅ BON avec seuil ajusté
|
||||
|
||||
Voir §2C ci-dessus. Je recommande `SEUIL_TEXTE_MINI = 100` au lieu de 50.
|
||||
|
||||
---
|
||||
|
||||
## 7. Helper `_count_residual_pii` — ⚠️ INSUFFISANT
|
||||
|
||||
La version de Claude ne couvre que EMAIL, TEL, NIR, IBAN, et noms INSEE. **Il manque :**
|
||||
|
||||
- FINESS (8-9 chiffres)
|
||||
- IPP (alphanumérique)
|
||||
- OGC (format spécifique)
|
||||
- Dates de naissance
|
||||
- Adresses (pattern Rue + CP + Ville)
|
||||
- RPPS (10 chiffres)
|
||||
|
||||
**Recommandation** : réutiliser les regex du leak_scanner (`evaluation/leak_scanner.py`) qui sont déjà complètes. Pas de réinvention.
|
||||
|
||||
---
|
||||
|
||||
## 8. Tests — ✅ LES TESTS XFAIL EXISTENT
|
||||
|
||||
Claude mentionne `test_q1_quarantine.py` avec 10 tests xfail. Je les ai vus dans `tests/unit/`. Bonne base.
|
||||
|
||||
**Tests manquants à ajouter :**
|
||||
|
||||
1. `test_quarantine_index_md_format` — vérifier que INDEX.md est bien généré avec le bon format
|
||||
2. `test_errors_log_json_lines` — vérifier que chaque ligne de errors.log est un JSON valide
|
||||
3. `test_doc_log_per_document` — vérifier que chaque doc a son fichier .log
|
||||
4. `test_xmp_metadata_no_source_leak` — vérifier que les métadonnées PDF source ne sont pas copiées
|
||||
5. `test_preflight_text_too_short_boundary` — tester à 49, 50, 51, 100 chars
|
||||
|
||||
---
|
||||
|
||||
## 9. Résumé des décisions pour Dom
|
||||
|
||||
| Décision | Proposition Claude | Avis Qwen | Recommandation finale |
|
||||
|---|---|---|---|
|
||||
| A — Texte Q-PDF | output_dir uniquement | ✅ D'accord | output_dir uniquement |
|
||||
| B — Fallback raster | Oui, si vector rate | ✅ D'accord, avec flag | Oui, flag `pdf_vector_fallback_to_raster` |
|
||||
| C — Seuil texte mini | 50 chars | ⚠️ Trop bas | **100 chars** |
|
||||
| C — Seuil rescan | 3 PII résiduelles | ⚠️ Trop permissif | **0 PII résiduelles** (tolérance zéro) |
|
||||
| D — Copie texte en quarantaine | Non | ⚠️ D'accord partiel | **Oui, copie pour autoportance** |
|
||||
| E — Inventaire except:pass | 13 cas | ⚠️ Incomplet | **+5 cas manqués** (rescan, raster, stopwords, search, regex inline) |
|
||||
| F — Métadonnées source PDF | Ne pas copier | ✅ D'accord | **+ clear explicite des metadata source** |
|
||||
|
||||
---
|
||||
|
||||
## 10. Ordre de travail révisé
|
||||
|
||||
1. **Matin** : `quarantine.py` + 5 cas manquants dans l'inventaire — 1h30
|
||||
2. **Matin** : `redact_pdf_vector:3938` raise au lieu de pass — 30 min
|
||||
3. **Matin** : `process_pdf:4655` try/flag — 1h
|
||||
4. **Matin** : Pré-flight B-3 (seuil 100) — 30 min
|
||||
5. **Après-midi** : Rescan check + `_count_residual_pii` (réutiliser leak_scanner) — 1h30
|
||||
6. **Après-midi** : XMP metadata + clear source — 30 min
|
||||
7. **Après-midi** : Metadata `.audit.jsonl` — 30 min
|
||||
8. **Après-midi** : DocLogger — 30 min
|
||||
9. **Soir** : Tests — 2h
|
||||
|
||||
**Total estimé : ~8h** (au lieu de 4-6h initiales — le gap vient des 5 cas manquants).
|
||||
|
||||
---
|
||||
|
||||
— Qwen
|
||||
276
docs/coordination/inbox/for-dom/2026-05-29_qwen_smoke-test-T6.md
Normal file
276
docs/coordination/inbox/for-dom/2026-05-29_qwen_smoke-test-T6.md
Normal file
@@ -0,0 +1,276 @@
|
||||
# Kit de smoke test -- Beta-testeur v11.0
|
||||
|
||||
**Date** : 29 mai 2026
|
||||
**Version** : Pseudonymisation v11.0
|
||||
**Audience** : beta-testeur (non technique)
|
||||
**Objet** : verifier que l'anonymisation fonctionne correctement avant mise en production
|
||||
|
||||
---
|
||||
|
||||
## 1. Specification du PDF de test synthetique
|
||||
|
||||
Le PDF de test doit etre un document d'1 a 3 pages qui ressemble a un compte-rendu medical courant (compte-rendu d'hospitalisation, lettre de liaison, ou compte-rendu de consultation). Il doit contenir **deliberement** les donnees personnelles listees ci-dessous, placees dans des contextes realistes.
|
||||
|
||||
### 1.1 Donnees obligatoires a inclure
|
||||
|
||||
| # | Type de donnee | Exemple exact a inserer | Attendu apres anonymisation |
|
||||
|---|---|---|---|
|
||||
| 1 | **Nom de medecin** (titre + NOM en majuscules) | `DR. MARTIN` | `DR. [NOM]` |
|
||||
| 2 | **Nom de patiente** (titre civilite + NOM) | `MME DUPONT` | `MME [NOM]` |
|
||||
| 3 | **Date de naissance** | `nee le 14/03/1985` ou `Date de naissance : 14/03/1985` | `nee le [DATE]` ou `Date de naissance : [DATE]` |
|
||||
| 4 | **NIR** (13 chiffres + cle 2 chiffres, espaces acceptes) | `1 85 03 75 108 042 37` | `[NIR]` |
|
||||
| 5 | **Telephone** (format francais avec espaces) | `01 42 68 53 17` ou `06 12 34 56 78` | `[TEL]` |
|
||||
| 6 | **Email** | `jean.martin@chu-reunion.fr` | `[EMAIL]` |
|
||||
| 7 | **FINESS** (9 chiffres avec label) | `FINESS : 123450123` | `[FINESS]` |
|
||||
| 8 | **Etablissement** (nom complet) | `CENTRE HOSPITALIER UNIVERSITAIRE DE LA REUNION` | `[ETABLISSEMENT]` ou masque selon profil |
|
||||
| 9 | **Adresse complete** (numero + voie + ville + CP) | `12 rue de la Republique, 12345 Springfield` | `[ADRESSE]` |
|
||||
|
||||
### 1.2 Donnees supplementaires recommandees
|
||||
|
||||
| # | Type | Exemple | Attendu |
|
||||
|---|---|---|---|
|
||||
| 10 | **IPP** (identifiant patient) | `IPP : 1234512345` | `[IPP]` |
|
||||
| 11 | **RPPS** (numero medecin, 11 chiffres) | `RPPS : 10000234567` | `[RPPS]` |
|
||||
| 12 | **IBAN** | `FR76 3000 2005 0000 0123 4567 890` | `[IBAN]` |
|
||||
| 13 | **Nom compose** (trait d'union) | `M. DURAND-MARTIN` | `M. [NOM]` ou `[NOM]-[NOM]` |
|
||||
| 14 | **Nom INSEE ambigu** (test fix "GRAND") | `DR. GRAND` ou `BILLON-GRAND Sylvie` | `DR. [NOM]` / `[NOM]-[NOM] Sylvie` |
|
||||
| 15 | **Deuxieme email** (dans un contexte different) | `Contact : secretariat@hopital.fr` | `Contact : [EMAIL]` |
|
||||
|
||||
### 1.3 Conseils de creation du PDF
|
||||
|
||||
- **Ne pas** faire un PDF scanne (image) -- utiliser un PDF textuel genere depuis un traitement de texte (Word, LibreOffice, Google Docs).
|
||||
- Repartir les PII sur **au moins 2 pages** differentes pour valider la propagation globale (un nom detecte page 1 doit etre masque page 2).
|
||||
- Inclure au moins un paragraphe de texte medical banal entre les PII (ex : « Le patient presente une hypertension arterielle moderee. Traitement propose : Amlodipine 5 mg. ») pour verifier que le texte medical n'est **pas** masque par erreur.
|
||||
- Le document doit contenir **au moins 200 caracteres de texte** (hors PII) pour ne pas etre place en quarantaine automatiquement.
|
||||
|
||||
### 1.4 Exemple de squelette de document
|
||||
|
||||
```
|
||||
COMPTE RENDU D'HOSPITALISATION
|
||||
|
||||
Patient : MME DUPONT Marie
|
||||
Nee le : 14/03/1985
|
||||
NIR : 1 85 03 75 108 042 37
|
||||
IPP : 1234512345
|
||||
Adresse : 12 rue de la Republique, 12345 Springfield
|
||||
Telephone : 06 12 34 56 78
|
||||
Email : marie.dupont@email.fr
|
||||
|
||||
Medecin traitant : DR. MARTIN Philippe
|
||||
RPPS : 10000234567
|
||||
Email : jean.martin@chu-reunion.fr
|
||||
|
||||
Etablissement : CENTRE HOSPITALIER UNIVERSITAIRE DE LA REUNION
|
||||
FINESS : 123450123
|
||||
Adresse : 12 rue de la Republique, 12345 Springfield
|
||||
|
||||
---
|
||||
|
||||
Motif d'hospitalisation :
|
||||
La patiente MME DUPONT a ete admise le 20/05/2026 pour des douleurs
|
||||
thoraciques recurrentes. Antecedents : hypertension arterielle,
|
||||
diabete de type 2.
|
||||
|
||||
DR. GRAND a realise un ECG qui ne montre pas d'anomalie particuliere.
|
||||
Le Dr BILLON-GRAND Sylvie a complete l'examen clinique.
|
||||
|
||||
Traitement prescrit :
|
||||
- Amlodipine 5 mg, 1 comprime par jour
|
||||
- Metformine 1000 mg, matin et soir
|
||||
|
||||
Rendez-vous de controle prevu le 15/06/2026.
|
||||
Contacter le secretariat au 01 42 68 53 17 ou par email a
|
||||
secretariat@chu-reunion.fr.
|
||||
|
||||
IBAN pour la facturation : FR76 3000 2005 0000 0123 4567 890
|
||||
|
||||
Dr MARTIN Philippe
|
||||
Centre Hospitalier Universitaire de la Reunion
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Procedure de validation manuelle
|
||||
|
||||
### 2.1 Preparation
|
||||
|
||||
1. Installer le logiciel selon la procedure fournie (decompression + premier lancement).
|
||||
2. Creer un dossier de test vide sur le bureau, par exemple `C:\TestsBeta\Sortie\`.
|
||||
3. Placer le PDF de test decrit ci-dessus dans un dossier source, par exemple `C:\TestsBeta\Source\`.
|
||||
|
||||
### 2.2 Lancement
|
||||
|
||||
1. Ouvrir l'application **Pseudonymisation**.
|
||||
2. Dans le panneau **Dossier source**, selectionner `C:\TestsBeta\Source\`.
|
||||
3. Dans le panneau **Dossier de sortie**, selectionner `C:\TestsBeta\Sortie\`.
|
||||
4. Laisser le profil sur **standard_local** (par defaut).
|
||||
5. Cliquer sur le bouton **Anonymiser**.
|
||||
6. Attendre la fin du traitement (indicateur de progression).
|
||||
|
||||
### 2.3 Verification des fichiers produits
|
||||
|
||||
Une fois le traitement termine, ouvrir le dossier de sortie (`C:\TestsBeta\Sortie\`).
|
||||
|
||||
**Ce que vous devez trouver :**
|
||||
|
||||
| Fichier | Description |
|
||||
|---|---|
|
||||
| `mon_test.pseudonymise.txt` | Texte complet du document avec les PII remplaces par des balises |
|
||||
| `mon_test.audit.jsonl` | Journal d'audit (une ligne par PII detectee) |
|
||||
| `mon_test.redacted.pdf` | PDF caviarde (zones sensibles masquee par des rectangles noirs) |
|
||||
| `mon_test.log` | Journal detaille du traitement |
|
||||
|
||||
**Ce que vous ne devez PAS trouver (si tout va bien) :**
|
||||
|
||||
- Pas de dossier `quarantaine/` -- il ne doit apparaitre que si un document a pose probleme.
|
||||
|
||||
### 2.4 Verification du contenu anonymise
|
||||
|
||||
Ouvrir le fichier `mon_test.pseudonymise.txt` et verifier point par point :
|
||||
|
||||
1. **Aucun** des noms, emails, telephones, NIR, adresses, FINESS, etc. du document original n'apparait en clair.
|
||||
2. A la place, vous voyez des balises comme `[NOM]`, `[TEL]`, `[EMAIL]`, `[NIR]`, `[ADRESSE]`, `[FINESS]`, `[DATE]`, etc.
|
||||
3. Le texte medical normal (diagnostics, traitements, observations) est **conserve intact** -- seules les donnees personnelles sont remplacees.
|
||||
4. Si un nom apparaissait sur plusieurs pages dans le document original, il est masque sur **toutes** les pages.
|
||||
|
||||
### 2.5 Verification du PDF caviarde
|
||||
|
||||
1. Ouvrir `mon_test.redacted.pdf` dans un lecteur PDF classique.
|
||||
2. Les zones contenant des PII doivent etre recouvertes de **rectangles noirs**.
|
||||
3. Le reste du document (texte medical, mise en page) doit etre lisible.
|
||||
|
||||
### 2.6 En cas de quarantaine
|
||||
|
||||
Si un dossier `quarantaine/` est apparu dans le dossier de sortie :
|
||||
|
||||
1. Ouvrir le fichier `quarantaine/INDEX.md` avec un editeur de texte (Bloc-notes).
|
||||
2. Ce fichier indique **quels documents** ont ete places en quarantaine et **pourquoi**.
|
||||
3. Chaque document en quarantaine a son propre fichier `.reason.txt` qui explique le probleme en langage lisible.
|
||||
4. **Action recommandee** : noter la raison et envoyer les fichiers de quarantaine au support pour analyse.
|
||||
|
||||
---
|
||||
|
||||
## 3. Checklist OK / KO
|
||||
|
||||
Cochez chaque case apres execution. Une seule case KO = le test est considere comme **echoue**.
|
||||
|
||||
### Fichiers de sortie
|
||||
|
||||
- [ ] Le fichier `.pseudonymise.txt` existe dans le dossier de sortie
|
||||
- [ ] Le fichier `.audit.jsonl` existe dans le dossier de sortie
|
||||
- [ ] Le fichier `.redacted.pdf` existe dans le dossier de sortie
|
||||
- [ ] Le fichier `.log` existe dans le dossier de sortie
|
||||
- [ ] Aucun dossier `quarantaine/` n'a ete cree (pour un document valide)
|
||||
|
||||
### Detection des PII (dans le .pseudonymise.txt)
|
||||
|
||||
- [ ] `DR. MARTIN` → masque en `DR. [NOM]` (ou equivalent)
|
||||
- [ ] `MME DUPONT` → masque en `MME [NOM]` (ou equivalent)
|
||||
- [ ] La date de naissance `14/03/1985` → masque en `[DATE]`
|
||||
- [ ] Le NIR `1 85 03 75 108 042 37` → masque en `[NIR]`
|
||||
- [ ] Le telephone `06 12 34 56 78` → masque en `[TEL]`
|
||||
- [ ] L'email `jean.martin@chu-reunion.fr` → masque en `[EMAIL]`
|
||||
- [ ] Le FINESS `123450123` → masque en `[FINESS]`
|
||||
- [ ] L'adresse `12 rue de la Republique, 12345 Springfield` → masque en `[ADRESSE]`
|
||||
- [ ] Le nom compose `DURAND-MARTIN` → masque (pas en clair)
|
||||
- [ ] `DR. GRAND` → masque en `DR. [NOM]` (fix regression v11)
|
||||
- [ ] `BILLON-GRAND` → masque (pas de fuite du mot "GRAND")
|
||||
- [ ] L'IPP `1234512345` → masque en `[IPP]`
|
||||
- [ ] Le RPPS `10000234567` → masque en `[RPPS]`
|
||||
- [ ] L'IBAN → masque en `[IBAN]`
|
||||
|
||||
### Qualite du resultat
|
||||
|
||||
- [ ] Le texte medical non sensible est conserve intact (pas de sur-masquage)
|
||||
- [ ] La propagation globale fonctionne : un nom masque page 1 l'est aussi page 2
|
||||
- [ ] Le PDF caviarde est lisible (rectangles noirs sur les zones sensibles)
|
||||
- [ ] Aucune donnee personnelle du document original n'apparait en clair dans le fichier de sortie
|
||||
|
||||
### Resultat global
|
||||
|
||||
| Critere | Statut |
|
||||
|---|---|
|
||||
| Tous les fichiers de sortie produits | OK / KO |
|
||||
| Tous les PII masques | OK / KO |
|
||||
| Aucun faux positif majeur | OK / KO |
|
||||
| PDF caviarde lisible | OK / KO |
|
||||
| Pas de quarantaine inattendue | OK / KO |
|
||||
| **TEST GLOBAL** | **REUSSI / ECHOUE** |
|
||||
|
||||
---
|
||||
|
||||
## 4. Cas de test "erreur attendue" -- Document en quarantaine
|
||||
|
||||
Ce cas de test verifie que le systeme de **quarantaine differentielle** (nouveau en v11.0) fonctionne correctement : un document qui ne peut pas etre traite correctement ne doit **pas** sortir comme "anonymise" sans signal d'alerte.
|
||||
|
||||
### 4.1 Comment creer un PDF qui DOIT aller en quarantaine
|
||||
|
||||
**Methode 1 -- Document vide ou quasi-vide (pre-flight) :**
|
||||
|
||||
1. Creer un PDF qui ne contient que **quelques caracteres** (moins de 100).
|
||||
- Exemple : un PDF avec juste le mot `Test` ou un logo image sans texte extractible.
|
||||
- Depuis Word : taper 3 mots, exporter en PDF.
|
||||
2. Ce PDF va etre detecte comme "texte insuffisant" et place en quarantaine automatique.
|
||||
3. **Resultat attendu :**
|
||||
- Pas de fichier `.pseudonymise.txt` en sortie
|
||||
- Pas de fichier `.redacted.pdf` en sortie
|
||||
- Un dossier `quarantaine/` est cree avec un fichier `nom_du_doc.reason.txt` indiquant `preflight_text_too_short`
|
||||
- Le fichier `quarantaine/INDEX.md` liste ce document avec la raison
|
||||
|
||||
**Methode 2 -- PDF avec image uniquement (scan non-OCRise) :**
|
||||
|
||||
1. Prendre une photo d'un document medical avec un telephone.
|
||||
2. L'inserer dans Word sans ajouter de texte.
|
||||
3. Exporter en PDF.
|
||||
4. Ce PDF est une **image pure** -- si l'OCR ne parvient pas a extraire au moins 100 caracteres, le document va en quarantaine.
|
||||
5. **Resultat attendu :** meme resultat que Methode 1.
|
||||
|
||||
**Methode 3 -- PDF chiffre (protection par mot de passe) :**
|
||||
|
||||
1. Creer un PDF normal avec des PII (comme le document de test ci-dessus).
|
||||
2. Le proteger par un mot de passe via Word ou un outil PDF (interdire l'extraction de texte).
|
||||
3. **Resultat attendu :**
|
||||
- Soit le texte est quand meme extrait et le document est traite normalement
|
||||
- Soit l'extraction echoue et le document va en quarantaine avec la raison `extraction_total_failure`
|
||||
|
||||
### 4.2 Verification de la quarantaine
|
||||
|
||||
Apres avoir traite l'un des documents ci-dessus :
|
||||
|
||||
- [ ] Le dossier `quarantaine/` existe dans le dossier de sortie
|
||||
- [ ] Le fichier `quarantaine/INDEX.md` existe et contient le nom du document teste
|
||||
- [ ] Le fichier `quarantaine/<nom>.reason.txt` existe et explique la raison (lisible en langage clair)
|
||||
- [ ] Le fichier `.reason.txt` contient :
|
||||
- [ ] Le type de probleme (ex : `preflight_text_too_short`)
|
||||
- [ ] L'horodatage du traitement
|
||||
- [ ] Une suggestion d'action pour l'operateur
|
||||
- [ ] Aucun fichier `.pseudonymise.txt` ou `.redacted.pdf` n'a ete genere pour ce document dans le dossier de sortie principal
|
||||
- [ ] Le fichier `errors.log` existe dans le dossier de sortie (journal cumulatif des erreurs)
|
||||
|
||||
### 4.3 Exemple de fichier .reason.txt attendu
|
||||
|
||||
```
|
||||
Document : doc_vide
|
||||
Sévérité : full (le document entier a été placé en quarantaine)
|
||||
Raison : preflight_text_too_short
|
||||
Détail : Seulement 12 caracteres extraits (seuil minimum = 100)
|
||||
Horodatage : 2026-05-30T14:32:11+02:00
|
||||
Version code : 0.11.0
|
||||
Caractères extraits : 12
|
||||
Suggestion opérateur : Verifier que le document contient du texte extractible.
|
||||
Si c'est un scan, verifier que l'OCR est active.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Resume rapide pour le beta-testeur
|
||||
|
||||
| Action | Ce qu'il faut faire | Ce qu'il faut verifier |
|
||||
|---|---|---|
|
||||
| **Test normal** | Anonymiser le PDF de test (section 1) | Tous les PII sont masques, 3 fichiers de sortie produits |
|
||||
| **Test quarantaine** | Anonymiser un PDF vide ou image (section 4) | Le dossier `quarantaine/` est cree avec explication |
|
||||
| **En cas de probleme** | Envoyer au support | Le dossier `quarantaine/` complet + `errors.log` + profil utilise |
|
||||
|
||||
---
|
||||
|
||||
*Document genere le 29/05/2026 pour la beta v11.0 -- Pseudonymisation de documents medicaux*
|
||||
Reference in New Issue
Block a user