v1.0 - Version stable: multi-PC, détection UI-DETR-1, 3 modes exécution
- Frontend v4 accessible sur réseau local (192.168.1.40) - Ports ouverts: 3002 (frontend), 5001 (backend), 5004 (dashboard) - Ollama GPU fonctionnel - Self-healing interactif - Dashboard confiance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
388
docs/archive/misc/dashboard/DASHBOARD_PHASE1_CHANGES.md
Normal file
388
docs/archive/misc/dashboard/DASHBOARD_PHASE1_CHANGES.md
Normal file
@@ -0,0 +1,388 @@
|
||||
# Dashboard Phase 1 - Modifications Appliquées
|
||||
|
||||
**Date**: 7 janvier 2026 - 22:45
|
||||
**Objectif**: Corriger les chemins screenshots + rendre visibles les screen_states
|
||||
|
||||
---
|
||||
|
||||
## 📝 Modifications Détaillées
|
||||
|
||||
### Modification 1 - Fix Chemin Screenshots (Liste Sessions)
|
||||
**Fichier**: `web_dashboard/app.py`
|
||||
**Ligne**: 206-210
|
||||
|
||||
**AVANT** :
|
||||
```python
|
||||
# Compter les screenshots
|
||||
screenshots_dir = session_dir / "screenshots"
|
||||
screenshot_files = list(screenshots_dir.glob('*.png')) if screenshots_dir.exists() else []
|
||||
```
|
||||
|
||||
**APRÈS** :
|
||||
```python
|
||||
# Compter les screenshots
|
||||
# Structure : sessions/{session_id}/{session_id}/shots/*.png
|
||||
session_id = session.session_id
|
||||
screenshots_dir = session_dir / session_id / "shots"
|
||||
screenshot_files = list(screenshots_dir.glob('*.png')) if screenshots_dir.exists() else []
|
||||
```
|
||||
|
||||
**Raison** :
|
||||
- La structure réelle est `sessions/sess_xxx/sess_xxx/shots/shot_0001.png`
|
||||
- L'ancien code cherchait dans `sessions/sess_xxx/screenshots/` (n'existe pas)
|
||||
- Résultat : **TOUJOURS 0 screenshots affichés**
|
||||
|
||||
**Impact** :
|
||||
- ✅ Screenshots count sera correct pour les sessions non nettoyées
|
||||
- ✅ L'utilisateur voit le nombre réel de captures
|
||||
|
||||
---
|
||||
|
||||
### Modification 2 - Fix Chemin Screenshots (Détails Session)
|
||||
**Fichier**: `web_dashboard/app.py`
|
||||
**Ligne**: 251-261
|
||||
|
||||
**AVANT** :
|
||||
```python
|
||||
screenshots_dir = session_dir / "screenshots"
|
||||
```
|
||||
|
||||
**APRÈS** :
|
||||
```python
|
||||
# Structure : sessions/{session_id}/{session_id}/shots/*.png
|
||||
screenshots_dir = session_dir / session_id / "shots"
|
||||
```
|
||||
|
||||
**Impact** :
|
||||
- ✅ La modal "📸 Screenshots" affiche les vraies images
|
||||
- ✅ Les URLs sont correctement générées
|
||||
|
||||
---
|
||||
|
||||
### Modification 3 - Fix Route Get Screenshot
|
||||
**Fichier**: `web_dashboard/app.py`
|
||||
**Ligne**: 287-320
|
||||
|
||||
**AVANT** :
|
||||
```python
|
||||
screenshot_path = session_dir / "screenshots" / filename
|
||||
```
|
||||
|
||||
**APRÈS** :
|
||||
```python
|
||||
# Essayer le chemin correct en premier : {session_id}/shots/
|
||||
screenshot_path = session_dir / session_id / "shots" / filename
|
||||
|
||||
if not screenshot_path.exists():
|
||||
# Essayer l'ancien chemin pour compatibilité
|
||||
screenshot_path = session_dir / "screenshots" / filename
|
||||
|
||||
if not screenshot_path.exists():
|
||||
# Essayer dans les sous-dossiers (fallback)
|
||||
for subdir in session_dir.iterdir():
|
||||
if subdir.is_dir():
|
||||
# Essayer shots/
|
||||
alt_path = subdir / "shots" / filename
|
||||
if alt_path.exists():
|
||||
screenshot_path = alt_path
|
||||
break
|
||||
# Essayer screenshots/
|
||||
alt_path = subdir / "screenshots" / filename
|
||||
if alt_path.exists():
|
||||
screenshot_path = alt_path
|
||||
break
|
||||
|
||||
if not screenshot_path.exists():
|
||||
return jsonify({'error': 'Screenshot non trouvé ou supprimé après traitement'}), 404
|
||||
```
|
||||
|
||||
**Raison** :
|
||||
- Cherche d'abord dans le bon chemin
|
||||
- Fallback sur l'ancien chemin (compatibilité)
|
||||
- Message d'erreur clair si supprimé après traitement
|
||||
|
||||
**Impact** :
|
||||
- ✅ Images servies correctement
|
||||
- ✅ Message clair si screenshot supprimé (après cleanup)
|
||||
|
||||
---
|
||||
|
||||
### Modification 4 - NOUVELLE Route `/api/screen_states`
|
||||
**Fichier**: `web_dashboard/app.py`
|
||||
**Ligne**: 355-425
|
||||
|
||||
**Code ajouté** :
|
||||
```python
|
||||
@app.route('/api/screen_states')
|
||||
def list_screen_states():
|
||||
"""Liste tous les screen states traités."""
|
||||
try:
|
||||
screen_states = []
|
||||
screen_states_path = DATA_PATH / "screen_states"
|
||||
|
||||
if not screen_states_path.exists():
|
||||
return jsonify({'screen_states': [], 'total': 0})
|
||||
|
||||
# Parcourir tous les fichiers JSON dans screen_states/
|
||||
for date_dir in screen_states_path.iterdir():
|
||||
if not date_dir.is_dir():
|
||||
continue
|
||||
|
||||
for state_file in date_dir.glob('*.json'):
|
||||
try:
|
||||
with open(state_file, 'r') as f:
|
||||
state_data = json.load(f)
|
||||
|
||||
screen_states.append({
|
||||
'screen_state_id': state_data.get('screen_state_id', state_file.stem),
|
||||
'session_id': state_data.get('session_id', 'unknown'),
|
||||
'timestamp': state_data.get('timestamp', ''),
|
||||
'window': state_data.get('window', {}),
|
||||
'tags': state_data.get('context', {}).get('tags', []),
|
||||
'workflow_candidate': state_data.get('context', {}).get('current_workflow_candidate'),
|
||||
'user_id': state_data.get('context', {}).get('user_id', 'unknown'),
|
||||
'business_variables': state_data.get('context', {}).get('business_variables', {}),
|
||||
'file_path': str(state_file),
|
||||
'date': date_dir.name
|
||||
})
|
||||
except Exception as e:
|
||||
print(f"Erreur lecture screen state {state_file}: {e}")
|
||||
continue
|
||||
|
||||
# Trier par timestamp (plus récent en premier)
|
||||
screen_states.sort(key=lambda x: x['timestamp'], reverse=True)
|
||||
|
||||
# Grouper par session
|
||||
sessions_grouped = {}
|
||||
for state in screen_states:
|
||||
session_id = state['session_id']
|
||||
if session_id not in sessions_grouped:
|
||||
sessions_grouped[session_id] = {
|
||||
'session_id': session_id,
|
||||
'screen_states': [],
|
||||
'count': 0,
|
||||
'first_timestamp': state['timestamp'],
|
||||
'last_timestamp': state['timestamp'],
|
||||
'tags': state['tags'],
|
||||
'user_id': state['user_id']
|
||||
}
|
||||
sessions_grouped[session_id]['screen_states'].append(state)
|
||||
sessions_grouped[session_id]['count'] += 1
|
||||
|
||||
return jsonify({
|
||||
'screen_states': screen_states,
|
||||
'total': len(screen_states),
|
||||
'sessions_grouped': list(sessions_grouped.values()),
|
||||
'sessions_count': len(sessions_grouped)
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
```
|
||||
|
||||
**Fonctionnalités** :
|
||||
- ✅ Liste TOUS les screen_states (236 actuellement)
|
||||
- ✅ Groupe par session
|
||||
- ✅ Retourne métadonnées (tags, workflow candidate, user, etc.)
|
||||
- ✅ Tri par timestamp (plus récent en premier)
|
||||
|
||||
**Réponse JSON** :
|
||||
```json
|
||||
{
|
||||
"screen_states": [...],
|
||||
"total": 236,
|
||||
"sessions_grouped": [
|
||||
{
|
||||
"session_id": "sess_20260107T220743_6be50905",
|
||||
"count": 40,
|
||||
"screen_states": [...],
|
||||
"tags": ["Facturation_T2A_demo"],
|
||||
"user_id": "demo_user"
|
||||
}
|
||||
],
|
||||
"sessions_count": 6
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Modification 5 - NOUVELLE Route `/api/screen_states/<session_id>`
|
||||
**Fichier**: `web_dashboard/app.py`
|
||||
**Ligne**: 428-462
|
||||
|
||||
**Code ajouté** :
|
||||
```python
|
||||
@app.route('/api/screen_states/<session_id>')
|
||||
def get_session_screen_states(session_id):
|
||||
"""Récupère tous les screen states d'une session."""
|
||||
try:
|
||||
screen_states = []
|
||||
screen_states_path = DATA_PATH / "screen_states"
|
||||
|
||||
if not screen_states_path.exists():
|
||||
return jsonify({'error': 'Screen states directory not found'}), 404
|
||||
|
||||
# Parcourir tous les fichiers JSON dans screen_states/
|
||||
for date_dir in screen_states_path.iterdir():
|
||||
if not date_dir.is_dir():
|
||||
continue
|
||||
|
||||
for state_file in date_dir.glob('*.json'):
|
||||
try:
|
||||
with open(state_file, 'r') as f:
|
||||
state_data = json.load(f)
|
||||
|
||||
if state_data.get('session_id') == session_id:
|
||||
screen_states.append(state_data)
|
||||
except Exception as e:
|
||||
continue
|
||||
|
||||
# Trier par timestamp
|
||||
screen_states.sort(key=lambda x: x.get('timestamp', ''))
|
||||
|
||||
return jsonify({
|
||||
'session_id': session_id,
|
||||
'screen_states': screen_states,
|
||||
'total': len(screen_states)
|
||||
})
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
```
|
||||
|
||||
**Fonctionnalités** :
|
||||
- ✅ Récupère tous les screen_states d'une session spécifique
|
||||
- ✅ Retourne les données COMPLÈTES (pas de résumé)
|
||||
- ✅ Tri chronologique
|
||||
|
||||
---
|
||||
|
||||
## ✅ Vérifications Avant Déploiement
|
||||
|
||||
### Rétrocompatibilité
|
||||
- ✅ Aucune route existante n'a été SUPPRIMÉE
|
||||
- ✅ Les routes existantes fonctionnent toujours (avec chemins corrigés)
|
||||
- ✅ 2 nouvelles routes AJOUTÉES (pas de modification d'existantes)
|
||||
|
||||
### Pas de Breaking Changes
|
||||
- ✅ `/api/system/status` - INCHANGÉ
|
||||
- ✅ `/api/agent/sessions` - CHEMINS CORRIGÉS (amélioration)
|
||||
- ✅ `/api/agent/sessions/<id>` - CHEMINS CORRIGÉS (amélioration)
|
||||
- ✅ `/api/agent/sessions/<id>/screenshot/<filename>` - CHEMINS CORRIGÉS (amélioration)
|
||||
- ✅ `/api/workflows` - INCHANGÉ
|
||||
- ✅ `/api/chains` - INCHANGÉ
|
||||
- ✅ `/api/triggers` - INCHANGÉ
|
||||
|
||||
---
|
||||
|
||||
## 📋 Déploiement
|
||||
|
||||
### Option 1 - Script Automatique (Recommandé)
|
||||
```bash
|
||||
cd /home/dom/ai/rpa_vision_v3
|
||||
./deploy_dashboard_fix.sh
|
||||
```
|
||||
|
||||
### Option 2 - Manuel
|
||||
```bash
|
||||
# Sauvegarde
|
||||
sudo cp /opt/rpa_vision_v3/web_dashboard/app.py \
|
||||
/opt/rpa_vision_v3/web_dashboard/app.py.backup_phase1_$(date +%Y%m%d_%H%M%S)
|
||||
|
||||
# Déploiement
|
||||
sudo cp /home/dom/ai/rpa_vision_v3/web_dashboard_app.py \
|
||||
/opt/rpa_vision_v3/web_dashboard/app.py
|
||||
sudo chown rpa:rpa /opt/rpa_vision_v3/web_dashboard/app.py
|
||||
sudo chmod 644 /opt/rpa_vision_v3/web_dashboard/app.py
|
||||
|
||||
# Redémarrage
|
||||
sudo systemctl restart rpa-vision-v3-dashboard.service
|
||||
|
||||
# Vérification
|
||||
systemctl status rpa-vision-v3-dashboard.service
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Tests Post-Déploiement
|
||||
|
||||
### Test 1 - Nouvelle Route Screen States
|
||||
```bash
|
||||
curl http://localhost:5001/api/screen_states | python3 -m json.tool | head -50
|
||||
```
|
||||
|
||||
**Attendu** :
|
||||
```json
|
||||
{
|
||||
"total": 236,
|
||||
"sessions_count": 6,
|
||||
"screen_states": [...]
|
||||
}
|
||||
```
|
||||
|
||||
### Test 2 - Screenshots Count Corrigé
|
||||
```bash
|
||||
curl http://localhost:5001/api/agent/sessions | python3 -m json.tool | grep screenshots_count
|
||||
```
|
||||
|
||||
**Attendu** :
|
||||
- Sessions non nettoyées : `"screenshots_count": 30` (ou autre nombre > 0)
|
||||
- Sessions nettoyées : `"screenshots_count": 0` (normal, supprimés après traitement)
|
||||
|
||||
### Test 3 - Pas de Régression
|
||||
```bash
|
||||
curl http://localhost:5001/api/system/status | python3 -m json.tool
|
||||
```
|
||||
|
||||
**Attendu** :
|
||||
```json
|
||||
{
|
||||
"status": "online",
|
||||
"sessions_count": 8,
|
||||
"workflows_count": 2,
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
### Test 4 - Dashboard Web
|
||||
Ouvrir dans le navigateur : `http://localhost:5001`
|
||||
|
||||
**Vérifier** :
|
||||
- ✅ Onglet "Sessions" affiche screenshots_count > 0 pour sessions non nettoyées
|
||||
- ✅ Aucune erreur JavaScript dans la console
|
||||
- ✅ Toutes les anciennes fonctionnalités marchent
|
||||
|
||||
---
|
||||
|
||||
## 📊 Impact Utilisateur
|
||||
|
||||
### Avant Phase 1
|
||||
- ❌ Screenshots count toujours à 0
|
||||
- ❌ 236 screen_states invisibles
|
||||
- ❌ Impossible de voir les données traitées
|
||||
|
||||
### Après Phase 1
|
||||
- ✅ Screenshots count correct
|
||||
- ✅ Nouvelle API `/api/screen_states` pour accéder aux 236 screen_states
|
||||
- ✅ Groupement par session disponible
|
||||
- ✅ TOUTES les anciennes fonctionnalités intactes
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Prochaines Étapes (Phase 2)
|
||||
|
||||
1. **Créer onglet "Données Traitées" dans le dashboard**
|
||||
- Afficher les 236 screen_states
|
||||
- Grouper par session
|
||||
- Filtrage par date, user, tags
|
||||
|
||||
2. **Ajouter stats de processing**
|
||||
- Route `/api/processing/stats`
|
||||
- Afficher dans "Vue d'ensemble"
|
||||
|
||||
3. **Distinction Raw vs Processed**
|
||||
- Renommer "Sessions" → "Sessions Brutes"
|
||||
- Ajouter statut (🟡 Attente, 🟢 Traité, 🔴 Erreur)
|
||||
|
||||
---
|
||||
|
||||
**Version** : 1.0 - Phase 1 Complète
|
||||
**Status** : ✅ Prêt pour Déploiement
|
||||
Reference in New Issue
Block a user