From 93338b6b72aaa3d57550fa9129ee2f2c8791fa47 Mon Sep 17 00:00:00 2001 From: Domi31tls Date: Mon, 27 Apr 2026 20:46:22 +0200 Subject: [PATCH] =?UTF-8?q?test(review):=20=C3=A9tendre=20couche=202=20?= =?UTF-8?q?=C3=A0=2010=20cas=20et=20brancher=20gate=20pytest=20avec=20xfai?= =?UTF-8?q?l=20strict?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Couche 2 (revue humaine sur documents complets) : ajout de 6 cas synthétiques pour atteindre la cible cadrage produit (10 cas). Cas ajoutés : - 005_bacterio_complete : layout BACTERIO N° venue rejeté avant IPP + RPPS prescripteur (pattern qualifié non détecté). - 006_trackare_soignants : export Trackare avec activités HH:MM NOM, Note IDE/médicale, Signé — médicament greedy. - 007_lettre_sortie_complete : courrier médecin→médecin, multi-villes, email institutionnel @chcb.fr (cassé par le force_term CHCB). - 008_anesthesie_complete : protocole anesthésique avec molécules BDPM, prénoms basques rares (Maddi, Pantxoa). - 009_multi_etablissements : 3 établissements distincts (CHCB, CHU Bordeaux, Clinique Aguilera), prénoms basques avec ñ (Beñat). - 010_fiche_admission_minimale : fiche administrative dense, labels variés (Nom de jeune fille :, Prénom :, Ville :, Mutuelle :). Gate pytest (tests/unit/test_synthetic_review.py) : - vérifie l'inventaire (10 cas) et fait passer chaque cas via run_case. - 3 cas marqués xfail(strict=True) pour révéler 9 fuites de PII et 2 patterns partiels que le moteur ne couvre pas aujourd'hui : * 005 — RPPS avec qualificateur (RPPS prescripteur :) * 009 — Bordeaux résiduel après [ETAB], CHCB en fin de phrase, Biarritz sur ligne Ville :, ñ qui casse Beñat → [NOM]ñat * 010 — Nom de jeune fille / Prénom / Ville sans label "Patient :", NIR au format espacé partiellement consommé en TEL, numéro de mutuelle MGEN non couvert - xfail strict force pytest à signaler un xpass quand un fix passe : rappel automatique de retirer l'entrée de KNOWN_FAILURES. Le runner tools/run_synthetic_review_corpus.py reste utilisable en direct (sortie diff/audit/summary) pour la revue humaine. Les sorties actual/ sont gitignorées (régénérées à chaque exécution). Co-Authored-By: Claude Opus 4.7 (1M context) --- tests/synthetic_review/.gitignore | 2 + .../005_bacterio_complete/expectations.json | 32 +++++++ .../cases/005_bacterio_complete/expected.txt | 30 +++++++ .../cases/005_bacterio_complete/review.md | 34 ++++++++ .../cases/005_bacterio_complete/test.txt | 30 +++++++ .../006_trackare_soignants/expectations.json | 44 ++++++++++ .../cases/006_trackare_soignants/expected.txt | 39 +++++++++ .../cases/006_trackare_soignants/review.md | 43 ++++++++++ .../cases/006_trackare_soignants/test.txt | 39 +++++++++ .../expectations.json | 48 +++++++++++ .../007_lettre_sortie_complete/expected.txt | 42 +++++++++ .../007_lettre_sortie_complete/review.md | 52 ++++++++++++ .../cases/007_lettre_sortie_complete/test.txt | 42 +++++++++ .../008_anesthesie_complete/expectations.json | 46 ++++++++++ .../008_anesthesie_complete/expected.txt | 51 +++++++++++ .../cases/008_anesthesie_complete/review.md | 36 ++++++++ .../cases/008_anesthesie_complete/test.txt | 51 +++++++++++ .../expectations.json | 45 ++++++++++ .../009_multi_etablissements/expected.txt | 37 ++++++++ .../cases/009_multi_etablissements/review.md | 37 ++++++++ .../cases/009_multi_etablissements/test.txt | 41 +++++++++ .../expectations.json | 43 ++++++++++ .../010_fiche_admission_minimale/expected.txt | 40 +++++++++ .../010_fiche_admission_minimale/review.md | 36 ++++++++ .../010_fiche_admission_minimale/test.txt | 40 +++++++++ tests/unit/test_synthetic_review.py | 85 +++++++++++++++++++ 26 files changed, 1065 insertions(+) create mode 100644 tests/synthetic_review/.gitignore create mode 100644 tests/synthetic_review/cases/005_bacterio_complete/expectations.json create mode 100644 tests/synthetic_review/cases/005_bacterio_complete/expected.txt create mode 100644 tests/synthetic_review/cases/005_bacterio_complete/review.md create mode 100644 tests/synthetic_review/cases/005_bacterio_complete/test.txt create mode 100644 tests/synthetic_review/cases/006_trackare_soignants/expectations.json create mode 100644 tests/synthetic_review/cases/006_trackare_soignants/expected.txt create mode 100644 tests/synthetic_review/cases/006_trackare_soignants/review.md create mode 100644 tests/synthetic_review/cases/006_trackare_soignants/test.txt create mode 100644 tests/synthetic_review/cases/007_lettre_sortie_complete/expectations.json create mode 100644 tests/synthetic_review/cases/007_lettre_sortie_complete/expected.txt create mode 100644 tests/synthetic_review/cases/007_lettre_sortie_complete/review.md create mode 100644 tests/synthetic_review/cases/007_lettre_sortie_complete/test.txt create mode 100644 tests/synthetic_review/cases/008_anesthesie_complete/expectations.json create mode 100644 tests/synthetic_review/cases/008_anesthesie_complete/expected.txt create mode 100644 tests/synthetic_review/cases/008_anesthesie_complete/review.md create mode 100644 tests/synthetic_review/cases/008_anesthesie_complete/test.txt create mode 100644 tests/synthetic_review/cases/009_multi_etablissements/expectations.json create mode 100644 tests/synthetic_review/cases/009_multi_etablissements/expected.txt create mode 100644 tests/synthetic_review/cases/009_multi_etablissements/review.md create mode 100644 tests/synthetic_review/cases/009_multi_etablissements/test.txt create mode 100644 tests/synthetic_review/cases/010_fiche_admission_minimale/expectations.json create mode 100644 tests/synthetic_review/cases/010_fiche_admission_minimale/expected.txt create mode 100644 tests/synthetic_review/cases/010_fiche_admission_minimale/review.md create mode 100644 tests/synthetic_review/cases/010_fiche_admission_minimale/test.txt create mode 100644 tests/unit/test_synthetic_review.py diff --git a/tests/synthetic_review/.gitignore b/tests/synthetic_review/.gitignore new file mode 100644 index 0000000..5c45cd1 --- /dev/null +++ b/tests/synthetic_review/.gitignore @@ -0,0 +1,2 @@ +# Sorties régénérées à chaque exécution du runner couche 2. +actual/ diff --git a/tests/synthetic_review/cases/005_bacterio_complete/expectations.json b/tests/synthetic_review/cases/005_bacterio_complete/expectations.json new file mode 100644 index 0000000..cb0f63d --- /dev/null +++ b/tests/synthetic_review/cases/005_bacterio_complete/expectations.json @@ -0,0 +1,32 @@ +{ + "required_kinds": [ + "ETAB", + "IPP", + "NDA", + "RPPS", + "TEL", + "VILLE" + ], + "must_contain": [ + "Service de néphrologie", + "prise en charge", + "Escherichia coli", + "Antibiogramme", + "Amoxicilline", + "Céfotaxime", + "Ciprofloxacine" + ], + "must_not_contain": [ + "LARRALDE", + "MARIE-PIERRE", + "DUHALDE", + "2300451267", + "DEF98765", + "10101010101", + "18/06/1972", + "05 59 44 35 35", + "CHCB", + "COTE BASQUE", + "Bayonne" + ] +} diff --git a/tests/synthetic_review/cases/005_bacterio_complete/expected.txt b/tests/synthetic_review/cases/005_bacterio_complete/expected.txt new file mode 100644 index 0000000..73368c1 --- /dev/null +++ b/tests/synthetic_review/cases/005_bacterio_complete/expected.txt @@ -0,0 +1,30 @@ +[ETABLISSEMENT] +Laboratoire de bactériologie +[VILLE], le 03/04/2024 + +RESULTAT D'EXAMEN BACTERIOLOGIQUE + +N° venue +[DATE_NAISSANCE] +[NOM] [NOM] +[NDA] +IPP : [IPP] +RPPS prescripteur : [RPPS] + +Prélèvement : ECBU +Date de prélèvement : 02/04/2024 à 08h30 +Service prescripteur : Service de néphrologie + +Examen direct : leucocytes nombreux, hématies rares. +Culture : Escherichia coli >100 000 UFC/mL. + +Antibiogramme : +- Amoxicilline : R +- Céfotaxime : S +- Ciprofloxacine : S + +Conclusion : infection urinaire à Escherichia coli sensible aux céphalosporines. +La prise en charge thérapeutique relève de l'antibiothérapie ciblée. + +Validé par [NOM], biologiste médicale. +Tel laboratoire : [TEL] diff --git a/tests/synthetic_review/cases/005_bacterio_complete/review.md b/tests/synthetic_review/cases/005_bacterio_complete/review.md new file mode 100644 index 0000000..3ef4842 --- /dev/null +++ b/tests/synthetic_review/cases/005_bacterio_complete/review.md @@ -0,0 +1,34 @@ +# Revue 005 — résultat bactériologique + +Famille documentaire : résultat d'examen biologique avec entête multi-ligne +typique du laboratoire (N° venue, DDN, nom, NDA, IPP empilés sans label +explicite avant chaque valeur). + +Points critiques : +- le numéro de venue est rejeté plusieurs lignes après son libellé, juste + avant la ligne IPP — ce layout BACTERIO est précisément ce que la règle + `_RE_VENUE_BEFORE_IPP` doit attraper ; +- la date de naissance doit être masquée, pas la date de prélèvement ni + l'horaire de prélèvement ; +- le RPPS du prescripteur doit disparaître ; +- le téléphone du laboratoire est une donnée de contact à masquer ; +- le vocabulaire microbiologique (`Escherichia coli`, `Antibiogramme`, + `Amoxicilline`, `Céfotaxime`, `Ciprofloxacine`) doit rester lisible + intégralement, c'est l'utilité métier du document ; +- `Service de néphrologie` doit rester lisible ; +- `prise en charge` doit rester lisible ; +- le nom composé `MARIE-PIERRE` doit être traité en bloc ; +- le biologiste signataire (`Dr DUHALDE Anne`) doit être masqué. + +Écarts détectés au runner (à corriger) : +- **fuite RPPS critique** : `RPPS prescripteur : 10101010101` n'est pas masqué. + La règle RPPS courante attend `RPPS\s*:\s*\d{11}` et ne tolère pas un + qualificateur (`prescripteur`, `signataire`, `prescripteur du jour`, …) + entre `RPPS` et `:`. Mêmes layouts probables pour FINESS, IPP, NDA. +- bloc `Dr DUHALDE Anne` masqué comme un seul `[NOM]` plutôt que + `Dr [NOM] [NOM]` — accepté tant qu'aucun token de nom ne fuit ; à + retraiter si l'usage demande la conservation du préfixe `Dr`. + +Vérification BDPM/gazetteer : +- `Amoxicilline`, `Céfotaxime`, `Ciprofloxacine`, `Escherichia coli`, + `Antibiogramme` doivent rester intacts (contenu métier). diff --git a/tests/synthetic_review/cases/005_bacterio_complete/test.txt b/tests/synthetic_review/cases/005_bacterio_complete/test.txt new file mode 100644 index 0000000..38ea75a --- /dev/null +++ b/tests/synthetic_review/cases/005_bacterio_complete/test.txt @@ -0,0 +1,30 @@ +CENTRE HOSPITALIER DE LA COTE BASQUE +Laboratoire de bactériologie +Bayonne, le 03/04/2024 + +RESULTAT D'EXAMEN BACTERIOLOGIQUE + +N° venue +DDN : 18/06/1972 +LARRALDE MARIE-PIERRE +2300451267 +IPP : DEF98765 +RPPS prescripteur : 10101010101 + +Prélèvement : ECBU +Date de prélèvement : 02/04/2024 à 08h30 +Service prescripteur : Service de néphrologie + +Examen direct : leucocytes nombreux, hématies rares. +Culture : Escherichia coli >100 000 UFC/mL. + +Antibiogramme : +- Amoxicilline : R +- Céfotaxime : S +- Ciprofloxacine : S + +Conclusion : infection urinaire à Escherichia coli sensible aux céphalosporines. +La prise en charge thérapeutique relève de l'antibiothérapie ciblée. + +Validé par Dr DUHALDE Anne, biologiste médicale. +Tel laboratoire : 05 59 44 35 35 diff --git a/tests/synthetic_review/cases/006_trackare_soignants/expectations.json b/tests/synthetic_review/cases/006_trackare_soignants/expectations.json new file mode 100644 index 0000000..16cc68b --- /dev/null +++ b/tests/synthetic_review/cases/006_trackare_soignants/expectations.json @@ -0,0 +1,44 @@ +{ + "required_kinds": [ + "ADRESSE", + "CODE_POSTAL", + "DATE_NAISSANCE", + "DOSSIER", + "ETAB", + "IPP", + "NOM_FORCE", + "NOM_GLOBAL", + "TEL", + "VILLE" + ], + "must_contain": [ + "Service de chirurgie viscérale", + "Détails des patients", + "prise en charge", + "cholécystectomie", + "EVA 2/10", + "PARACETAMOL" + ], + "must_not_contain": [ + "PIERRE", + "HARRIET", + "ETCHEBARNE", + "ALVARADO", + "LACLAU ", + "NARZABAL", + "LACROUTS", + "LARRIEU ", + "DUPONT", + "MARTIN", + "DURAND", + "Jean-Paul", + "Sophie", + "GHI11223", + "2300784512", + "23145678", + "04/09/1956", + "06 87 65 43 21", + "05 59 44 35 35", + "CHCB" + ] +} diff --git a/tests/synthetic_review/cases/006_trackare_soignants/expected.txt b/tests/synthetic_review/cases/006_trackare_soignants/expected.txt new file mode 100644 index 0000000..ebdbcf0 --- /dev/null +++ b/tests/synthetic_review/cases/006_trackare_soignants/expected.txt @@ -0,0 +1,39 @@ +[ETABLISSEMENT] +Service de chirurgie viscérale + +Dossier Patient — Détails des patients +[VILLE], le 22/05/2024 + +Patient : +[NOM] +[NOM] +Nom de naissance : [NOM] +[DATE_NAISSANCE] +N° dossier : [DOSSIER] +NDA : [DOSSIER] +IPP : [IPP] + +Adresse : [ADRESSE] +Code postal : [CODE_POSTAL] +Ville : [ETABLISSEMENT]-de-Luz +Téléphone : [TEL] + +Activités de soins : +07 : 00 [NOM] Pose voie veineuse périphérique. +07 : 15 [NOM] Surveillance constantes. +08 : 00 [NOM]- Bilan d'entrée terminé. +12 : 30 [NOM] Distribution médicamenteuse. +19 : 00 [NOM] Sortie de bloc, surveillance post-op. + +Note IDE [NOM] +Patient calme, douleur EVA 2/10. Pansement propre. + +Note médicale Dr [NOM] +Suites simples post cholécystectomie. La prise en charge anti-douleur +est efficace. Reprise alimentaire progressive. Service de chirurgie +viscérale : rendez-vous de contrôle à J+15. + +Signé — PARACETAMOL BBM 1000 MG INJ [NOM] [NOM] +Signé [NOM]- + +Tel service : [TEL] diff --git a/tests/synthetic_review/cases/006_trackare_soignants/review.md b/tests/synthetic_review/cases/006_trackare_soignants/review.md new file mode 100644 index 0000000..59c2507 --- /dev/null +++ b/tests/synthetic_review/cases/006_trackare_soignants/review.md @@ -0,0 +1,43 @@ +# Revue 006 — dossier de soins Trackare + +Famille documentaire : export Trackare/TrakCare avec activités de soins +horodatées et noms de soignants en formats variés. Regroupe les patterns +historiquement les plus piégeux du moteur (cf. mémoire `soignants-trackare`). + +Le document doit contenir au moins deux marqueurs Trackare reconnus +(`Détails des patients`, `Nom de naissance`, `Dossier Patient`) pour que +`_extract_trackare_identity` se déclenche. Sans ces marqueurs, les patterns +spécifiques (HH:MM NOM, Note IDE NOM, Signé NOM, etc.) ne tournent pas. + +Patterns testés et confirmés masqués : +- `Patient :\n\n` (PIERRE / HARRIET) sur trois lignes ; +- soignants `HH:MM ` dans les activités de soins (ETCHEBARNE, + ALVARADO, LACLAU-, NARZABAL, LACROUTS) — kind NOM_GLOBAL ; +- soignants `Note IDE ` (DUPONT) — kind NOM_FORCE ; +- soignant `Note médicale Dr ` (MARTIN Jean-Paul) + — capturé en bloc puis Jean-Paul re-confirmé en NOM_FORCE ; +- soignant après médicament greedy `Signé — PARACETAMOL BBM 1000 MG INJ + DURAND Sophie` — DURAND et Sophie sont masqués via NOM_GLOBAL ; +- nom tronqué `Signé LARRIEU-` — masqué (kind NOM_FORCE). + +Vérification métier (préservation) : +- `PARACETAMOL BBM 1000 MG INJ` reste lisible (gazetteer BDPM) ; +- `cholécystectomie`, `EVA 2/10`, `Service de chirurgie viscérale` + restent intacts ; +- `Détails des patients` doit rester pour conserver la trace de la + source documentaire. + +Écarts détectés au runner (à fixer ultérieurement) : +- **`Saint-Jean-de-Luz` partiellement masqué en `[ETABLISSEMENT]-de-Luz`** + via un hit `ETAB_FINESS` sur `Saint-Jean`. La ville composée doit être + prise comme un bloc avant que le matcher FINESS ne morde. Laisser le + résiduel `-de-Luz` est un FP visuel mais pas une fuite directe. +- **classification `NDA` → `DOSSIER`** : la valeur `2300784512` derrière + `NDA :` est masquée mais le kind utilisé est `DOSSIER`, pas `NDA`. Le + texte est masqué correctement, c'est la cohérence d'audit qui souffre. +- **horodatages `07:00` deviennent `07 : 00`** : une normalisation + cosmétique ajoute des espaces autour du `:`. Sans impact sur la sécurité + mais altère la lisibilité du document final. +- **bloc `Dr MARTIN Jean-Paul` masqué en un seul `[NOM]`** : MARTIN et + Jean-Paul sont bien dans l'audit, mais le rendu `Note médicale Dr [NOM]` + efface la structure préfixe+nom+prénom. diff --git a/tests/synthetic_review/cases/006_trackare_soignants/test.txt b/tests/synthetic_review/cases/006_trackare_soignants/test.txt new file mode 100644 index 0000000..6705292 --- /dev/null +++ b/tests/synthetic_review/cases/006_trackare_soignants/test.txt @@ -0,0 +1,39 @@ +CENTRE HOSPITALIER DE LA COTE BASQUE +Service de chirurgie viscérale + +Dossier Patient — Détails des patients +Bayonne, le 22/05/2024 + +Patient : +PIERRE +HARRIET +Nom de naissance : HARRIET +Né le 04/09/1956 +N° dossier : 23145678 +NDA : 2300784512 +IPP : GHI11223 + +Adresse : 3 chemin du Moulin +Code postal : 64500 +Ville : Saint-Jean-de-Luz +Téléphone : 06 87 65 43 21 + +Activités de soins : +07:00 ETCHEBARNE Pose voie veineuse périphérique. +07:15 ALVARADO Surveillance constantes. +08:00 LACLAU- Bilan d'entrée terminé. +12:30 NARZABAL Distribution médicamenteuse. +19:00 LACROUTS Sortie de bloc, surveillance post-op. + +Note IDE DUPONT +Patient calme, douleur EVA 2/10. Pansement propre. + +Note médicale Dr MARTIN Jean-Paul +Suites simples post cholécystectomie. La prise en charge anti-douleur +est efficace. Reprise alimentaire progressive. Service de chirurgie +viscérale : rendez-vous de contrôle à J+15. + +Signé — PARACETAMOL BBM 1000 MG INJ DURAND Sophie +Signé LARRIEU- + +Tel service : 05 59 44 35 35 diff --git a/tests/synthetic_review/cases/007_lettre_sortie_complete/expectations.json b/tests/synthetic_review/cases/007_lettre_sortie_complete/expectations.json new file mode 100644 index 0000000..3261d72 --- /dev/null +++ b/tests/synthetic_review/cases/007_lettre_sortie_complete/expectations.json @@ -0,0 +1,48 @@ +{ + "required_kinds": [ + "ADRESSE", + "CODE_POSTAL", + "DATE_NAISSANCE", + "DOSSIER", + "EMAIL", + "ETAB", + "IPP", + "RPPS", + "TEL", + "VILLE" + ], + "must_contain": [ + "Service de cardiologie", + "classification internationale", + "prise en charge", + "insuffisance cardiaque", + "infarctus du myocarde", + "hypertension artérielle", + "diabète de type 2", + "FUROSEMIDE", + "BISOPROLOL", + "RAMIPRIL", + "CIM-10", + "I50.0" + ], + "must_not_contain": [ + "CASTAIGNEDE", + "Olivier", + "ARRAMBIDE", + "Jean-Baptiste", + "LAFITTE", + "Marie-Hélène", + "Biarritz", + "Anglet", + "Bayonne", + "MNO55667", + "2400112233", + "11122233344", + "23/11/1948", + "06 33 22 11 99", + "05 59 44 35 22", + "jb.arrambide@example.fr", + "mh.lafitte@chcb.fr", + "CHCB" + ] +} diff --git a/tests/synthetic_review/cases/007_lettre_sortie_complete/expected.txt b/tests/synthetic_review/cases/007_lettre_sortie_complete/expected.txt new file mode 100644 index 0000000..ac3ad1b --- /dev/null +++ b/tests/synthetic_review/cases/007_lettre_sortie_complete/expected.txt @@ -0,0 +1,42 @@ +[ETABLISSEMENT] +Service de cardiologie +[VILLE], le 17/06/2024 + +Dr [NOM] +Cabinet médical +[ADRESSE] +[CODE_POSTAL] + +Cher Confrère, + +Je me permets de vous adresser le compte rendu de l'hospitalisation +de votre patient Monsieur [NOM], [DATE_NAISSANCE], +demeurant [ADRESSE], [CODE_POSTAL], joignable au +[TEL] ou par courriel [EMAIL]. + +IPP : [IPP] +NDA : [DOSSIER] + +Motif d'hospitalisation : insuffisance cardiaque décompensée sur +cardiopathie ischémique connue. Le patient a été admis le 12/06/2024 +en unité de soins intensifs cardiologiques. + +Antécédents : infarctus du myocarde en 2018, hypertension artérielle, +diabète de type 2 équilibré. + +Évolution : amélioration sous traitement diurétique et bêta-bloquant. +La classification internationale CIM-10 retient I50.0 (insuffisance +cardiaque congestive). La prise en charge thérapeutique a été optimisée. + +Sortie le 16/06/2024 avec ordonnance de sortie comprenant FUROSEMIDE, +BISOPROLOL et RAMIPRIL aux posologies adaptées. + +Un rendez-vous de contrôle est programmé en consultation externe le +17/07/2024 dans notre Service de cardiologie. + +Confraternellement, + +Dr [NOM] +Cardiologue, RPPS : [RPPS] +Tel secrétariat : [TEL] +mh.[NOM]@[MASK].fr diff --git a/tests/synthetic_review/cases/007_lettre_sortie_complete/review.md b/tests/synthetic_review/cases/007_lettre_sortie_complete/review.md new file mode 100644 index 0000000..9eea4cb --- /dev/null +++ b/tests/synthetic_review/cases/007_lettre_sortie_complete/review.md @@ -0,0 +1,52 @@ +# Revue 007 — lettre de sortie médecin → médecin + +Famille documentaire : courrier médical adressé d'un médecin hospitalier +vers un correspondant de ville, contenant un compte rendu narratif +d'hospitalisation. Format classique français très répandu. + +Patterns testés : +- en-tête établissement + service + ville + date ; +- adresse complète du destinataire (médecin de ville) avec rue, CP, ville ; +- coordonnées patient en narratif continu (nom, prénom composé, date de + naissance, adresse, CP, ville, téléphone, email) sur plusieurs lignes ; +- IPP / NDA en lignes structurées ; +- terminologie médicale dense : `insuffisance cardiaque`, `infarctus du + myocarde`, `hypertension artérielle`, `diabète de type 2`, `cardiopathie + ischémique`, `unité de soins intensifs cardiologiques` ; +- code CIM-10 cité littéralement (`I50.0`) — ne doit PAS être masqué ; +- noms de médicaments en majuscules cités dans l'ordonnance de sortie ; +- formule de politesse `Cher Confrère`, `Confraternellement` à préserver ; +- signature médecin avec RPPS et email institutionnel se terminant en + `@chcb.fr` (le sigle CHCB doit être masqué dans l'email aussi). + +Points critiques : +- aucun token nominal du destinataire (CASTAIGNEDE Olivier) ni du + signataire (LAFITTE Marie-Hélène) ne doit fuiter ; +- aucun token nominal du patient (ARRAMBIDE Jean-Baptiste) ne doit + fuiter, y compris en reprise narrative ; +- toutes les villes (Bayonne, Biarritz, Anglet) doivent être masquées ; +- la date de soin (12/06/2024, 16/06/2024, 17/07/2024) reste lisible ; +- la date de naissance (23/11/1948) doit être masquée ; +- le sigle `CHCB` est dans l'adresse email — vérifier que l'email entier + est masqué (et pas juste le local-part). + +Écarts détectés au runner (à fixer ultérieurement) : +- **fuite indirecte sur email institutionnel** : `mh.lafitte@chcb.fr` est + masqué en `mh.[NOM]@[MASK].fr` au lieu de `[EMAIL]`. Le sigle CHCB + (force_term) est appliqué AVANT la règle EMAIL et casse la capture du + pattern complet, laissant le local-part `mh.` (initiales du signataire) + exposé. À refondre : la détection EMAIL doit précéder le masquage des + force_terms à l'intérieur d'une adresse email. +- **villes consommées dans le hit `CP+VILLE`** : `64200 Biarritz` et + `64600 Anglet` deviennent `[CODE_POSTAL]` sans placeholder `[VILLE]` + visible. Pas de fuite (les villes disparaissent), mais perte + d'information sur la structure du document. +- **classification `NDA` → `DOSSIER`** : même quirk que dans 005/006. +- **bloc `Dr CASTAIGNEDE Olivier`** masqué en un seul `[NOM]` (idem 006). + +Préservation à confirmer : +- préfixe `Monsieur` avant le patient : préservé. +- prénom composé `Marie-Hélène` traité dans le bloc nom. +- code CIM `I50.0` cité littéralement, doit rester intact. +- noms de médicaments `FUROSEMIDE`, `BISOPROLOL`, `RAMIPRIL` doivent + rester (gazetteer BDPM). diff --git a/tests/synthetic_review/cases/007_lettre_sortie_complete/test.txt b/tests/synthetic_review/cases/007_lettre_sortie_complete/test.txt new file mode 100644 index 0000000..3917fb3 --- /dev/null +++ b/tests/synthetic_review/cases/007_lettre_sortie_complete/test.txt @@ -0,0 +1,42 @@ +CENTRE HOSPITALIER DE LA COTE BASQUE +Service de cardiologie +Bayonne, le 17/06/2024 + +Dr CASTAIGNEDE Olivier +Cabinet médical +12 avenue de la République +64200 Biarritz + +Cher Confrère, + +Je me permets de vous adresser le compte rendu de l'hospitalisation +de votre patient Monsieur ARRAMBIDE Jean-Baptiste, né le 23/11/1948, +demeurant 8 impasse des Rosiers, 64600 Anglet, joignable au +06 33 22 11 99 ou par courriel jb.arrambide@example.fr. + +IPP : MNO55667 +NDA : 2400112233 + +Motif d'hospitalisation : insuffisance cardiaque décompensée sur +cardiopathie ischémique connue. Le patient a été admis le 12/06/2024 +en unité de soins intensifs cardiologiques. + +Antécédents : infarctus du myocarde en 2018, hypertension artérielle, +diabète de type 2 équilibré. + +Évolution : amélioration sous traitement diurétique et bêta-bloquant. +La classification internationale CIM-10 retient I50.0 (insuffisance +cardiaque congestive). La prise en charge thérapeutique a été optimisée. + +Sortie le 16/06/2024 avec ordonnance de sortie comprenant FUROSEMIDE, +BISOPROLOL et RAMIPRIL aux posologies adaptées. + +Un rendez-vous de contrôle est programmé en consultation externe le +17/07/2024 dans notre Service de cardiologie. + +Confraternellement, + +Dr LAFITTE Marie-Hélène +Cardiologue, RPPS : 11122233344 +Tel secrétariat : 05 59 44 35 22 +mh.lafitte@chcb.fr diff --git a/tests/synthetic_review/cases/008_anesthesie_complete/expectations.json b/tests/synthetic_review/cases/008_anesthesie_complete/expectations.json new file mode 100644 index 0000000..5d6c038 --- /dev/null +++ b/tests/synthetic_review/cases/008_anesthesie_complete/expectations.json @@ -0,0 +1,46 @@ +{ + "required_kinds": [ + "ADRESSE", + "CODE_POSTAL", + "DATE_NAISSANCE", + "DOSSIER", + "ETAB", + "IPP", + "RPPS", + "TEL" + ], + "must_contain": [ + "Service d'anesthésie-réanimation", + "CONSULTATION PRE-ANESTHESIQUE", + "cholécystectomie", + "coelioscopie", + "lithiase vésiculaire", + "Classification ASA", + "ASA 1", + "HYDROXYZINE", + "PROPOFOL", + "SUFENTANIL", + "SEVOFLURANE", + "PARACETAMOL", + "KETOPROFENE", + "prise en charge", + "TA 120/75", + "FC 72", + "SpO2 98" + ], + "must_not_contain": [ + "OLAIZOLA", + "Maddi", + "URRUTIA", + "Pantxoa", + "DUFAU", + "Anne-Sophie", + "PQR44556", + "2400334455", + "22233344455", + "02/02/1992", + "06 78 90 12 34", + "05 59 44 35 41", + "CHCB" + ] +} diff --git a/tests/synthetic_review/cases/008_anesthesie_complete/expected.txt b/tests/synthetic_review/cases/008_anesthesie_complete/expected.txt new file mode 100644 index 0000000..5ee8e0e --- /dev/null +++ b/tests/synthetic_review/cases/008_anesthesie_complete/expected.txt @@ -0,0 +1,51 @@ +[ETABLISSEMENT] +Service d'anesthésie-réanimation +[VILLE], le 11/07/2024 + +CONSULTATION PRE-ANESTHESIQUE + +Patient : [NOM] [NOM] +[DATE_NAISSANCE] +Sexe : F +IPP : [IPP] +NDA : [DOSSIER] +Téléphone : [TEL] + +Adresse : [ADRESSE] +Code postal : [CODE_POSTAL] +Ville : [ETABLISSEMENT]-de-Luz + +Intervention prévue : cholécystectomie sous coelioscopie +Indication : lithiase vésiculaire symptomatique +Date d'intervention : 18/07/2024 +Chirurgien : Dr [NOM] +Anesthésiste : Dr [NOM] + +Antécédents : +- pas d'antécédent chirurgical notable +- pas d'allergie médicamenteuse connue +- non fumeuse, IMC 23 + +Examen clinique : +TA 120/75 mmHg, FC 72 bpm, SpO2 98% air ambiant. +Auscultation cardio-pulmonaire normale. + +Bilan préopératoire : +NFS, ionogramme, hémostase : sans particularité. +ECG : rythme sinusal régulier. + +Classification ASA : ASA 1 +Consentement éclairé recueilli. + +Protocole anesthésique prévu : +- prémédication : HYDROXYZINE 25 mg per os +- induction : PROPOFOL 2 mg/kg, SUFENTANIL 0,3 µg/kg +- entretien : SEVOFLURANE +- analgésie post-opératoire : PARACETAMOL 1 g IV puis KETOPROFENE 100 mg + +La prise en charge sera assurée en hôpital de jour. Sortie prévue +le soir même après surveillance en SSPI. + +Signé Dr [NOM], anesthésiste +RPPS : [RPPS] +Tel anesthésie : [TEL] diff --git a/tests/synthetic_review/cases/008_anesthesie_complete/review.md b/tests/synthetic_review/cases/008_anesthesie_complete/review.md new file mode 100644 index 0000000..b71ee67 --- /dev/null +++ b/tests/synthetic_review/cases/008_anesthesie_complete/review.md @@ -0,0 +1,36 @@ +# Revue 008 — consultation pré-anesthésique + +Famille documentaire : compte rendu de consultation pré-opératoire +en anesthésie-réanimation. Très chargé en terminologie médicale (ASA, +constantes vitales, protocoles d'induction et d'entretien) et en noms +de molécules anesthésiques. + +Patterns testés : +- prénoms locaux basques rares (Maddi, Pantxoa) qui peuvent ne pas être + dans les gazetteers INSEE classiques — risque de FN ; +- prénom composé `Anne-Sophie` (anesthésiste) ; +- nombreux noms de médicaments en majuscules à préserver + (HYDROXYZINE, PROPOFOL, SUFENTANIL, SEVOFLURANE, PARACETAMOL, KETOPROFENE) ; +- doses avec unités complexes (`mg/kg`, `µg/kg`, `mg`, `g IV`, `100 mg`) ; +- constantes vitales (`TA 120/75 mmHg`, `FC 72 bpm`, `SpO2 98%`) qui + ne doivent JAMAIS être prises pour des identifiants. + +Points critiques : +- le terme `ASA 1` (classification anesthésique) doit rester intact ; + attention au sigle ASA qui peut ressembler à un identifiant ; +- les abréviations cliniques `IMC 23`, `NFS`, `ECG`, `SSPI` doivent rester ; +- `cholécystectomie` et `coelioscopie` (actes CCAM) doivent rester ; +- `lithiase vésiculaire` (diagnostic) doit rester ; +- les ratios constantes (`120/75`) ne doivent pas être interprétés + comme dates ou identifiants. + +Préservation à surveiller : +- aucun nom de molécule ne doit être tronqué par un masquage erroné ; +- le préfixe `Dr` est suivi du nom ; si un seul `[NOM]` apparaît à la + place de `Dr NOM Prenom`, accepter tant que les noms et prénoms sont + bien dans l'audit. + +Écarts attendus (déjà observés sur d'autres cas) : +- `Saint-Jean-de-Luz` partiellement masqué en `[ETABLISSEMENT]-de-Luz` ; +- classification `NDA` → `DOSSIER` dans l'audit ; +- `Dr NOM Prenom` masqué en bloc unique `[NOM]`. diff --git a/tests/synthetic_review/cases/008_anesthesie_complete/test.txt b/tests/synthetic_review/cases/008_anesthesie_complete/test.txt new file mode 100644 index 0000000..9a5522e --- /dev/null +++ b/tests/synthetic_review/cases/008_anesthesie_complete/test.txt @@ -0,0 +1,51 @@ +CENTRE HOSPITALIER DE LA COTE BASQUE +Service d'anesthésie-réanimation +Bayonne, le 11/07/2024 + +CONSULTATION PRE-ANESTHESIQUE + +Patient : OLAIZOLA Maddi +Né le 02/02/1992 +Sexe : F +IPP : PQR44556 +NDA : 2400334455 +Téléphone : 06 78 90 12 34 + +Adresse : 22 rue Gambetta +Code postal : 64500 +Ville : Saint-Jean-de-Luz + +Intervention prévue : cholécystectomie sous coelioscopie +Indication : lithiase vésiculaire symptomatique +Date d'intervention : 18/07/2024 +Chirurgien : Dr URRUTIA Pantxoa +Anesthésiste : Dr DUFAU Anne-Sophie + +Antécédents : +- pas d'antécédent chirurgical notable +- pas d'allergie médicamenteuse connue +- non fumeuse, IMC 23 + +Examen clinique : +TA 120/75 mmHg, FC 72 bpm, SpO2 98% air ambiant. +Auscultation cardio-pulmonaire normale. + +Bilan préopératoire : +NFS, ionogramme, hémostase : sans particularité. +ECG : rythme sinusal régulier. + +Classification ASA : ASA 1 +Consentement éclairé recueilli. + +Protocole anesthésique prévu : +- prémédication : HYDROXYZINE 25 mg per os +- induction : PROPOFOL 2 mg/kg, SUFENTANIL 0,3 µg/kg +- entretien : SEVOFLURANE +- analgésie post-opératoire : PARACETAMOL 1 g IV puis KETOPROFENE 100 mg + +La prise en charge sera assurée en hôpital de jour. Sortie prévue +le soir même après surveillance en SSPI. + +Signé Dr DUFAU Anne-Sophie, anesthésiste +RPPS : 22233344455 +Tel anesthésie : 05 59 44 35 41 diff --git a/tests/synthetic_review/cases/009_multi_etablissements/expectations.json b/tests/synthetic_review/cases/009_multi_etablissements/expectations.json new file mode 100644 index 0000000..a498395 --- /dev/null +++ b/tests/synthetic_review/cases/009_multi_etablissements/expectations.json @@ -0,0 +1,45 @@ +{ + "required_kinds": [ + "ADRESSE", + "CODE_POSTAL", + "DATE_NAISSANCE", + "ETAB", + "IPP", + "TEL" + ], + "must_contain": [ + "Service de neurologie", + "neurochirurgie", + "neuropathie périphérique", + "rééducation fonctionnelle", + "EMG", + "IRM médullaire", + "classification internationale", + "CIM-10", + "G56.8", + "prise en charge", + "réflexes ostéotendineux" + ], + "must_not_contain": [ + "SALABERRY", + "Iban", + "ELISSALDE", + "Xabi", + "LARRALDE", + "Maïté", + "ITHURRIAGUE", + "Beñat", + "Bordeaux", + "Biarritz", + "Bayonne", + "Aguilera", + "STU77889", + "2400556677", + "33344455566", + "14/05/1965", + "06 23 45 67 89", + "05 59 44 35 19", + "CHCB", + "CHU de Bordeaux" + ] +} diff --git a/tests/synthetic_review/cases/009_multi_etablissements/expected.txt b/tests/synthetic_review/cases/009_multi_etablissements/expected.txt new file mode 100644 index 0000000..8e39c5f --- /dev/null +++ b/tests/synthetic_review/cases/009_multi_etablissements/expected.txt @@ -0,0 +1,37 @@ +[ETABLISSEMENT] +Service de neurologie +[VILLE], le 25/08/2024 + +COMPTE RENDU DE CONSULTATION + +Patient : [NOM] [NOM] +[DATE_NAISSANCE] +IPP : [IPP] +NDA : [DOSSIER] +Adresse : [ADRESSE] +Code postal : [CODE_POSTAL] +Ville : [VILLE] +Téléphone : [TEL] + +Patient adressé par le Dr [NOM] du [ETABLISSEMENT], service de neurochirurgie, pour avis +sur une suspicion de neuropathie périphérique post-traumatique. + +Antécédents : +- accident de la voie publique en 2022, traité initialement au [ETABLISSEMENT] puis transféré au [MASK] pour la rééducation ; +- séjour en service de rééducation fonctionnelle de la [ETABLISSEMENT] à [VILLE] du 12/06/2022 au 30/07/2022. + +Examen neurologique : déficit sensitif territoire L5 droit, +réflexes ostéotendineux normaux. Force motrice cotée 4/5 sur le +quadriceps droit. + +Conduite à tenir : +- EMG demandé en urgence au laboratoire de neurophysiologie du [ETABLISSEMENT] (Dr [NOM] [NOM], neurophysiologiste) ; +- IRM médullaire programmée à la [ETABLISSEMENT] ; +- la classification internationale CIM-10 retient G56.8. + +La prise en charge multidisciplinaire sera coordonnée entre nos +trois établissements. Service de neurologie disponible pour suivi. + +Signé Dr [NOM], neurologue +RPPS : [RPPS] +Tel : [TEL] diff --git a/tests/synthetic_review/cases/009_multi_etablissements/review.md b/tests/synthetic_review/cases/009_multi_etablissements/review.md new file mode 100644 index 0000000..3bc7af0 --- /dev/null +++ b/tests/synthetic_review/cases/009_multi_etablissements/review.md @@ -0,0 +1,37 @@ +# Revue 009 — compte rendu multi-établissements + +Famille documentaire : consultation neurologique impliquant trois +établissements distincts cités dans le narratif (CHCB, CHU de Bordeaux, +Clinique Aguilera). Document typique du parcours de soin patient passant +d'un établissement à l'autre. + +Patterns testés : +- établissement principal en entête (CHCB) ; +- établissement secondaire en narratif (`Centre Hospitalier Universitaire + de Bordeaux`, `CHU de Bordeaux`) — variantes longue et courte du même + établissement ; +- établissement privé en narratif (`Clinique Aguilera`) — pas dans les + gazetteers FINESS publics par défaut, doit être détecté contextuellement + via le mot-clé `Clinique` ; +- prénoms basques rares (Iban, Xabi, Maïté, Beñat) sur trois noms de + médecins différents — risque de FN si gazetteer prénoms incomplet ; +- nom composé avec accent (`Maïté`) ; +- code CIM `G56.8` cité littéralement — préservation obligatoire. + +Points critiques : +- aucun token nominal de patient (SALABERRY Iban) ni des trois médecins + (ELISSALDE Xabi, LARRALDE Maïté, ITHURRIAGUE Beñat) ne doit fuiter ; +- les villes Bordeaux, Biarritz, Bayonne et le nom d'établissement + Aguilera doivent toutes disparaître ; +- le sigle `CHCB` doit être masqué (force_term) ; +- le terme `CHU de Bordeaux` doit être masqué — y compris la version + courte qui ne contient pas explicitement `Centre Hospitalier` ; +- terminologie médicale dense doit rester intacte : + `neuropathie périphérique`, `réflexes ostéotendineux`, + `rééducation fonctionnelle`, `EMG`, `IRM médullaire`. + +Écart spécifique à observer : +- détection des établissements non FINESS publics (cliniques privées) ; +- détection variante longue vs sigle (`Centre Hospitalier Universitaire + de Bordeaux` vs `CHU de Bordeaux`) — la version sigle peut échapper au + matcher si `CHU` n'est pas en règle force_term ou contextuelle. diff --git a/tests/synthetic_review/cases/009_multi_etablissements/test.txt b/tests/synthetic_review/cases/009_multi_etablissements/test.txt new file mode 100644 index 0000000..05e088c --- /dev/null +++ b/tests/synthetic_review/cases/009_multi_etablissements/test.txt @@ -0,0 +1,41 @@ +CENTRE HOSPITALIER DE LA COTE BASQUE +Service de neurologie +Bayonne, le 25/08/2024 + +COMPTE RENDU DE CONSULTATION + +Patient : SALABERRY Iban +Né le 14/05/1965 +IPP : STU77889 +NDA : 2400556677 +Adresse : 5 allée des Platanes +Code postal : 64200 +Ville : Biarritz +Téléphone : 06 23 45 67 89 + +Patient adressé par le Dr ELISSALDE Xabi du Centre Hospitalier +Universitaire de Bordeaux, service de neurochirurgie, pour avis +sur une suspicion de neuropathie périphérique post-traumatique. + +Antécédents : +- accident de la voie publique en 2022, traité initialement au CHU + de Bordeaux puis transféré au CHCB pour la rééducation ; +- séjour en service de rééducation fonctionnelle de la Clinique + Aguilera à Biarritz du 12/06/2022 au 30/07/2022. + +Examen neurologique : déficit sensitif territoire L5 droit, +réflexes ostéotendineux normaux. Force motrice cotée 4/5 sur le +quadriceps droit. + +Conduite à tenir : +- EMG demandé en urgence au laboratoire de neurophysiologie du CHU + de Bordeaux (Dr LARRALDE Maïté, neurophysiologiste) ; +- IRM médullaire programmée à la Clinique Aguilera ; +- la classification internationale CIM-10 retient G56.8. + +La prise en charge multidisciplinaire sera coordonnée entre nos +trois établissements. Service de neurologie disponible pour suivi. + +Signé Dr ITHURRIAGUE Beñat, neurologue +RPPS : 33344455566 +Tel : 05 59 44 35 19 diff --git a/tests/synthetic_review/cases/010_fiche_admission_minimale/expectations.json b/tests/synthetic_review/cases/010_fiche_admission_minimale/expectations.json new file mode 100644 index 0000000..642be55 --- /dev/null +++ b/tests/synthetic_review/cases/010_fiche_admission_minimale/expectations.json @@ -0,0 +1,43 @@ +{ + "required_kinds": [ + "ADRESSE", + "CODE_POSTAL", + "DATE_NAISSANCE", + "EMAIL", + "ETAB", + "IPP", + "NIR", + "TEL", + "VILLE" + ], + "must_contain": [ + "FICHE D'ADMISSION", + "Service de gastro-entérologie", + "Sexe : F", + "Nationalité : française", + "Lien : conjoint", + "MGEN" + ], + "must_not_contain": [ + "DARRIBEHAUDE", + "ELIZONDO", + "Sabine", + "ETCHEGOIN", + "Jean-Louis", + "Tarbes", + "Bayonne", + "VWX99001", + "24009988", + "2400667788", + "44455566677", + "30/04/1973", + "05 59 22 33 44", + "06 88 99 00 11", + "06 77 88 99 00", + "05 59 11 22 33", + "sabine.darribehaude@example.com", + "1234567890", + "2 73 04 65 100 100 88", + "CHCB" + ] +} diff --git a/tests/synthetic_review/cases/010_fiche_admission_minimale/expected.txt b/tests/synthetic_review/cases/010_fiche_admission_minimale/expected.txt new file mode 100644 index 0000000..2211ff5 --- /dev/null +++ b/tests/synthetic_review/cases/010_fiche_admission_minimale/expected.txt @@ -0,0 +1,40 @@ +[ETABLISSEMENT] +FICHE D'ADMISSION + +Date : 02/09/2024 +N° venue : [NDA] +IPP : [IPP] +Dossier : [DOSSIER] + +IDENTITE +Nom : [NOM] +Nom de jeune fille : [NOM] +Prénom : [NOM] +Sexe : F +[DATE_NAISSANCE] +Lieu de naissance : [VILLE] +Nationalité : française + +COORDONNEES +Adresse : [ADRESSE] +Code postal : [CODE_POSTAL] +Ville : [VILLE] +Téléphone fixe : [TEL] +Téléphone portable : [TEL] +Email : [EMAIL] + +PERSONNE A PREVENIR +Nom : [NOM] (époux) +Téléphone : [TEL] +Lien : conjoint + +MEDECIN TRAITANT +Dr [NOM] +RPPS : [RPPS] +Tel : [TEL] + +INFORMATIONS COMPLEMENTAIRES +Mutuelle : MGEN n°adhérent [NDA] +Sécurité sociale : [NIR] + +Service de gastro-entérologie — chambre 412 diff --git a/tests/synthetic_review/cases/010_fiche_admission_minimale/review.md b/tests/synthetic_review/cases/010_fiche_admission_minimale/review.md new file mode 100644 index 0000000..4c17a6f --- /dev/null +++ b/tests/synthetic_review/cases/010_fiche_admission_minimale/review.md @@ -0,0 +1,36 @@ +# Revue 010 — fiche d'admission administrative + +Famille documentaire : fiche d'identification administrative pure, +quasi sans narratif. Empilement dense de PII structurées sous des +labels explicites. Pas de contexte sémantique pour aider le NER. + +Patterns testés : +- structuration en blocs (IDENTITE, COORDONNEES, PERSONNE A PREVENIR, + MEDECIN TRAITANT, INFORMATIONS COMPLEMENTAIRES) ; +- nom marital + nom de jeune fille empilés sur deux lignes ; +- patient et époux portant le même nom de famille (DARRIBEHAUDE) : + vérifier la propagation globale ; +- 4 numéros de téléphone différents (fixe patient, portable patient, + proche, médecin traitant) ; +- email avec local-part contenant le nom de famille + (`sabine.darribehaude`) — fuite indirecte si l'email n'est pas masqué + comme un bloc atomique ; +- numéro de mutuelle MGEN (10 chiffres) à masquer ; +- numéro de sécurité sociale au format espacé (`2 73 04 65 100 100 88`) + qui doit être détecté par la règle NIR. + +Points critiques : +- aucun token PII ne doit fuiter, malgré l'absence de contexte narratif ; +- le label structurel doit rester (`Nom :`, `Prénom :`, `Adresse :`, etc.) ; +- le sigle `MGEN` (organisme de mutuelle, pas un nom propre) doit rester ; +- le numéro d'adhérent MGEN `1234567890` doit être masqué (pseudo-NDA) ; +- `Sexe : F` et `Nationalité : française` doivent rester intacts ; +- le numéro de chambre `chambre 412` doit rester intact (pas un + identifiant patient). + +Écarts attendus : +- numéro d'adhérent MGEN : pas couvert par les règles standard, peut + être un FN si aucune règle générique sur séquence numérique 10+ ; +- le NIR au format espacé peut être détecté ou non selon la règle ; +- patient et époux portant le même nom : vérifier que les deux + occurrences sont bien masquées. diff --git a/tests/synthetic_review/cases/010_fiche_admission_minimale/test.txt b/tests/synthetic_review/cases/010_fiche_admission_minimale/test.txt new file mode 100644 index 0000000..2cba60f --- /dev/null +++ b/tests/synthetic_review/cases/010_fiche_admission_minimale/test.txt @@ -0,0 +1,40 @@ +CENTRE HOSPITALIER DE LA COTE BASQUE +FICHE D'ADMISSION + +Date : 02/09/2024 +N° venue : 2400667788 +IPP : VWX99001 +Dossier : 24009988 + +IDENTITE +Nom : DARRIBEHAUDE +Nom de jeune fille : ELIZONDO +Prénom : Sabine +Sexe : F +Date de naissance : 30/04/1973 +Lieu de naissance : Tarbes +Nationalité : française + +COORDONNEES +Adresse : 17 boulevard Thiers, appartement 3B +Code postal : 64100 +Ville : Bayonne +Téléphone fixe : 05 59 22 33 44 +Téléphone portable : 06 88 99 00 11 +Email : sabine.darribehaude@example.com + +PERSONNE A PREVENIR +Nom : DARRIBEHAUDE Pierre (époux) +Téléphone : 06 77 88 99 00 +Lien : conjoint + +MEDECIN TRAITANT +Dr ETCHEGOIN Jean-Louis +RPPS : 44455566677 +Tel : 05 59 11 22 33 + +INFORMATIONS COMPLEMENTAIRES +Mutuelle : MGEN n°adhérent 1234567890 +Sécurité sociale : 2 73 04 65 100 100 88 + +Service de gastro-entérologie — chambre 412 diff --git a/tests/unit/test_synthetic_review.py b/tests/unit/test_synthetic_review.py new file mode 100644 index 0000000..66ae35f --- /dev/null +++ b/tests/unit/test_synthetic_review.py @@ -0,0 +1,85 @@ +#!/usr/bin/env python3 +""" +Gate pytest sur le corpus synthétique de revue humaine (couche 2). + +Chaque cas dans tests/synthetic_review/cases/ doit produire un texte +identique à expected.txt, satisfaire ses expectations.json et ne révéler +aucune fuite via le LeakScanner. + +Les cas listés dans KNOWN_FAILURES sont marqués xfail(strict=True) : +ils sont attendus en échec aujourd'hui car ils révèlent des bugs réels +du moteur. Quand un bug est fixé, le cas correspondant passe → pytest +signale le xpass strict, ce qui force à retirer son entrée de +KNOWN_FAILURES. +""" +from __future__ import annotations + +import sys +from pathlib import Path + +import pytest + +ROOT = Path(__file__).resolve().parents[2] +if str(ROOT) not in sys.path: + sys.path.insert(0, str(ROOT)) + +from tools.run_synthetic_review_corpus import ( # noqa: E402 + CASES_DIR, + run_case, +) + + +KNOWN_FAILURES: dict[str, str] = { + "005_bacterio_complete": ( + "RPPS avec qualificateur (`RPPS prescripteur :`) non détecté — " + "fuite identifiant médecin." + ), + "009_multi_etablissements": ( + "Plusieurs fuites : suffixe `de Bordeaux` après [ETABLISSEMENT], " + "CHCB en fin de phrase, Biarritz sur ligne `Ville :`, caractère " + "`ñ` qui casse Beñat → [NOM]ñat." + ), + "010_fiche_admission_minimale": ( + "Labels `Nom de jeune fille :`, `Prénom :`, `Ville :` non " + "couverts — ELIZONDO, Sabine, Bayonne fuient. NIR au format " + "espacé partiellement masqué (consommé en TEL)." + ), +} + + +def _case_dirs() -> list[Path]: + if not CASES_DIR.exists(): + return [] + return sorted(path for path in CASES_DIR.iterdir() if path.is_dir()) + + +def _make_param(case_dir: Path) -> "pytest.ParameterSet": + if case_dir.name in KNOWN_FAILURES: + return pytest.param( + case_dir, + id=case_dir.name, + marks=pytest.mark.xfail( + strict=True, + reason=KNOWN_FAILURES[case_dir.name], + ), + ) + return pytest.param(case_dir, id=case_dir.name) + + +def test_synthetic_review_inventory(): + """Le corpus doit contenir 10 cas (cible de cadrage produit).""" + assert CASES_DIR.exists(), f"Dossier corpus introuvable : {CASES_DIR}" + case_dirs = _case_dirs() + assert len(case_dirs) == 10, ( + f"Attendu 10 cas dans synthetic_review/cases, trouvé {len(case_dirs)} : " + f"{[c.name for c in case_dirs]}" + ) + + +@pytest.mark.parametrize("case_dir", [_make_param(c) for c in _case_dirs()]) +def test_synthetic_review_case(case_dir: Path): + result = run_case(case_dir) + assert not result["failures"], ( + f"{case_dir.name} : {', '.join(result['failures'])}\n" + f"Diff disponible dans {result['output_dir']}/diff.txt" + )