feat(gui): confirmation explicite avant anonymisation regex-only (NER off)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -20,6 +20,31 @@ from gui_v6 import ui_kit
|
|||||||
from gui_v6.config_state import ConfigState, default_profile_key, list_profile_keys
|
from gui_v6.config_state import ConfigState, default_profile_key, list_profile_keys
|
||||||
from manual_masking import ensure_mask_templates_dir, list_mask_templates, mask_template_label
|
from manual_masking import ensure_mask_templates_dir, list_mask_templates, mask_template_label
|
||||||
|
|
||||||
|
NER_DISABLE_WARNING = (
|
||||||
|
"Vous allez désactiver le moteur d'intelligence artificielle "
|
||||||
|
"(CamemBERT-bio).\n\n"
|
||||||
|
"Sans lui, la détection des NOMS de personnes repose uniquement sur des "
|
||||||
|
"règles (expressions régulières) : des noms peuvent rester EN CLAIR dans "
|
||||||
|
"les documents.\n\n"
|
||||||
|
"Pour un usage médical, garder ce moteur activé est fortement recommandé.\n\n"
|
||||||
|
"Confirmer la désactivation ?"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def confirm_ner_disable(asker) -> bool:
|
||||||
|
"""Décision de désactivation du NER.
|
||||||
|
|
||||||
|
``asker`` est une fonction ``() -> bool`` (ex. ``messagebox.askyesno``),
|
||||||
|
injectée pour rester testable sans display. Retourne True si l'utilisateur
|
||||||
|
CONFIRME la désactivation (regex-only). Toute erreur de l'asker est traitée
|
||||||
|
comme un refus (sens sûr : le NER reste actif).
|
||||||
|
"""
|
||||||
|
try:
|
||||||
|
return bool(asker())
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
_SUBTABS = [
|
_SUBTABS = [
|
||||||
("reg", "⚙️ Réglages"),
|
("reg", "⚙️ Réglages"),
|
||||||
("pro", "👤 Profils"),
|
("pro", "👤 Profils"),
|
||||||
@@ -891,7 +916,19 @@ class ConfigTab(ctk.CTkFrame):
|
|||||||
setattr(self._state, field_name, bool(toggle.get()))
|
setattr(self._state, field_name, bool(toggle.get()))
|
||||||
|
|
||||||
def _on_ner(self) -> None:
|
def _on_ner(self) -> None:
|
||||||
self._state.use_local_ner = self._tog_ner.get()
|
new_value = self._tog_ner.get()
|
||||||
|
if not new_value:
|
||||||
|
confirmed = confirm_ner_disable(
|
||||||
|
lambda: messagebox.askyesno(
|
||||||
|
"Moteur de détection", NER_DISABLE_WARNING, icon="warning"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if not confirmed:
|
||||||
|
# Refus : rétablir l'affichage du switch et garder le NER actif.
|
||||||
|
self._tog_ner.var.set(True)
|
||||||
|
self._state.use_local_ner = True
|
||||||
|
return
|
||||||
|
self._state.use_local_ner = new_value
|
||||||
|
|
||||||
def _on_eds(self) -> None:
|
def _on_eds(self) -> None:
|
||||||
self._state.enable_eds = self._tog_eds.get()
|
self._state.enable_eds = self._tog_eds.get()
|
||||||
|
|||||||
31
tests/unit/test_gui_v6_ner_confirm.py
Normal file
31
tests/unit/test_gui_v6_ner_confirm.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
"""Confirmation avant de désactiver le NER (regex-only) — outil médical.
|
||||||
|
|
||||||
|
Pur : la décision est isolée dans ``confirm_ner_disable(asker)`` ; ``asker`` est
|
||||||
|
injecté (pas de messagebox réel, pas de display).
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from gui_v6.tabs.tab_config import NER_DISABLE_WARNING, confirm_ner_disable
|
||||||
|
|
||||||
|
|
||||||
|
def test_confirm_true_when_user_accepts():
|
||||||
|
assert confirm_ner_disable(lambda: True) is True
|
||||||
|
|
||||||
|
|
||||||
|
def test_confirm_false_when_user_declines():
|
||||||
|
assert confirm_ner_disable(lambda: False) is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_confirm_false_when_asker_raises():
|
||||||
|
def boom():
|
||||||
|
raise RuntimeError("Tk indisponible")
|
||||||
|
# Sens sûr : une erreur de dialogue ne désactive jamais le NER.
|
||||||
|
assert confirm_ner_disable(boom) is False
|
||||||
|
|
||||||
|
|
||||||
|
def test_warning_text_is_explicit_for_medical_use():
|
||||||
|
txt = NER_DISABLE_WARNING.lower()
|
||||||
|
# L'avertissement DOIT nommer la dégradation : règles/regex + risque noms.
|
||||||
|
assert "règles" in txt or "regex" in txt
|
||||||
|
assert "nom" in txt
|
||||||
|
assert "recommand" in txt # « fortement recommandé »
|
||||||
Reference in New Issue
Block a user