Files
rpa_vision_v3/scripts/verification_proprietes_etapes_complete_12jan2026.py
Dom a27b74cf22 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>
2026-01-29 11:23:51 +01:00

399 lines
14 KiB
Python

#!/usr/bin/env python3
"""
Script de Vérification Complète des Propriétés d'Étapes VWB
Auteur : Dom, Alice, Kiro - 12 janvier 2026
Ce script vérifie que toutes les actions du catalogue VWB ont leurs propriétés
correctement définies et implémentées dans le système de propriétés.
"""
import json
import sys
import os
from pathlib import Path
from typing import Dict, List, Any, Set
from datetime import datetime
# Ajouter le répertoire racine au path
sys.path.insert(0, str(Path(__file__).parent.parent))
def analyser_catalogue_statique() -> Dict[str, Any]:
"""
Analyse le catalogue statique pour extraire toutes les actions et leurs paramètres.
Returns:
Dictionnaire avec les actions et leurs configurations
"""
print("📋 Analyse du catalogue statique...")
# Lire le fichier TypeScript du catalogue statique
catalogue_path = Path("visual_workflow_builder/frontend/src/data/staticCatalog.ts")
if not catalogue_path.exists():
print(f"❌ Fichier catalogue non trouvé : {catalogue_path}")
return {}
try:
with open(catalogue_path, 'r', encoding='utf-8') as f:
contenu = f.read()
# Extraire les actions (analyse simple du contenu)
actions_trouvees = {}
# Rechercher les définitions d'actions
import re
# Pattern pour extraire les IDs d'actions
pattern_id = r"id:\s*['\"]([^'\"]+)['\"]"
ids = re.findall(pattern_id, contenu)
# Pattern pour extraire les noms d'actions
pattern_name = r"name:\s*['\"]([^'\"]+)['\"]"
names = re.findall(pattern_name, contenu)
# Pattern pour extraire les catégories
pattern_category = r"category:\s*['\"]([^'\"]+)['\"]"
categories = re.findall(pattern_category, contenu)
# Combiner les informations
for i, action_id in enumerate(ids):
actions_trouvees[action_id] = {
'id': action_id,
'name': names[i] if i < len(names) else action_id,
'category': categories[i] if i < len(categories) else 'unknown',
'parameters_found': True, # Présumé vrai pour le catalogue statique
}
print(f"{len(actions_trouvees)} actions trouvées dans le catalogue statique")
return actions_trouvees
except Exception as e:
print(f"❌ Erreur lors de l'analyse du catalogue : {e}")
return {}
def analyser_backend_registry() -> Dict[str, Any]:
"""
Analyse le registry backend pour vérifier les actions disponibles.
Returns:
Dictionnaire avec les actions du backend
"""
print("🔧 Analyse du registry backend...")
try:
# Importer le registry
from visual_workflow_builder.backend.actions.registry import get_global_registry
registry = get_global_registry()
# Obtenir les informations du registry
info = registry.get_registry_stats()
actions = registry.list_actions()
actions_backend = {}
for action_id in actions:
metadata = registry.get_action_metadata(action_id)
actions_backend[action_id] = {
'id': action_id,
'metadata': metadata,
'class_available': registry.get_action_class(action_id) is not None,
}
print(f"{len(actions_backend)} actions trouvées dans le registry backend")
return {
'stats': info,
'actions': actions_backend,
}
except Exception as e:
print(f"❌ Erreur lors de l'analyse du registry backend : {e}")
return {}
def analyser_composants_frontend() -> Dict[str, Any]:
"""
Analyse les composants frontend pour vérifier l'implémentation des propriétés.
Returns:
Dictionnaire avec l'état des composants frontend
"""
print("🎨 Analyse des composants frontend...")
composants_analyses = {}
# Analyser PropertiesPanel principal
properties_panel_path = Path("visual_workflow_builder/frontend/src/components/PropertiesPanel/index.tsx")
if properties_panel_path.exists():
try:
with open(properties_panel_path, 'r', encoding='utf-8') as f:
contenu = f.read()
composants_analyses['PropertiesPanel'] = {
'exists': True,
'has_step_parameters_config': 'stepParametersConfig' in contenu,
'has_vwb_integration': 'useVWBStepIntegration' in contenu,
'has_visual_selector': 'VisualSelector' in contenu,
'has_variable_autocomplete': 'VariableAutocomplete' in contenu,
'file_size': len(contenu),
}
except Exception as e:
composants_analyses['PropertiesPanel'] = {'exists': True, 'error': str(e)}
else:
composants_analyses['PropertiesPanel'] = {'exists': False}
# Analyser VWBActionProperties
vwb_properties_path = Path("visual_workflow_builder/frontend/src/components/PropertiesPanel/VWBActionProperties.tsx")
if vwb_properties_path.exists():
try:
with open(vwb_properties_path, 'r', encoding='utf-8') as f:
contenu = f.read()
composants_analyses['VWBActionProperties'] = {
'exists': True,
'has_visual_anchor_editor': 'VisualAnchorEditor' in contenu,
'has_parameter_validation': 'validateParameters' in contenu,
'has_real_time_validation': 'validation' in contenu,
'has_examples_display': 'examples' in contenu,
'file_size': len(contenu),
}
except Exception as e:
composants_analyses['VWBActionProperties'] = {'exists': True, 'error': str(e)}
else:
composants_analyses['VWBActionProperties'] = {'exists': False}
# Analyser useVWBStepIntegration hook
hook_path = Path("visual_workflow_builder/frontend/src/hooks/useVWBStepIntegration.ts")
if hook_path.exists():
try:
with open(hook_path, 'r', encoding='utf-8') as f:
contenu = f.read()
composants_analyses['useVWBStepIntegration'] = {
'exists': True,
'has_create_vwb_step': 'createVWBStep' in contenu,
'has_validation': 'validateVWBStep' in contenu,
'has_drag_drop_support': 'convertDragDataToVWBStep' in contenu,
'file_size': len(contenu),
}
except Exception as e:
composants_analyses['useVWBStepIntegration'] = {'exists': True, 'error': str(e)}
else:
composants_analyses['useVWBStepIntegration'] = {'exists': False}
print(f"{len(composants_analyses)} composants analysés")
return composants_analyses
def verifier_coherence_types() -> Dict[str, Any]:
"""
Vérifie la cohérence des types TypeScript entre les différents fichiers.
Returns:
Résultats de la vérification de cohérence
"""
print("🔍 Vérification de la cohérence des types...")
coherence = {
'catalog_types_exists': False,
'main_types_exists': False,
'types_coherent': False,
'issues': [],
}
# Vérifier catalog.ts
catalog_types_path = Path("visual_workflow_builder/frontend/src/types/catalog.ts")
if catalog_types_path.exists():
coherence['catalog_types_exists'] = True
try:
with open(catalog_types_path, 'r', encoding='utf-8') as f:
contenu = f.read()
# Vérifier la présence des types essentiels
types_essentiels = [
'VWBCatalogAction',
'VWBActionParameter',
'VWBVisualAnchor',
'VWBActionValidationResult',
]
for type_name in types_essentiels:
if type_name not in contenu:
coherence['issues'].append(f"Type manquant : {type_name}")
except Exception as e:
coherence['issues'].append(f"Erreur lecture catalog.ts : {e}")
else:
coherence['issues'].append("Fichier catalog.ts manquant")
# Vérifier index.ts principal
main_types_path = Path("visual_workflow_builder/frontend/src/types/index.ts")
if main_types_path.exists():
coherence['main_types_exists'] = True
else:
coherence['issues'].append("Fichier types/index.ts manquant")
coherence['types_coherent'] = len(coherence['issues']) == 0
print(f"✅ Vérification de cohérence terminée - {len(coherence['issues'])} problèmes trouvés")
return coherence
def generer_rapport_complet() -> Dict[str, Any]:
"""
Génère un rapport complet de l'état des propriétés d'étapes.
Returns:
Rapport complet
"""
print("📊 Génération du rapport complet...")
rapport = {
'timestamp': datetime.now().isoformat(),
'version': '1.0.0',
'auteur': 'Dom, Alice, Kiro',
'catalogue_statique': analyser_catalogue_statique(),
'backend_registry': analyser_backend_registry(),
'composants_frontend': analyser_composants_frontend(),
'coherence_types': verifier_coherence_types(),
}
# Calculer des métriques globales
catalogue_actions = rapport['catalogue_statique']
backend_actions = rapport['backend_registry'].get('actions', {})
rapport['metriques'] = {
'total_actions_catalogue': len(catalogue_actions),
'total_actions_backend': len(backend_actions),
'actions_communes': len(set(catalogue_actions.keys()) & set(backend_actions.keys())),
'actions_catalogue_seulement': list(set(catalogue_actions.keys()) - set(backend_actions.keys())),
'actions_backend_seulement': list(set(backend_actions.keys()) - set(catalogue_actions.keys())),
}
# Évaluer l'état global
composants = rapport['composants_frontend']
coherence = rapport['coherence_types']
rapport['etat_global'] = {
'properties_panel_ok': composants.get('PropertiesPanel', {}).get('exists', False),
'vwb_properties_ok': composants.get('VWBActionProperties', {}).get('exists', False),
'integration_hook_ok': composants.get('useVWBStepIntegration', {}).get('exists', False),
'types_coherents': coherence.get('types_coherent', False),
'pret_pour_production': False, # Sera calculé
}
# Calculer si prêt pour production
etat = rapport['etat_global']
etat['pret_pour_production'] = all([
etat['properties_panel_ok'],
etat['vwb_properties_ok'],
etat['integration_hook_ok'],
etat['types_coherents'],
rapport['metriques']['total_actions_catalogue'] > 0,
])
return rapport
def sauvegarder_rapport(rapport: Dict[str, Any]) -> str:
"""
Sauvegarde le rapport dans un fichier JSON.
Args:
rapport: Rapport à sauvegarder
Returns:
Chemin du fichier sauvegardé
"""
# Créer le répertoire docs s'il n'existe pas
docs_dir = Path("docs")
docs_dir.mkdir(exist_ok=True)
# Nom du fichier avec timestamp
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
fichier_rapport = docs_dir / f"rapport_verification_proprietes_etapes_{timestamp}.json"
try:
with open(fichier_rapport, 'w', encoding='utf-8') as f:
json.dump(rapport, f, indent=2, ensure_ascii=False)
print(f"✅ Rapport sauvegardé : {fichier_rapport}")
return str(fichier_rapport)
except Exception as e:
print(f"❌ Erreur sauvegarde rapport : {e}")
return ""
def afficher_resume(rapport: Dict[str, Any]):
"""
Affiche un résumé du rapport.
Args:
rapport: Rapport à résumer
"""
print("\n" + "="*60)
print("📋 RÉSUMÉ DE LA VÉRIFICATION DES PROPRIÉTÉS D'ÉTAPES")
print("="*60)
metriques = rapport['metriques']
etat = rapport['etat_global']
print(f"📊 Actions catalogue : {metriques['total_actions_catalogue']}")
print(f"🔧 Actions backend : {metriques['total_actions_backend']}")
print(f"🤝 Actions communes : {metriques['actions_communes']}")
print(f"\n🎨 Composants Frontend :")
print(f" - PropertiesPanel : {'' if etat['properties_panel_ok'] else ''}")
print(f" - VWBActionProperties : {'' if etat['vwb_properties_ok'] else ''}")
print(f" - useVWBStepIntegration : {'' if etat['integration_hook_ok'] else ''}")
print(f"\n🔍 Types TypeScript : {'' if etat['types_coherents'] else ''}")
print(f"\n🚀 Prêt pour production : {'' if etat['pret_pour_production'] else ''}")
# Afficher les problèmes s'il y en a
coherence = rapport['coherence_types']
if coherence.get('issues'):
print(f"\n⚠️ Problèmes détectés :")
for issue in coherence['issues']:
print(f" - {issue}")
# Afficher les actions manquantes
if metriques['actions_catalogue_seulement']:
print(f"\n📋 Actions catalogue non implémentées backend :")
for action in metriques['actions_catalogue_seulement']:
print(f" - {action}")
if metriques['actions_backend_seulement']:
print(f"\n🔧 Actions backend non référencées catalogue :")
for action in metriques['actions_backend_seulement']:
print(f" - {action}")
def main():
"""Fonction principale du script."""
print("🔍 Vérification Complète des Propriétés d'Étapes VWB")
print("Auteur : Dom, Alice, Kiro - 12 janvier 2026")
print("-" * 60)
try:
# Générer le rapport complet
rapport = generer_rapport_complet()
# Sauvegarder le rapport
fichier_rapport = sauvegarder_rapport(rapport)
# Afficher le résumé
afficher_resume(rapport)
# Déterminer le code de sortie
if rapport['etat_global']['pret_pour_production']:
print(f"\n✅ Système prêt - Toutes les propriétés d'étapes sont correctement implémentées")
return 0
else:
print(f"\n⚠️ Système nécessite des améliorations - Voir le rapport : {fichier_rapport}")
return 1
except Exception as e:
print(f"❌ Erreur lors de la vérification : {e}")
import traceback
traceback.print_exc()
return 2
if __name__ == "__main__":
exit_code = main()
sys.exit(exit_code)