Point de sauvegarde incluant les fichiers non committés des sessions précédentes (systemd, docs, agents, GPU manager). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
18 KiB
Plan d'action — Dashboard Web RPA Vision V3
Date : 2026-04-15 — périmètre : web_dashboard/ (port 5001). Auteur : audit technique (lecture seule, aucune modif de code).
Objectifs :
- faire le ménage dans un dashboard qui a grossi par sédimentation,
- préparer l'onglet Audit & Traçabilité attendu par les clients (AI Act / RGPD),
- donner à Dom une roadmap actionnable et priorisée.
Section A — Inventaire
Le dashboard a aujourd'hui 14 onglets déclarés dans web_dashboard/templates/index.html (3 455 lignes) plus des pages auxiliaires (chat.html, gestures.html, extractions.html, streaming.html). Le backend Flask (web_dashboard/app.py, 2 665 lignes) expose ~65 routes HTTP + 4 events SocketIO.
| # | Onglet (label UI) | Routes backend principales | État | MAJ estimée | Utile ? |
|---|---|---|---|---|---|
| 1 | 🎛️ Services | /api/services*, /api/version* |
OK — fonctionne, utilisé quotidiennement | avril 2026 | oui, cœur |
| 2 | 📊 Vue d'ensemble | /api/system/status, SocketIO |
OK partiel — statTests et statExecution remplis par legacy |
mars 2026 | doublonne avec Services |
| 3 | ⚡ Exécution | /api/automation/*, SocketIO subscribe_execution |
Douteux — branché sur le moteur v1 core, pas sur Agent V1 streaming (5005). Le replay réel passe par VWB ou /api/v1/traces/stream/replay* |
janv. 2026 | non en l'état — obsolète face au flux replay actuel |
| 4 | 🔄 Workflows | /api/workflows*, /api/chains*, /api/triggers* |
OK liste, exécution via /api/workflows/<id>/execute redondante avec VWB et Agent V1 |
janv.-mars 2026 | partiel — la liste oui, l'exécution non |
| 5 | 📦 Sessions | /api/agent/sessions* |
OK — affiche bien les sessions dans data/training/sessions/ |
avril 2026 | oui mais se recoupe avec le cleaner (5006) |
| 6 | 📈 Performance | /api/system/performance, /api/system/faiss/test, /metrics |
OK — FAISS + Prometheus + cache hit | mars 2026 | oui, utile debug/benchmark |
| 7 | 📡 Streaming | proxy vers http://localhost:5005/api/v1/traces/stream/* |
OK — lecture seule, bonne visibilité live sessions | mars 2026 | oui, cœur Agent V1 |
| 8 | 📄 Logs | /api/logs, /api/logs/download |
OK minimaliste — lit logs/*.log, pas de filtre/tail |
nov. 2025 | utile ponctuel, pourrait disparaître si Audit bien fait |
| 9 | 🧪 Tests | /api/tests* (subprocess pytest) |
Cassé en prod — pytest non dispo sur cible packagée, timeout 120s bloque l'UI, aucun droit d'exécuter pytest depuis une UI exposée sur Internet | mars 2026 | NON — à retirer |
| 10 | 💾 Sauvegardes | /api/backup/* |
OK — exports fonctionnels | janv. 2026 | oui, valeur clairement réglementaire |
| 11 | 🔧 Corrections (packs) | routes ailleurs (VWB / API core) — onglet affiche des stats | Cassé — refreshCorrectionPacks appelle une route qui n'existe plus côté dashboard, données via VWB |
févr. 2026 | à supprimer côté dashboard, garder côté VWB |
| 12 | 🧠 Apprentissage | idem : placeholders statCorpusSize, charts Chart.js non alimentés |
Cassé/placeholder — aucune route backend ne nourrit les 4 stat-cards ni les 2 canvas | janv. 2026 | NON — à retirer ou refaire sérieusement |
| 13 | 🔧 Configuration | /api/config*, /api/config/ollama-models, /api/config/test-connection |
OK — édition ports/modèles/DB/sécurité/logs | avril 2026 | oui (utile admin) |
| 14 | 🧹 Nettoyage | iframe → http://localhost:5006 |
OK — ajouté hier, dépend du service session_cleaner | avril 2026 | oui |
Pages auxiliaires (templates séparés, non liées aux onglets) :
| Page | Route | État | Verdict |
|---|---|---|---|
/chat |
chat.html + /api/chat/* |
OK expérimental — utilisé en dev | doublonne Agent Chat (5004), à supprimer ici |
/gestures |
gestures.html + /api/gestures |
Mort — aucune donnée, concept abandonné | à supprimer |
/extractions |
extractions.html + /api/extractions* |
Douteux — fonctionnalité concurrente au plan Data Extraction prévu via VWB | à geler/archiver |
/streaming |
streaming.html |
Doublon — remplacé par l'onglet Streaming intégré dans index.html |
à supprimer |
SocketIO : 4 events (connect, disconnect, subscribe_execution, get_performance). Seul connect/disconnect sert aujourd'hui — le reste alimente l'onglet Exécution qui va disparaître.
Section B — À virer (cleanup)
Dans cet ordre, à faire en un seul coup (effort total estimé : 2 à 3 heures).
-
Onglet 🧪 Tests (lignes 67, 499-517 de
index.html; routes 1006-1094 deapp.py)- Pourquoi : exécuter
pytestdepuis une UI auth Basic exposée sur Internet est une RCE déguisée. Et ça plante en prod. Les tests se lancent en CLI. - Effort : 20 min.
- Pourquoi : exécuter
-
Onglet 🧠 Apprentissage (lignes 70, 665-720)
- Pourquoi : placeholders, aucune route backend, induit le client en erreur.
- Alternative : soit on le refait proprement dans l'onglet Audit & Traçabilité (stats globales sur trace d'exécution), soit on l'enlève.
- Effort : 10 min (retrait).
-
Onglet 🔧 Corrections (lignes 69, 603-664)
- Pourquoi : les correction packs sont gérés dans VWB, pas ici. L'onglet affiche des cartes qui ne se remplissent plus. Ajouter un simple bouton "Ouvrir VWB" dans l'onglet Services suffit.
- Effort : 10 min.
-
Onglet ⚡ Exécution (lignes 61, 197-233)
- Pourquoi : branché sur l'ancien moteur core via SocketIO
subscribe_execution. Aujourd'hui le replay passe par l'Agent V1 et VWB. L'onglet Streaming couvre déjà le live. - Effort : 15 min (retrait + supprimer les 4 routes
/api/automation/*).
- Pourquoi : branché sur l'ancien moteur core via SocketIO
-
Onglet 📊 Vue d'ensemble (lignes 60, 162-194)
- Pourquoi : 4 stat-cards dupliquées depuis Services + Sessions + Workflows. Un
perfChartqui duplique ce qui est dans Performance. - Alternative : fusionner un mini-résumé (4 KPIs) en tête de l'onglet Services, ce qui fait gagner un clic. Puis supprimer l'onglet.
- Effort : 30 min.
- Pourquoi : 4 stat-cards dupliquées depuis Services + Sessions + Workflows. Un
-
Pages auxiliaires
/chat,/gestures,/streaming,/extractions- Pourquoi : concurrence avec services dédiés (Agent Chat 5004, VWB, plan Data Extraction) ou fonctionnalités mortes (gestures).
- Effort : 15 min (supprimer templates + routes Flask).
-
Code mort résiduel
execution_state,performance_metrics(globales module) : utiles uniquement si Exécution / Overview subsistent.chain_manager,trigger_manager,automation_scheduler: à évaluer, probablement à garder côté moteur mais retirer l'UI.- Effort : 30 min.
Résultat visé : de 14 onglets à 8 onglets (Services, Sessions, Performance, Streaming, Logs, Sauvegardes, Config, Nettoyage) + 1 nouveau (Audit). Soit 9 onglets utiles et alimentés.
Section C — À garder mais améliorer
Par priorité.
-
🎛️ Services — ajouter un bandeau "santé globale" (somme du statut des 6 services critiques + streaming server + session cleaner) et rapatrier les 4 stat-cards de "Vue d'ensemble" en tête. Effort : 1 h.
-
📦 Sessions — ajouter un filtre par statut (pending/processing/completed/failed — la donnée existe déjà dans
PROCESSING_STATUS_FILE). Ajouter un bouton "Voir dans le cleaner" qui ouvre l'onglet Nettoyage pré-filtré sur la session. Effort : 1 h. -
📄 Logs — passer en lecture "tail -f" WebSocket plutôt que polling d'un fichier entier. Filtrer par niveau (INFO/WARN/ERROR) côté serveur. Effort : 2 h. Faible priorité : une fois l'onglet Audit en place, 90 % de l'usage métier disparaît.
-
📈 Performance — la section FAISS est bonne. Retirer les deux graphiques Chart.js
cacheChartetfaissChart: ils se redessinent toutes les 5s avec un tableau vide au reload, c'est du bruit visuel. Effort : 20 min. -
🔧 Configuration — documenter dans un tooltip chaque champ (DASHBOARD_PASSWORD, RPA_API_TOKEN, etc.) et signaler clairement les secrets. Ajouter un bouton "Recharger les modèles Ollama" déjà présent mais discret. Effort : 1 h.
Aucune amélioration pour Streaming, Sauvegardes, Nettoyage : ils sont récents et suffisants.
Section D — Nouvel onglet "⚖️ Audit & Traçabilité"
Ce que l'utilisateur voit
Une table paginée des actions Léa, précédée de filtres, avec export CSV.
Bandeau haut — 4 KPIs aujourd'hui :
- Actions totales (24 h)
- Taux de succès global
- Nombre de TIMs actifs
- Applications cibles touchées
Zone de filtres (ligne horizontale) :
- Période (preset : Aujourd'hui / 7j / 30j / personnalisée via deux date pickers)
- Collaborateur (dropdown peuplé via
/api/v1/audit/summary→by_user) - Application métier (dropdown, peuplé via le champ
target_appdes entrées) - Type d'action (click, type, key_combo, wait)
- Résultat (success / failed / recovered / skipped)
- Mode d'exécution (autonomous / assisted / shadow)
- Workflow (dropdown si < 50, sinon champ texte)
- Recherche libre (matche
action_detail)
Boutons d'action (à droite du bandeau) :
- 📥 Exporter CSV (respecte les filtres courants)
- 📄 Rapport PDF pour DSI (génération simple, voir ci-dessous)
- 🔄 Actualiser
Tableau principal (colonnes dans cet ordre) :
| Colonne | Source AuditEntry |
Remarque |
|---|---|---|
| Horodatage | timestamp |
affichage local HH:mm:ss · JJ/MM |
| Collaborateur | user_name ou fallback user_id |
|
| Poste | machine_id |
utile multi-sites |
| Application | target_app |
DPI, Orbis, DxCare, navigateur… |
| Action | action_type + badge |
icône par type |
| Détail | action_detail |
tronqué à 80 car., tooltip complet |
| Mode | execution_mode |
badge coloré |
| Résultat | result |
vert/rouge/orange |
| Récup. | recovery_action |
uniquement si result != success |
| Durée | duration_ms |
ms → s si > 1 s |
| Workflow | workflow_name ou workflow_id tronqué |
lien vers détail workflow |
Ligne cliquable → panneau latéral avec le JSON complet (+ critic_result, resolution_method, session_id, action_id). Ce panneau sert aux audits techniques.
Pagination serveur (limit 100, offset) — le backend /api/v1/audit/history gère déjà.
Widgets complémentaires (en dessous du tableau) :
- Camembert "répartition par application" (utile DSI pour visualiser le périmètre Léa)
- Courbe "taux d'échec sur 7 j" (seuil d'alerte ajustable)
- Liste "Top 10 échecs récents" — pour qu'un TIM/RSSI identifie vite les workflows à retoucher
Sources de données — ce qui existe déjà
Tout le backend est déjà là côté streaming server (port 5005) :
- Module
agent_v0/server_v1/audit_trail.py—AuditTrailavecrecord(),query(),get_summary(),export_csv(). - Endpoints FastAPI déjà en place :
GET /api/v1/audit/history— historique filtrable paginéGET /api/v1/audit/summary?date=YYYY-MM-DD— résumé du jourGET /api/v1/audit/export— export CSV
- Données réelles présentes dans
data/audit/audit_YYYY-MM-DD.jsonl(7 fichiers, ~500 ko sur les 10 derniers jours, ~1 800 entrées aujourd'hui).
Ce qu'il manque
- Proxy Flask côté dashboard (5001 → 5005) — sur le modèle de
/api/streaming/<path:endpoint>qui existe déjà (app.py:2505). Coût : ~30 lignes. - Template HTML + JS — nouvel onglet dans
index.html, ~300 lignes. Pas de framework : réutiliser le style et Chart.js existant. - Champ patient pseudonymisé : actuellement pas présent dans
AuditEntry. Décision nécessaire :- Option A (recommandée) : ajouter un champ optionnel
patient_ref_hash(SHA-256 tronqué du n° patient), alimenté quand Léa extrait ou saisit un identifiant patient. Coût : ajout d'un champ dataclass + propagation dans 2-3 endroits au niveau exécuteur. - Option B : n'en pas mettre pour le POC Anouste, préciser dans la doc DSI.
- Option A (recommandée) : ajouter un champ optionnel
- Rapport PDF DSI — simple template ReportLab ou WeasyPrint, une page A4 avec en-tête (client, période, nombre d'actions, signature hash des logs source pour intégrité), puis le tableau filtré. Coût : ~150 lignes + 1 dép.
Effort estimé
| Lot | Jours·homme |
|---|---|
| Proxy Flask + nouvel onglet (MVP : tableau + filtres + export CSV) | 0.5 |
| Widgets graphiques (camembert + courbe 7j) | 0.25 |
| Rapport PDF DSI | 0.5 |
Champ patient_ref_hash (option A) |
0.5 |
| Alerting (si > N échecs consécutifs sur 1 h → badge rouge + email optionnel) | 0.5 |
| Total MVP (sans PDF ni patient) | 0.75 j |
| Total version "complète DSI-ready" | ~2.25 j |
Réglementaire — ce qui est adressé
- AI Act, article 12 — "Record-keeping" : les systèmes d'IA à haut risque doivent automatiquement enregistrer les événements pertinents. L'onglet rend visibles et exportables les logs qui existent déjà côté serveur. Respect du critère traçabilité permanente.
- AI Act, article 14 — "Human oversight" : le champ
execution_mode(shadow/assisted/autonomous) documente le niveau de supervision humaine pour chaque action. - RGPD, article 30 — registre des traitements : champ
target_app+domainpermettent de produire un inventaire des traitements par application métier. - RGPD, article 32 — intégrité : ajouter un hash SHA-256 du fichier JSONL signé à la clôture journalière (coût marginal, 20 lignes) garantit la non-falsification.
- RGPD, article 33 — notification de violation : l'alerting (> N échecs sur fenêtre glissante) est la brique technique qui permet à un RSSI d'être notifié.
Exemple concret — "un DSI hospitalier demande un audit"
Scénario : le DSI du CH d'Auch veut montrer à son directeur que Léa n'a jamais validé seule une codification CIM-10 sur le patient X pendant la semaine 15.
- Il ouvre le dashboard → onglet Audit.
- Filtre : période = 2026-04-06 → 2026-04-12, application =
DxCare, action =click. - Il saisit dans la recherche libre le hash pseudo du patient (fourni par le TIM responsable).
- Il voit 3 lignes, toutes en mode
assisted, toutes avecuser_name = "Marie Dupont". - Il clique sur "📄 Rapport PDF DSI" → reçoit un PDF d'une page avec les 3 lignes, la signature d'intégrité, le tampon Léa, la période.
- Il remonte ça à sa direction. Dossier clos en 4 minutes.
C'est exactement le cas d'usage qui manque aujourd'hui et qui fera la différence en appel d'offres CHU.
Section E — Non-décisions (ce qu'on ne fait pas)
- Dashboard mobile / responsive : le dashboard est un outil admin, pas un produit grand public. Les TIMs n'en ont pas besoin sur téléphone. Non.
- Multi-thème (clair/sombre) : sombre tout le temps. Non.
- Internationalisation du dashboard : tout est en français, cible FR. i18n prévu côté produit Léa, pas côté dashboard admin. Non pour 2026.
- Refonte complète en framework (React/Vue) : le HTML vanilla + Chart.js tient la route. Une refonte coûterait 2 semaines pour zéro gain utilisateur. Non.
- Authentification OAuth / SSO : HTTP Basic suffit sur usage interne. SSO hôpital = chantier en soi, ne pas le mélanger avec ce cleanup. Pas maintenant.
- Temps réel sur l'onglet Audit : le polling toutes les 30 s est largement suffisant. WebSocket = complexité inutile ici. Non.
Section F — Roadmap recommandée
Ordre non négociable : on fait le ménage avant d'ajouter du neuf. Un onglet Audit brillant au milieu d'un dashboard bruité envoie un signal d'amateurisme.
Sprint 1 — Cleanup (0.5 jour)
- Section B points 1 à 7 (retirer Tests, Apprentissage, Corrections, Exécution, Vue d'ensemble, pages mortes, code orphelin).
- Livrable : dashboard à 8 onglets fonctionnels, zéro placeholder, zéro 404 silencieuse.
- Critère de sortie : un client invité voit l'interface sans jamais tomber sur une page vide ou une erreur JS.
Sprint 2 — Onglet Audit MVP (0.75 jour)
- Proxy Flask
/api/audit/*→http://localhost:5005/api/v1/audit/*(réutilise le pattern/api/streaming/<path>). - Nouvel onglet "⚖️ Audit & Traçabilité" : bandeau 4 KPIs + filtres + tableau paginé + export CSV.
- Livrable : un DSI peut filtrer, visualiser, exporter.
- Critère de sortie : scénario CH Auch (voir Section D) exécutable en < 5 min par un utilisateur non technique.
Sprint 3 — Audit complet DSI-ready (1.5 jour, à chaud si appel d'offres)
- Rapport PDF DSI.
- Champ
patient_ref_hashdansAuditEntry+ propagation executor. - Signature d'intégrité journalière (hash du JSONL en clôture).
- Widgets graphiques (camembert + courbe 7 j).
- Alerting seuil d'échecs.
- Livrable : conformité démontrable AI Act art. 12 + 14 + RGPD art. 30 + 32.
Sprint 4 — Améliorations ciblées (1 à 2 jours, au fil de l'eau)
- Section C (santé globale Services, filtres Sessions, tail logs WebSocket, retrait graphiques vides Performance, tooltips Config).
- À faire seulement quand un TIM ou un DSI remonte un manque précis, pas en préventif.
Annexe — Justification du cleanup
Pourquoi on supprime plutôt qu'on "met en veille" ?
- Chaque onglet coûte en maintenance (CSS, JS, tests manuels, support client).
- Chaque route Flask morte est une surface d'attaque (surtout
/api/tests/runqui exécutepytesten subprocess). - Chaque placeholder visuel dégrade la perception client : "pourquoi il y a un onglet 🧠 Apprentissage qui n'affiche rien ?"
- Git garde tout. Aucune donnée n'est perdue. Revert possible.
Principe général : moins de surface, plus de valeur. Un dashboard de 9 onglets pleins bat un dashboard de 14 onglets dont 5 creux, tous les jours.