# Challenge des plans d'action — Dashboard & VWB _16 avril 2026 — critique transversale des deux plans du 15 avril, avant exécution._ _Lecture ciblée : 10 minutes. Aucune modification de code. Ton direct._ --- ## Section 0 — Verdict global Les deux plans sont **globalement justes**, bien structurés, honnêtes sur la dette. Mais : - **Le plan Dashboard** sous-estime le couplage avec l'audit trail backend (risque cascading), et pousse un onglet Audit un peu trop ambitieux pour un POC qui démarre dans 2 semaines. - **Le plan VWB** a une bonne hiérarchie mais **deux erreurs factuelles** (B5 vise le mauvais frontend, et la "bibliothèque qui s'efface" peut avoir une cause simple non explorée) et rate une priorité réelle : **le backup automatique des workflows n'existe pas**. - **Aucun des deux plans ne parle à l'autre** — ils pourraient se contredire sur correction_packs et sur l'audit. Recommandation : exécuter VWB quick wins en priorité (impact immédiat pour Dom), puis Dashboard cleanup, puis audit MVP. PAS l'onglet Audit "DSI-ready complet" avant le POC Anouste. --- ## Section 1 — Dashboard : ce qui tient, ce qui ne tient pas ### 1.1. Ce qu'on valide tel quel - **Retirer onglet 🧪 Tests (B1)** — correct, la RCE implicite via pytest subprocess est réelle, à éjecter sans regret. - **Retirer onglet ⚡ Exécution (B4)** — la logique Agent V1 a déprécié l'ancien SocketIO `subscribe_execution`, plus personne ne regarde ça. - **Retirer pages auxiliaires `/chat`, `/gestures`, `/streaming`, `/extractions`** — doublons morts. Bonne décision. - **Section E (non-décisions)** — tout est juste : pas de React, pas de SSO, pas de WebSocket Audit. Sagesse YAGNI. ### 1.2. Ce qu'on ajuste **B2 — Retirer onglet 🧠 Apprentissage** Le plan dit "10 min". Challenge : l'onglet affiche `statCorpusSize` qui est peut-être câblé ailleurs (conftest, training worker, etc.). Avant de retirer, vérifier qu'aucun autre consommateur (jobs, scripts) ne dépend de ces routes. Budget réaliste : **20-30 min** pour grep + vérifier, pas 10. **B5 — Retirer onglet 📊 Vue d'ensemble** "30 min" pour retirer + "fusionner un mini-résumé (4 KPIs) en tête de Services" — la fusion n'est pas gratuite. Si Dom veut garder les 4 KPIs, compter **1 h** (déplacement + CSS + test). Si on retire franc et net sans fusion, alors **15 min**. Trancher maintenant. **Estimation onglet Audit MVP (0.75 j)** C'est réaliste **à condition** que le proxy Flask `/api/audit/*` → 5005 soit vraiment du copy-paste du pattern `/api/streaming/*`. Mais le plan omet : - Côté streaming server, le token `RPA_API_TOKEN` est requis → le dashboard doit le propager (fait par le pattern `/api/streaming` mais pas mentionné dans le plan Audit). - Le volume de données est surestimé : "1 800 entrées aujourd'hui" **faux** — 18 entrées aujourd'hui dans `audit_2026-04-15.jsonl`, 430 le jour de test du 13 avril. Le volume réel est faible, la pagination serveur n'est pas critique pour le POC. **Rapport PDF DSI (0.5 j)** Sous-estimé. ReportLab/WeasyPrint sur une page A4 avec tableau + signature d'intégrité, c'est plutôt **1 j**, à cause du templating, de la gestion des polices, du tableau qui déborde, des caractères accentués (French), et surtout du hash chain (voir 1.3). **Signature d'intégrité journalière (SHA-256)** Le plan dit "20 lignes". Réaliste côté code, mais il faut : - décider quand la clôture journalière a lieu (minuit UTC ? heure locale ?), - stocker les hashes quelque part (fichier `.sig` ? table `audit_signatures` ?), - rejouer la vérification facilement (`python -m tools.verify_audit YYYY-MM-DD`). Compter **0.5 j** honnête, pas 0.25. ### 1.3. Ce qu'on retire du plan **Alerting seuil d'échecs (0.5 j en Sprint 3)** Pourquoi on le sort : le dashboard est un outil interne déjà bien chargé. Un "badge rouge si >N échecs/h" sans destinataire email configuré = gadget visuel. Si un jour il y a un vrai besoin RSSI, ça passe par n8n (déjà dans le stack) ou Prometheus alerting. **Ne pas le coder ici.** **Widgets graphiques (camembert + courbe 7j)** Pas avant validation MVP par un vrai DSI. Le tableau + filtres + export CSV suffisent pour 90 % des cas d'usage. Les graphiques, c'est du polish, à faire après retour client. ### 1.4. Ce qu'on ajoute **Backup BDD workflows VWB dans l'onglet Sauvegardes** Aujourd'hui `/api/backup/*` côté dashboard ne touche probablement pas à `visual_workflow_builder/backend/instance/workflows.db`. Or c'est là que vivent les 3 workflows réels de Dom. À vérifier et intégrer au cron backup. **Critique pour le POC.** **Lien explicite Dashboard → VWB** Si on retire les onglets "Workflows" et "Corrections", il faut un bouton "Ouvrir VWB" visible. Le plan le mentionne en passant dans "Services" mais ne le tranche pas. À préciser. **Health check streaming server** L'onglet Streaming affiche les sessions, mais pas le statut du serveur 5005. Si le serveur tombe, Dom voit l'iframe vide sans message clair. Ajouter un check explicite côté dashboard. --- ## Section 2 — VWB : ce qui tient, ce qui ne tient pas ### 2.1. Ce qu'on valide tel quel - **B2 (Unnamed Workflow)** — 20 min, impact immédiat, bon. - **B3 (supprimer vwb_v3.db fantôme)** — 15 min, risque réel identifié. Oui. - **B4 (double logging)** — confirmé dans les logs (chaque ligne présente 2×), 15 min, fait. - **B6 (nettoyer fichiers parasites)** — hygiène, 10 min. - **B7 (run.sh clarification)** — 20 min, évite que Dom et nous lancions le mauvais frontend. - **Sections D et E (non-décisions)** — toutes justifiées. ### 2.2. Ce qu'on ajuste **B1 — Migrer sessionStorage → localStorage** Challenge fort : le plan dit "30 min → résout le bug principal". Je ne suis pas convaincu que `sessionStorage` soit la **seule** cause du bug "la bibliothèque s'efface tout le temps". Hypothèses alternatives à tester **avant** de coder : 1. L'utilisateur ouvre un nouvel onglet (vrai effacement sessionStorage, OK). 2. Un StrictMode React qui double-mount et écrase le state. 3. Un `setCaptureLibrary([])` appelé par erreur dans un `useEffect` sans dépendance. 4. Une exception silencieuse qui reset l'état (QuotaExceededError de sessionStorage si > 5 Mo de base64 PNG). **Le plan saute direct à la solution sans diagnostic.** Avant de migrer, **reproduire le bug 2 minutes avec la console ouverte** pour voir *quand* il se déclenche. Si c'est un quota, localStorage ne sauvera rien (même limite). **Ne pas coder avant de comprendre.** Sous réserve que ce soit bien sessionStorage, la migration localStorage est bonne, mais : - clé `captureLibrary_v3` : bien de ne PAS migrer les deux anciennes clés automatiquement (laisser Dom perdre l'historique mauvais, repartir propre). - cap 200 captures : OK mais thumbnails JPEG 200×150 q=0.7 au lieu de PNG base64 **impératif** sinon on fait sauter le quota en 15 captures. Budget réaliste : **1 h** (diagnostic 15 min + migration 30 min + compression thumbnail 15 min). **B5 — Supprimer 404 /api/correction-packs/stats** **Erreur factuelle dans le plan** : B5 dit que l'appel vient de `frontend/src/hooks/useCorrectionPacks.ts` (legacy). Confirmé par grep. Mais le plan n'explique pas **pourquoi on voit ces 404 aujourd'hui alors que seul frontend_v4 tourne**. Deux possibilités : 1. Un onglet legacy resté ouvert dans le navigateur — triviale. 2. Un proxy dashboard appelle la route — à vérifier. Si c'est (1), fermer l'onglet suffit, pas besoin de stubber. Si c'est (2), stubber. Mais **avant de coder, regarder qui appelle**. Budget : **10 min d'enquête + 10 min de fix éventuel**. **C1 — Finaliser flux Import Léa → review → replay (1 j)** Sous-estimé. Le plan liste 4 actions, dont "Bouton 'Valider et exécuter' qui passe `review_status='approved'` puis lance le replay via `/execute`". Mais : - Le `/execute` VWB utilise l'IRBuilder local, pas le replay server Agent V1 (port 5005). Divergence d'exécution. - Le flux "replay" réussi du 13 avril passe par Agent V1, pas par VWB. Le bouton "Valider et exécuter" dans VWB va donc **exécuter avec un autre moteur** que celui qui a produit le workflow. - Question non résolue : si Dom valide un workflow importé et que l'exécution VWB échoue, alors qu'Agent V1 l'avait réussi, c'est quoi la vérité ? Budget réaliste : **2 j**, avec obligation de clarifier "qui exécute quoi" avant de coder le bouton. **C5 — Lier step ↔ screenshot source (2 j)** C'est la vraie valeur. Le plan dit que les workflows Léa "contiennent déjà des `screenshot_hash` dans leurs nodes (à vérifier dans notepad_enriched.json)". Le "à vérifier" est critique. Si ce n'est pas le cas, il faut **d'abord modifier le format d'export Léa** avant de toucher VWB, ce qui triple la durée. **Prérequis à lever avant de s'engager sur cet item.** ### 2.3. Ce qu'on retire du plan **C4 — Consolider les 3 app*.py (1 j)** Pas avant le POC. Zero impact utilisateur, risque de régression sur le seul endpoint VLM de `app_lightweight.py`. On garde en backlog "quand bande passante". Le plan le met en semaine 3+, correct, mais le listing en quick win serait une tentation. **C2 — Persister bibliothèque serveur (1.5 j)** Si B1 fait vraiment son job avec localStorage + compression thumbnails, le serveur n'est pas nécessaire pour le POC. **Ne démarrer C2 que si B1 échoue en usage réel.** Le plan le dit ("si B1 montre ses limites"), mais ne le chiffre pas comme optionnel dans la roadmap — le sortir explicitement. ### 2.4. Ce qu'on ajoute **Backup quotidien de `workflows.db`** Le plan le liste dans "Risques" mais ne le met pas comme action. C'est la seule BDD qui contient le travail manuel de Dom. **1 ligne dans `backup_ssd.sh`** (ou cron local). Critique avant POC. **15 min.** **Versionnement simple des workflows** Aucun des 2 plans n'en parle. Scénario : Dom modifie un workflow importé, casse quelque chose, veut revenir en arrière. SQLAlchemy n'a pas de versioning natif. Proposition minimale : à chaque `PUT /api/v3/workflow/`, dumper le JSON avant modification dans `data/vwb/workflow_history//.json`. **30 min**, zero dépendance, ROI fort. **Nom clair du projet dans la liste VWB** Si Dom importe 28 workflows du poste DESKTOP-58D5CAC, il va se noyer. Ajouter un filtre par machine + status (pending_review / approved / rejected) dans `WorkflowList.tsx`. **45 min**, grande valeur UX. --- ## Section 3 — Vision système transverse ### 3.1. Dépendances oubliées entre les deux plans **Audit trail parle à VWB ?** Le plan Dashboard mentionne `workflow_id` et `workflow_name` dans les colonnes Audit. Or : - Côté Agent V1, le `workflow_id` est celui du JSON disque. - Côté VWB, les workflows ont un `id` SQLAlchemy distinct. - Quand un workflow est importé dans VWB (source='learned_import'), le mapping entre les deux IDs n'est pas explicite. Conséquence : un DSI qui filtre "workflow = X" dans l'Audit risque de ne pas retrouver le workflow correspondant dans VWB. **À clarifier** avant le sprint Audit MVP. **Correction packs : 2 plans, 2 décisions contradictoires** - Plan Dashboard : "supprimer onglet Corrections, les packs sont gérés dans VWB." - Plan VWB section E3 : "Ne PAS porter CorrectionPacksDashboard sur le v4 — fermer proprement correction_packs." Les deux disent "on ne fait plus de correction packs ici", mais personne ne dit **où ils vivent maintenant**. Si la réponse est "plus nulle part", il faut archiver proprement les données historiques (packs déjà produits) et le déclarer explicitement. **Frontend legacy partagé ?** Le 404 `/api/correction-packs/stats` vient du frontend legacy VWB. Mais il ne serait pas impossible qu'un iframe du dashboard (onglet Corrections) l'ait aussi chargé. Si on retire l'onglet Dashboard **avant** de retirer le frontend legacy VWB, on ne supprime qu'une moitié du problème. ### 3.2. Ordre d'attaque recommandé **VWB quick wins AVANT Dashboard cleanup.** Raisons : 1. Dom utilise VWB quotidiennement, le bug captures le bloque tout de suite. 2. VWB a des erreurs factuelles à résoudre en amont (diagnostic B1, source des 404). 3. Un Dashboard cleanup, ça se fait en 1 push, le VWB nécessite diagnostic → étaler. ### 3.3. Points d'intégration critiques - **Token RPA_API_TOKEN** — doit être propagé Dashboard → streaming 5005 (audit) et VWB → streaming 5005 (replay). Fragile si Dom modifie `.env`. **Ajouter un check au démarrage.** - **Base `workflows.db`** — partagée entre backend VWB et (potentiellement) Agent V1. Vérifier qu'aucune écriture concurrente n'existe (locks SQLite). - **Volumes `data/audit/` et `data/training/sessions/`** — doivent être dans le backup quotidien. À vérifier dans `backup_ssd.sh`. --- ## Section 4 — Ce qui n'est pas dans les plans mais devrait y être Par ordre de priorité pour le POC Anouste : 1. **Backup quotidien de `workflows.db` et `data/audit/`** Aujourd'hui un seul backup du 23/01 dans `backend/instance/backups/`. Si un disque meurt, Dom perd ses 3 workflows de démo + 10 jours d'audit. **Bloquant POC.** 15 min. 2. **Versionnement basique des workflows VWB** Snapshot à chaque PUT. 30 min. Zero dépendance. Fort ROI dès le 2e client. 3. **Mode dégradé "streaming server indisponible"** Aujourd'hui si port 5005 tombe, VWB et Dashboard affichent des erreurs cryptiques. Ajouter un badge "Streaming KO — Léa en pause" partout. 1 h. 4. **Isolation multi-client** Le jour où Anouste + un second client tournent sur la même instance, il n'y a aucune séparation (BDD, audit, sessions). Avant le POC DGX, décider : 1 instance par client ou tag `client_id` partout ? À trancher avec Dom **avant** de coder l'onglet Audit (sinon on refait le schéma). 5. **Observabilité unifiée** Prometheus existe côté dashboard (`/metrics`), mais pas côté VWB ni streaming server. Pour un hôpital, "pourquoi c'est lent aujourd'hui" = question fréquente. Ajouter 3 métriques clés (replay_duration_ms, vlm_call_ms, faiss_search_ms) exposées en Prometheus sur les 3 services. 2 h. 6. **Documentation d'installation POC** Ni DEV_SETUP.md ni README n'expliquent comment déployer l'ensemble chez un client. `run.sh --full` suppose l'environnement Dom. Pour Anouste il faut une procédure, sinon c'est Dom qui installe à la main. 2 h. 7. **Anonymisation des logs pour export** Si un DSI exporte le CSV Audit, il récupère `user_name = "Marie Dupont"`. Fine pour un audit interne, problématique pour une démo publique. Prévoir un flag `--anonymize` sur l'export. 30 min. 8. **Concurrence dashboard** Aucune protection : 2 onglets ouverts = 2 actions possibles en parallèle. Pour le POC mono-utilisateur ça passe, à tracer pour multi-TIM. --- ## Section 5 — Roadmap recommandée révisée (4 jours) **Contexte** : POC Anouste dans ~2 semaines. DGX pas encore arrivé. Fenêtre technique ouverte mais finie. ### Jour 1 (4 h) — Sécuriser le quotidien de Dom - VWB B3 (vwb_v3.db fantôme) : 15 min - VWB B4 (double logging) : 15 min - VWB B6 (fichiers parasites) : 10 min - VWB B7 (run.sh) : 20 min - **NOUVEAU** — backup quotidien `workflows.db` + `data/audit/` : 15 min - VWB B2 (Unnamed Workflow) : 20 min - **Diagnostic B1** (bibliothèque captures, pas de code) : 30 min - VWB B1 (localStorage + thumbnails JPEG) : 1 h - Reste : commit + test manuel + pause café. **Sortie** : Dom ne perd plus ses captures, ses workflows sont sauvegardés, les logs sont lisibles. ### Jour 2 (4-6 h) — Dashboard cleanup + audit MVP backend - Dashboard B1→B6 (retirer 5 onglets + pages mortes) : 2 h - **NOUVEAU** — vérifier proxy `workflow_id` VWB ↔ Audit : 30 min - Dashboard — onglet Audit MVP (proxy + tableau + filtres + export CSV) : 3 h - **NON** : pas de PDF, pas de patient_ref_hash, pas d'alerting, pas de graphiques. **Sortie** : dashboard à 9 onglets propres, onglet Audit fonctionnel pour démo POC. ### Jour 3 (4-6 h) — Flux Léa → VWB → replay (C1) - Diagnostic source des 404 correction-packs/stats : 15 min, fix si nécessaire - **NOUVEAU** — versionnage workflows VWB (snapshot avant PUT) : 30 min - **NOUVEAU** — filtre machine + status dans WorkflowList : 45 min - C1 étape 1 : vérifier `pendingReviewCount` + banner : 1 h - C1 étape 2 : warnings visuels sur steps importés : 1 h - C1 étape 3 : bouton "Valider et exécuter" **avec clarification** qui exécute (Agent V1 ou VWB) : 2 h **Sortie** : Dom peut importer un workflow Léa, voir les étapes floues, corriger, relancer. ### Jour 4 (4 h) — Hardening POC Anouste - **NOUVEAU** — mode dégradé streaming KO (3 services) : 1 h - **NOUVEAU** — 3 métriques Prometheus sur VWB + streaming : 2 h - **NOUVEAU** — doc installation POC (README_DEPLOY_POC.md) : 1 h **Sortie** : POC déployable chez Anouste, observable, résilient aux pannes. ### Ce qu'on garde en backlog (pas avant POC) - VWB C3 (retirer frontend legacy), C4 (consolider app*.py), C5 (screenshot source par step), C2 (captures serveur) - Dashboard Sprint 3 complet (PDF DSI, patient_ref_hash, signature intégrité, widgets, alerting) - Dashboard Sprint 4 (améliorations Services, Sessions, Logs, Config) --- ## Section 6 — Risques à surveiller pendant l'exécution | # | Risque | Probabilité | Impact | Mitigation | |---|---|---|---|---| | R1 | B1 localStorage ne résout pas le vrai bug (cause racine différente) | Moyenne | Moyen | Diagnostic avant code. 15 min budgétées. | | R2 | Suppression d'un onglet Dashboard casse un script externe qui appelait la route | Faible | Moyen | Grep workspace complet avant suppression. `n8n`, `agent_chat`, `core` peuvent consommer. | | R3 | Proxy dashboard→streaming 5005 échoue sur token RPA_API_TOKEN | Moyenne | Moyen | Reproduire le pattern `/api/streaming/*` à la lettre. Tester avec `curl` direct avant UI. | | R4 | Workflow importé non rejouable (format Léa incompatible bridge) | Moyenne | Fort | Tester C1 sur le workflow `notepad_enriched.json` en premier. Si KO, pivoter sur C5 avant C1. | | R5 | `workflow_id` Audit ≠ `id` VWB → filtre DSI casse | Forte | Faible (hors POC) | Documenter dans l'export CSV : "workflow_id = source disque, voir VWB pour UI". Fix propre post-POC. | | R6 | Backup `workflows.db` oublié, crash disque avant POC | Faible | Critique | Backup manuel aujourd'hui, automatisation demain. | | R7 | Cleanup Dashboard supprime une route consommée par Agent V1 | Faible | Fort | Routes retirées : `/api/automation/*`, `/api/tests/*`, `/api/gestures`, `/api/chat/*`. Grep avant. | | R8 | Onglet Audit "demi-fonctionnel" montré à Anouste produit plus de méfiance que rien | Moyenne | Fort | MVP uniquement (tableau + filtres + CSV). Pas de widgets creux. | | R9 | Régression frontend v4 après suppression legacy (C3 reporté, donc risque faible immédiat) | Faible | Moyen | C3 **pas en roadmap 4 jours**. Post-POC. | | R10 | Exécution VWB diverge de replay Agent V1 → incohérence démo | Forte | Fort | Clarifier quel moteur exécute en bouton "Valider et exécuter". Préférer Agent V1 via appel 5005. | | R11 | AI Act / RGPD — absence de patient_ref_hash repérée par DSI Anouste | Faible (POC early) | Moyen | Documenter la limitation dans DOSSIER_COMMISSAIRE_AUX_APPORTS. Planifier Sprint 3 post-POC. | | R12 | 2 personnes éditent workflows.db simultanément (Dom + un TIM pendant démo) | Faible (POC mono) | Fort | SQLite verrou exclusif = erreur propre. Documenter "VWB mono-utilisateur pour l'instant". | --- ## Résumé exécutif pour Dom 1. **Commence par VWB B3+B4+B6+B7+backup (1 h 30)** — hygiène, zéro risque, gains immédiats. 2. **Puis diagnostic B1 AVANT de coder** — 15 min pour éviter de coder une fausse solution. 3. **Dashboard cleanup + Audit MVP (1 journée)** — retire les onglets morts, ajoute l'onglet Audit minimal. Pas de PDF ni d'alerting avant retour client. 4. **Flux C1 (1 journée)** — la vraie valeur visible de ton idée "importer Léa, corriger". 5. **Hardening POC (demi-journée)** — backups, métriques, doc deploy. Sinon le POC Anouste sera douloureux. 6. **Tout le reste (C2, C3, C4, C5, Dashboard Sprint 3-4) : après POC.** Les deux plans sont solides. Ils manquent juste de **connexions entre eux** et sous-estiment **le hardening POC**. Ce document les relie et priorise pour la fenêtre de 2 semaines avant Anouste. --- _Fin du challenge — 16 avril 2026._