Crée gui_v6/version.py (DEFAULT_VERSION + resolve_version()) qui tente
d'importer gui_v6._build_version (généré au build Windows, non commité).
Câble gui_v6.__version__ sur resolve_version(). Ajoute gui_v6/_build_version.py
au .gitignore et aux hiddenimports du spec PyInstaller. 4 tests TDD.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Décision Dom 2026-06-29 (honnêteté UI) :
- « Téléphones / e-mails » → « Téléphones » : EMAIL reste toujours masqué (non-toggleable),
le label ne le promet plus.
- hint « Adresses / CP » : « Voie, ville, code » → « Voie + code postal » : VILLE reste
toujours masquée (décision 1b), le hint ne la promet plus.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ajoute un conteneur scrollable dedie au sous-onglet Profils pour permettre le defilement souris du formulaire complet. Tests GUI: test_gui_v6_profiles.py et test_gui_v6_*.py.
Passe theme clair, libelles utilisateur, aides conteneurs, recherche de mise a jour et indication honnete des moteurs optionnels non embarques. Tests GUI unitaires: 126 passed.
Condition du GO-CONDITIONNEL Qwen sur le lot engine capabilities
(cb3b767/890edb3/5e5f0bd) : un profil YAML forçant enable_eds/enable_gliner
ne doit pas déclencher un chargement voué à l'échec silencieux.
NerManagers.ensure_loaded() applique désormais un garde-fou via la sonde
engine_capabilities.capabilities_map() (injectable) AVANT toute tentative
de load EDS/GLiNER : si le moteur optionnel demandé est indisponible dans
le build courant → warning + désactivation forcée dans les réglages runtime.
Best-effort (sonde en échec ⇒ réglages inchangés, les try/except de load
protègent déjà). Sonde légère (find_spec), aucun import lourd.
CamemBERT (requis) inchangé. Diff limité au garde-fou + tests cibles.
TDD : 4 tests (test_gui_v6_engine_bridge.py) — eds/gliner indispo désactivés
et jamais chargés, moteur dispo conservé, fail-safe sonde. 282 unit passed.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Axe application GUI (utilisateur final) : cohérence UI/moteurs propre au build
GUI, sans présumer du build CLI. EDS-Pseudo / GLiNER désactivés (switch disabled
+ « non embarqué dans cette version ») et `enable_eds/gliner` forcés à False quand
indisponibles ; CamemBERT-bio reste le moteur standard actif. Note Moteurs des
Profils rendue honnête. `_mini_toggle` gère `disabled`/`disabled_hint` + `.switch`.
2 tests GUI (toggles désactivés si indispo + état forcé False ; actifs si dispo).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Retour Dom : « les règles du profil doivent être dans le menu profil, pas à
part ! ». Même logique que le Masquage — les règles qui influencent
l'anonymisation appartiennent au profil ; un sous-onglet séparé crée la
même confusion.
- Retrait du sous-onglet « Administration > Règles » (_SUBTABS, builder,
méthode _build_regles supprimée). Sous-onglets restants : Réglages /
Profils / Partage.
- Section « Profils > Règles du profil » enrichie : wording clair (règles
d'anonymisation portées par le profil), aperçu illustratif de la table
des règles (réutilise _rule_row + _HELP_REGLES), édition fine annoncée
« à venir ».
- Abandon du « Testeur de règle » (écran outil global) pour ne pas
réintroduire un second réglage métier.
Cible UX : Réglages / Profils (Général・Masquage・Mots・Moteurs・Règles du
profil) / Partage. Test obsolète test_rules_subtab_has_no_unexplained_2
remplacé par test_no_separate_rules_subtab.
262 tests unit OK (0 régression), self-test OK, nav 3 sous-onglets + section
Règles dans Profils + thème OK. Préserve d8bc0cd + GO Qwen. Aucun build/push
sans GO Dom.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Retour Dom : le sous-onglet Masquage séparé créait de la confusion. Le
masquage fait partie de la manière d'anonymiser associée au profil.
- Retrait du sous-onglet « Administration > Masquage » (_SUBTABS, builder,
méthode _build_masquage).
- Section « Profils > Masquage » enrichie : masque manuel requis, template
de masque (lié au profil édité), bouton « Ouvrir l'éditeur de masque »
(fenêtre dédiée) + dossier des templates, et apparence du masque
(couleur, style des marqueurs + aperçu, marges H/V, coins arrondis).
- Le template enregistré depuis l'éditeur remplit désormais le champ
Template du profil (preferred_manual_mask_template via _pro_template_var).
- Profils devient le centre des réglages métier (général/masquage/mots/
moteurs/règles). Réglages inchangé (pas de pastilles, pas de grosse
refonte). Nettoyage du code mort (_REPLACEMENT_CODES, _HELP_MASQUAGE).
261 tests unit OK (0 régression), self-test OK, nav 4 sous-onglets + éditeur
de masque depuis Profils + thème OK. Préserve 72841ed/GO Qwen. Aucun build/
push sans GO Dom.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Retour Dom : remplacer la page vitrine par un vrai éditeur de profils.
- gui_v6/profile_editor.py : couche logique (build_profile_spec,
profile_is_editable runtime vs defaut, list_profile_choices, slug_for_copy,
save/set_default/delete) au-dessus de profile_defaults — persistance dans
config/profiles.yml.
- gui_v6/editable_list.py : EditableTermList (tableau scrollable de termes,
ajout/suppression, pas de pastilles) — reste lisible à 50+ termes.
- tab_config : sous-onglet « 👤 Profils » réintroduit comme éditeur — menu
déroulant « Profil à modifier », boutons Nouveau / Dupliquer / Enregistrer /
Annuler / Définir par défaut, sections Identité, Masquage (require_manual_mask,
template), Moteurs (force_disable_vlm), Mots (à masquer/conserver/ignorer
éditables), Règles « à venir ». Profils défaut = lecture seule (dupliquer
pour modifier). Confirmation non bloquante (pas de modale).
- Réglages : bouton « ✏️ Modifier le profil… » → ouvre Profils sur le profil
actif. Pas de pastilles inline.
Persiste : label, description, require_manual_mask, force_disable_vlm,
preferred_manual_mask_template, param_lists (3 listes). 260 tests unit OK
(0 régression), self-test OK, nav 5 sous-onglets + thème OK. Préserve
1bbe70a/d30f7b7. Aucun build/push sans GO Dom.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Le module usage_telemetry est maintenant réellement branché : la GUI V6
envoie les statistiques au portail après chaque run (les stats web
restaient vides sans cela).
- processing_runner : RunSummary porte une liste DocResult (ordinal,
page_count via page_count_for, status, duration_ms, extension) — peuplée
dans la boucle. Aucun nom/chemin de fichier.
- usage_telemetry : report_run_summary(summary, base_url, license_ref,
machine_id, session, ...) construit le payload depuis le RunSummary et
l'envoie (non bloquant). N'envoie RIEN sans license_ref. Spool JSONL si
échec réseau.
- tab_usage : _finish() déclenche l'envoi en thread daemon (jamais bloquant
pour l'UI ni le run).
- app : fournit le reporter à UsageTab avec le contexte licence (base_url du
LicenseClient, license_ref via local_status, machine_id, app_version).
Tests : RunSummary.documents peuplé (0 chemin) ; report_run_summary (payload
correct, réseau KO → spool sans crash, pas d'envoi sans licence) ; _finish
appelle le reporter. 252 tests unit OK (0 régression), self-test OK.
V5/moteur/app_aivanov intacts, 0 dépendance. Aucun build/push sans GO Dom.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Retour Dom après validation visuelle : simplifier.
- Réglages > Listes locales : suppression des pastilles de termes et des
éditeurs inline (_compact_tag_editor). Remplacés par un texte court +
compteurs (À conserver/À masquer/À ignorer du profil actif) + bouton
« Ouvrir le tableau des termes » qui ouvre DIRECTEMENT TermsTableWindow.
- Retrait du bouton « Voir le profil » (son rôle = accéder au tableau).
- Retrait du sous-onglet « Profils » (doublon non câblé) : _SUBTABS,
builders, _build_profils/_rebuild_profils. Les helpers profil
(_active_profile_summary/_open_terms_table) sont conservés pour Réglages.
- Nettoyage du code mort associé : _compact_tag_editor, constantes
_PRESERVE_TERMS/_MASK_TERMS/_STOPWORDS, textes d'aide qui référençaient
l'onglet Profils.
Chemin utilisateur : Administration > Réglages > Ouvrir le tableau des
termes. 247 tests unit OK (0 régression), self-test OK. Préserve a9e8b2c
(thème, bêta, aide ?, fenêtre tableau). Aucun build/push sans GO Dom.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Phase A de la mission télémétrie d'usage par client.
- gui_v6/usage_telemetry.py :
- page_count_for(path) : PDF→fitz, image→1, autres→None ; best-effort, ne
lève jamais, ne lit que l'extension (jamais le nom).
- build_usage_payload(...) : compteurs (document/succeeded/failed/total_pages)
+ documents filtrés aux seules clés autorisées (ordinal/page_count/status/
duration_ms/extension) → aucun nom/chemin de fichier ne peut fuir.
- UsageTelemetryClient(session injectée) : report() non bloquant (capture
tout, False en cas d'échec réseau) vers POST /api/v1/usage/report.
- spool JSONL local (spool_payload/flush_spool) pour rejouer les échecs.
Module isolé, non câblé au runner pour l'instant (le branchement fin-de-run
viendra après le backend, hors validation visuelle GUI en cours). Aucun
build/push sans GO Dom. 10 tests unitaires (payload sans nom de fichier,
réseau indispo ne crashe pas, compteurs, page_count PDF mockable).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cinq retours utilisateur sur l'exécutable Windows GUI V6.
- Thème : `_render()` vidait les widgets mais conservait le cache
`_tab_frames`/`_visible_tab` → l'onglet Utilisation se vidait (TclError
sur widget détruit) au changement de thème. Reset du cache dans
`_render()` → onglet actif recréé proprement.
- Onglet principal « Configuration » → « Administration » (clé interne
inchangée).
- Sous-onglet « Règles 2 » → « Règles » (le « 2 » était un badge non
câblé).
- Actions de maquette non câblées (Partage Export/Import, Règles Nouvelle
règle/Recharger/Tester/Fermer) désactivées + suffixe « (à venir) » via
`_mockup_button` : plus aucune action morte qui semble fonctionner.
- Aide « ? » restaurée (façon V5) : `ui_kit.HelpButton`/`help_button`
réutilisable ouvrant une fenêtre d'aide en français simple, posée sur
Utilisation, Administration (Réglages/Masquage/Partage/Règles) et
À propos. Partage : phrase visible + aide expliquant qu'on partage les
réglages, jamais les documents patients.
`tests/unit/test_gui_v6_app_shell.py` : régression thème, libellés,
présence d'aide, navigation. 228 tests unit OK (0 régression), self-test
GUI V6 OK. V5/moteur/app_aivanov non touchés, aucune dépendance ajoutée.
Verdict Qwen requis avant push/build/diffusion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remplace l'éditeur de masquage encastré dans l'onglet Configuration —
jugé inutilisable par Dom (document trop à l'étroit, non défilable) —
par une fenêtre dédiée où le document est majoritaire et réellement
navigable.
- gui_v6/mask_editor_model.py : couche logique pure (rectangles par
page, conversions écran↔PDF, hit-test, sérialisation template)
testable sans display ; réutilise MaskRect/Template de
pdf_mask_designer → format de template inchangé (compat moteur).
- gui_v6/mask_editor_window.py : MaskEditorWindow (CTkToplevel)
redimensionnable — canvas + scrollbars H+V câblées + molette (le
manque qui rendait l'éditeur inutilisable), zoom + ajuster
largeur/page, navigation pages, rectangles au glisser-déposer,
sélection (clic) + suppression (Suppr / clic-droit), templates
JSON/YAML, mode aperçu d'exemple sans PDF.
- tab_config.py : l'onglet Masquage lance la fenêtre dédiée ; retrait
du canvas encastré et de ~290 lignes de code mort associé.
- tests/unit/test_gui_v6_mask_editor.py : 13 tests logique + 3 smoke
headless (scrollbars, ajout/sélection/suppression, save/load
roundtrip, câblage onglet→fenêtre).
Sans nouvelle dépendance. V5, moteur et app_aivanov non touchés.
221 tests unit OK (0 régression), self-test GUI V6 OK.
Verdict Qwen requis avant push/build/diffusion.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>