- 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>
638 lines
28 KiB
Python
638 lines
28 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Script d'Analyse - Cas Undefined stepParametersConfig
|
|
Auteur : Dom, Alice, Kiro - 12 janvier 2026
|
|
|
|
Ce script identifie tous les cas où stepParametersConfig[selectedStep.type] retourne undefined
|
|
pour diagnostiquer les problèmes de propriétés d'étapes vides.
|
|
"""
|
|
|
|
import json
|
|
import os
|
|
import sys
|
|
import re
|
|
import time
|
|
from pathlib import Path
|
|
from typing import Dict, List, Any, Optional, Set, Tuple
|
|
|
|
class AnalyseCasUndefinedStepParametersConfig:
|
|
"""Analyse des cas undefined dans stepParametersConfig."""
|
|
|
|
def __init__(self):
|
|
"""Initialise l'analyse."""
|
|
self.project_root = Path(__file__).parent.parent
|
|
self.frontend_path = self.project_root / "visual_workflow_builder" / "frontend"
|
|
|
|
self.analysis_results = {
|
|
"timestamp": "2026-01-12",
|
|
"version": "1.0.0",
|
|
"analysis_type": "cas_undefined_stepparametersconfig",
|
|
"summary": {
|
|
"total_step_types": 0,
|
|
"configured_types": 0,
|
|
"undefined_cases": 0,
|
|
"vwb_actions_analyzed": 0,
|
|
"potential_issues": 0
|
|
},
|
|
"step_types_analysis": {
|
|
"configured_types": [],
|
|
"undefined_types": [],
|
|
"type_mapping": {}
|
|
},
|
|
"vwb_actions_analysis": {
|
|
"known_vwb_actions": [],
|
|
"catalog_actions": [],
|
|
"unmapped_actions": []
|
|
},
|
|
"undefined_scenarios": [],
|
|
"recommendations": [],
|
|
"detailed_findings": []
|
|
}
|
|
|
|
print("🔍 Analyse des Cas Undefined - stepParametersConfig")
|
|
print(f"📁 Chemin frontend: {self.frontend_path}")
|
|
|
|
def run_complete_analysis(self) -> Dict[str, Any]:
|
|
"""Exécute l'analyse complète."""
|
|
try:
|
|
print("\n" + "="*70)
|
|
print("🚀 ANALYSE COMPLÈTE DES CAS UNDEFINED")
|
|
print("="*70)
|
|
|
|
# 1. Analyser la configuration stepParametersConfig
|
|
self._analyze_step_parameters_config()
|
|
|
|
# 2. Analyser les types TypeScript
|
|
self._analyze_typescript_step_types()
|
|
|
|
# 3. Analyser les actions VWB du catalogue
|
|
self._analyze_vwb_catalog_actions()
|
|
|
|
# 4. Identifier les scénarios undefined
|
|
self._identify_undefined_scenarios()
|
|
|
|
# 5. Analyser les cas d'usage réels
|
|
self._analyze_real_usage_cases()
|
|
|
|
# 6. Générer les recommandations
|
|
self._generate_recommendations()
|
|
|
|
# 7. Sauvegarder le rapport
|
|
self._save_analysis_report()
|
|
|
|
print(f"\n✅ Analyse terminée - {self.analysis_results['summary']['undefined_cases']} cas undefined identifiés")
|
|
return self.analysis_results
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur lors de l'analyse : {e}")
|
|
self.analysis_results["fatal_error"] = str(e)
|
|
return self.analysis_results
|
|
|
|
def _analyze_step_parameters_config(self):
|
|
"""Analyse la configuration stepParametersConfig."""
|
|
print("\n📋 Analyse de stepParametersConfig...")
|
|
|
|
try:
|
|
# Lire le fichier PropertiesPanel
|
|
properties_panel_path = self.frontend_path / "src" / "components" / "PropertiesPanel" / "index.tsx"
|
|
|
|
if not properties_panel_path.exists():
|
|
self._add_finding("CRITICAL", "Fichier PropertiesPanel introuvable", {})
|
|
return
|
|
|
|
content = properties_panel_path.read_text(encoding='utf-8')
|
|
|
|
# Extraire la configuration stepParametersConfig
|
|
config_match = re.search(
|
|
r'const stepParametersConfig: Record<StepType, ParameterConfig\[\]> = \{(.*?)\};',
|
|
content,
|
|
re.DOTALL
|
|
)
|
|
|
|
if not config_match:
|
|
self._add_finding("CRITICAL", "Configuration stepParametersConfig introuvable", {})
|
|
return
|
|
|
|
config_content = config_match.group(1)
|
|
|
|
# Extraire les types configurés
|
|
configured_types = re.findall(r'(\w+):\s*\[', config_content)
|
|
|
|
# Analyser chaque configuration
|
|
type_mapping = {}
|
|
for step_type in configured_types:
|
|
# Extraire la configuration détaillée pour ce type
|
|
type_pattern = rf'{step_type}:\s*\[(.*?)\],'
|
|
type_match = re.search(type_pattern, config_content, re.DOTALL)
|
|
|
|
if type_match:
|
|
type_config = type_match.group(1)
|
|
param_count = len(re.findall(r'\{[^}]+\}', type_config))
|
|
|
|
type_mapping[step_type] = {
|
|
"parameter_count": param_count,
|
|
"has_configuration": True,
|
|
"config_content": type_config.strip()
|
|
}
|
|
else:
|
|
type_mapping[step_type] = {
|
|
"parameter_count": 0,
|
|
"has_configuration": False,
|
|
"config_content": ""
|
|
}
|
|
|
|
self.analysis_results["step_types_analysis"] = {
|
|
"configured_types": configured_types,
|
|
"type_mapping": type_mapping,
|
|
"total_configured": len(configured_types)
|
|
}
|
|
|
|
self.analysis_results["summary"]["configured_types"] = len(configured_types)
|
|
|
|
print(f" ✅ {len(configured_types)} types configurés trouvés")
|
|
for step_type in configured_types:
|
|
param_count = type_mapping[step_type]["parameter_count"]
|
|
print(f" - {step_type}: {param_count} paramètres")
|
|
|
|
except Exception as e:
|
|
self._add_finding("ERROR", f"Erreur analyse stepParametersConfig: {e}", {})
|
|
|
|
def _analyze_typescript_step_types(self):
|
|
"""Analyse les types TypeScript StepType."""
|
|
print("\n🔧 Analyse des types TypeScript...")
|
|
|
|
try:
|
|
# Lire le fichier des types
|
|
types_file_path = self.frontend_path / "src" / "types" / "index.ts"
|
|
|
|
if not types_file_path.exists():
|
|
self._add_finding("HIGH", "Fichier types TypeScript introuvable", {})
|
|
return
|
|
|
|
types_content = types_file_path.read_text(encoding='utf-8')
|
|
|
|
# Extraire l'union StepType
|
|
step_type_match = re.search(
|
|
r'export type StepType = ([^;]+);',
|
|
types_content
|
|
)
|
|
|
|
typescript_types = set()
|
|
if step_type_match:
|
|
step_type_union = step_type_match.group(1)
|
|
typescript_types = set(re.findall(r"'(\w+)'", step_type_union))
|
|
|
|
# Comparer avec les types configurés
|
|
configured_types = set(self.analysis_results["step_types_analysis"]["configured_types"])
|
|
|
|
# Identifier les types undefined (présents en TypeScript mais pas configurés)
|
|
undefined_types = list(typescript_types - configured_types)
|
|
extra_configured = list(configured_types - typescript_types)
|
|
|
|
self.analysis_results["step_types_analysis"]["typescript_types"] = list(typescript_types)
|
|
self.analysis_results["step_types_analysis"]["undefined_types"] = undefined_types
|
|
self.analysis_results["step_types_analysis"]["extra_configured"] = extra_configured
|
|
|
|
self.analysis_results["summary"]["total_step_types"] = len(typescript_types)
|
|
self.analysis_results["summary"]["undefined_cases"] = len(undefined_types)
|
|
|
|
# Signaler les cas undefined
|
|
if undefined_types:
|
|
self._add_finding("HIGH", f"Types TypeScript sans configuration: {undefined_types}", {
|
|
"undefined_types": undefined_types,
|
|
"impact": "Ces types retourneront undefined dans stepParametersConfig",
|
|
"consequence": "Propriétés d'étapes vides pour ces types"
|
|
})
|
|
|
|
if extra_configured:
|
|
self._add_finding("MEDIUM", f"Configurations sans type TypeScript: {extra_configured}", {
|
|
"extra_configured": extra_configured,
|
|
"impact": "Configurations inutilisées"
|
|
})
|
|
|
|
print(f" ✅ {len(typescript_types)} types TypeScript trouvés")
|
|
print(f" ✅ {len(configured_types)} types configurés")
|
|
print(f" ⚠️ {len(undefined_types)} types undefined identifiés: {undefined_types}")
|
|
|
|
except Exception as e:
|
|
self._add_finding("ERROR", f"Erreur analyse types TypeScript: {e}", {})
|
|
|
|
def _analyze_vwb_catalog_actions(self):
|
|
"""Analyse les actions VWB du catalogue."""
|
|
print("\n🎯 Analyse des actions VWB du catalogue...")
|
|
|
|
try:
|
|
# Analyser le catalogue statique
|
|
static_catalog_path = self.frontend_path / "src" / "data" / "staticCatalog.ts"
|
|
|
|
catalog_actions = []
|
|
if static_catalog_path.exists():
|
|
catalog_content = static_catalog_path.read_text(encoding='utf-8')
|
|
|
|
# Extraire les actions du catalogue
|
|
actions_pattern = r"id:\s*['\"]([^'\"]+)['\"]"
|
|
catalog_actions = re.findall(actions_pattern, catalog_content)
|
|
|
|
# Actions VWB connues dans le code
|
|
properties_panel_path = self.frontend_path / "src" / "components" / "PropertiesPanel" / "index.tsx"
|
|
known_vwb_actions = []
|
|
|
|
if properties_panel_path.exists():
|
|
content = properties_panel_path.read_text(encoding='utf-8')
|
|
|
|
# Extraire la liste des actions VWB connues
|
|
known_actions_match = re.search(
|
|
r'knownVWBActions = \[(.*?)\]',
|
|
content,
|
|
re.DOTALL
|
|
)
|
|
|
|
if known_actions_match:
|
|
actions_content = known_actions_match.group(1)
|
|
known_vwb_actions = re.findall(r"'([^']+)'", actions_content)
|
|
|
|
# Identifier les actions non mappées
|
|
all_vwb_actions = set(catalog_actions + known_vwb_actions)
|
|
configured_types = set(self.analysis_results["step_types_analysis"]["configured_types"])
|
|
|
|
unmapped_vwb_actions = list(all_vwb_actions - configured_types)
|
|
|
|
self.analysis_results["vwb_actions_analysis"] = {
|
|
"catalog_actions": catalog_actions,
|
|
"known_vwb_actions": known_vwb_actions,
|
|
"all_vwb_actions": list(all_vwb_actions),
|
|
"unmapped_actions": unmapped_vwb_actions
|
|
}
|
|
|
|
self.analysis_results["summary"]["vwb_actions_analyzed"] = len(all_vwb_actions)
|
|
|
|
# Signaler les actions VWB non mappées
|
|
if unmapped_vwb_actions:
|
|
self._add_finding("MEDIUM", f"Actions VWB non mappées dans stepParametersConfig: {unmapped_vwb_actions}", {
|
|
"unmapped_actions": unmapped_vwb_actions,
|
|
"impact": "Ces actions VWB utiliseront le composant VWBActionProperties",
|
|
"note": "Comportement attendu pour les actions VWB"
|
|
})
|
|
|
|
print(f" ✅ {len(catalog_actions)} actions du catalogue analysées")
|
|
print(f" ✅ {len(known_vwb_actions)} actions VWB connues")
|
|
print(f" ✅ {len(unmapped_vwb_actions)} actions VWB non mappées (normal)")
|
|
|
|
except Exception as e:
|
|
self._add_finding("ERROR", f"Erreur analyse actions VWB: {e}", {})
|
|
|
|
def _identify_undefined_scenarios(self):
|
|
"""Identifie les scénarios spécifiques qui causent undefined."""
|
|
print("\n🔍 Identification des scénarios undefined...")
|
|
|
|
try:
|
|
undefined_scenarios = []
|
|
|
|
# Scénario 1: Types TypeScript sans configuration
|
|
undefined_types = self.analysis_results["step_types_analysis"].get("undefined_types", [])
|
|
for step_type in undefined_types:
|
|
scenario = {
|
|
"scenario_type": "typescript_without_config",
|
|
"step_type": step_type,
|
|
"description": f"Type '{step_type}' défini en TypeScript mais absent de stepParametersConfig",
|
|
"consequence": "stepParametersConfig[selectedStep.type] retourne undefined",
|
|
"user_impact": "Affichage 'Cette étape n'a pas de paramètres configurables'",
|
|
"severity": "HIGH",
|
|
"fix_required": True
|
|
}
|
|
undefined_scenarios.append(scenario)
|
|
|
|
# Scénario 2: Types dynamiques non prévus
|
|
dynamic_types = [
|
|
"custom_action", "user_defined", "plugin_action",
|
|
"external_tool", "api_call", "database_query"
|
|
]
|
|
|
|
for dynamic_type in dynamic_types:
|
|
scenario = {
|
|
"scenario_type": "dynamic_type_not_configured",
|
|
"step_type": dynamic_type,
|
|
"description": f"Type dynamique '{dynamic_type}' potentiellement créé à l'exécution",
|
|
"consequence": "stepParametersConfig[selectedStep.type] retourne undefined",
|
|
"user_impact": "Propriétés non configurables pour les types dynamiques",
|
|
"severity": "MEDIUM",
|
|
"fix_required": False,
|
|
"note": "Peut nécessiter une gestion spéciale"
|
|
}
|
|
undefined_scenarios.append(scenario)
|
|
|
|
# Scénario 3: Actions VWB mal détectées
|
|
vwb_actions = self.analysis_results["vwb_actions_analysis"].get("all_vwb_actions", [])
|
|
for vwb_action in vwb_actions:
|
|
scenario = {
|
|
"scenario_type": "vwb_action_detection_failure",
|
|
"step_type": vwb_action,
|
|
"description": f"Action VWB '{vwb_action}' non détectée par la logique VWB",
|
|
"consequence": "Utilisation de stepParametersConfig au lieu de VWBActionProperties",
|
|
"user_impact": "Propriétés VWB non affichées correctement",
|
|
"severity": "MEDIUM",
|
|
"fix_required": True,
|
|
"note": "Améliorer la détection VWB"
|
|
}
|
|
undefined_scenarios.append(scenario)
|
|
|
|
self.analysis_results["undefined_scenarios"] = undefined_scenarios
|
|
self.analysis_results["summary"]["potential_issues"] = len(undefined_scenarios)
|
|
|
|
print(f" ✅ {len(undefined_scenarios)} scénarios undefined identifiés")
|
|
|
|
# Afficher les scénarios critiques
|
|
critical_scenarios = [s for s in undefined_scenarios if s["severity"] == "HIGH"]
|
|
if critical_scenarios:
|
|
print(f" 🚨 {len(critical_scenarios)} scénarios critiques:")
|
|
for scenario in critical_scenarios:
|
|
print(f" - {scenario['step_type']}: {scenario['description']}")
|
|
|
|
except Exception as e:
|
|
self._add_finding("ERROR", f"Erreur identification scénarios: {e}", {})
|
|
|
|
def _analyze_real_usage_cases(self):
|
|
"""Analyse les cas d'usage réels dans le code."""
|
|
print("\n📊 Analyse des cas d'usage réels...")
|
|
|
|
try:
|
|
# Analyser l'utilisation de stepParametersConfig dans PropertiesPanel
|
|
properties_panel_path = self.frontend_path / "src" / "components" / "PropertiesPanel" / "index.tsx"
|
|
content = properties_panel_path.read_text(encoding='utf-8')
|
|
|
|
# Rechercher les accès à stepParametersConfig
|
|
config_accesses = re.findall(
|
|
r'stepParametersConfig\[([^\]]+)\]',
|
|
content
|
|
)
|
|
|
|
# Analyser la fonction getParameterConfig
|
|
get_param_config_match = re.search(
|
|
r'const getParameterConfig = useCallback\(\(\): ParameterConfig\[\] => \{(.*?)\}, \[selectedStep\]\);',
|
|
content,
|
|
re.DOTALL
|
|
)
|
|
|
|
usage_analysis = {
|
|
"config_accesses": config_accesses,
|
|
"access_count": len(config_accesses),
|
|
"has_fallback_logic": False,
|
|
"has_undefined_check": False,
|
|
"has_error_handling": False
|
|
}
|
|
|
|
if get_param_config_match:
|
|
config_logic = get_param_config_match.group(1)
|
|
|
|
# Vérifier la présence de logiques de protection
|
|
usage_analysis["has_fallback_logic"] = "|| []" in config_logic
|
|
usage_analysis["has_undefined_check"] = "undefined" in config_logic
|
|
usage_analysis["has_error_handling"] = "try" in config_logic and "catch" in config_logic
|
|
|
|
# Analyser les conditions de retour
|
|
return_statements = re.findall(r'return ([^;]+);', config_logic)
|
|
usage_analysis["return_statements"] = return_statements
|
|
|
|
self.analysis_results["real_usage_analysis"] = usage_analysis
|
|
|
|
# Signaler les problèmes d'usage
|
|
if not usage_analysis["has_fallback_logic"]:
|
|
self._add_finding("MEDIUM", "Pas de logique de fallback pour stepParametersConfig", {
|
|
"suggestion": "Ajouter '|| []' pour éviter les erreurs undefined"
|
|
})
|
|
|
|
if not usage_analysis["has_error_handling"]:
|
|
self._add_finding("LOW", "Pas de gestion d'erreurs dans getParameterConfig", {
|
|
"suggestion": "Ajouter try/catch pour la robustesse"
|
|
})
|
|
|
|
print(f" ✅ {usage_analysis['access_count']} accès à stepParametersConfig analysés")
|
|
print(f" ✅ Fallback logic: {'Oui' if usage_analysis['has_fallback_logic'] else 'Non'}")
|
|
print(f" ✅ Gestion d'erreurs: {'Oui' if usage_analysis['has_error_handling'] else 'Non'}")
|
|
|
|
except Exception as e:
|
|
self._add_finding("ERROR", f"Erreur analyse usage réel: {e}", {})
|
|
|
|
def _generate_recommendations(self):
|
|
"""Génère des recommandations pour résoudre les cas undefined."""
|
|
print("\n💡 Génération des recommandations...")
|
|
|
|
recommendations = []
|
|
|
|
# Recommandation 1: Corriger les types undefined
|
|
undefined_types = self.analysis_results["step_types_analysis"].get("undefined_types", [])
|
|
if undefined_types:
|
|
recommendations.append({
|
|
"priority": "HIGH",
|
|
"category": "Configuration manquante",
|
|
"title": "Ajouter les configurations manquantes pour les types undefined",
|
|
"description": f"{len(undefined_types)} types retournent undefined",
|
|
"affected_types": undefined_types,
|
|
"actions": [
|
|
f"Ajouter une configuration pour chaque type: {', '.join(undefined_types)}",
|
|
"Définir les paramètres appropriés pour chaque type",
|
|
"Tester l'affichage des propriétés après ajout"
|
|
],
|
|
"code_example": self._generate_config_example(undefined_types[0] if undefined_types else "example")
|
|
})
|
|
|
|
# Recommandation 2: Améliorer la robustesse
|
|
usage_analysis = self.analysis_results.get("real_usage_analysis", {})
|
|
if not usage_analysis.get("has_fallback_logic", False):
|
|
recommendations.append({
|
|
"priority": "MEDIUM",
|
|
"category": "Robustesse",
|
|
"title": "Ajouter une logique de fallback pour éviter undefined",
|
|
"description": "Protéger contre les accès undefined à stepParametersConfig",
|
|
"actions": [
|
|
"Ajouter '|| []' après stepParametersConfig[selectedStep.type]",
|
|
"Implémenter une configuration par défaut",
|
|
"Ajouter des logs pour diagnostiquer les cas undefined"
|
|
],
|
|
"code_example": "const config = stepParametersConfig[selectedStep.type as StepType] || [];"
|
|
})
|
|
|
|
# Recommandation 3: Améliorer la détection VWB
|
|
vwb_actions = self.analysis_results["vwb_actions_analysis"].get("unmapped_actions", [])
|
|
if len(vwb_actions) > 5: # Si beaucoup d'actions VWB non mappées
|
|
recommendations.append({
|
|
"priority": "MEDIUM",
|
|
"category": "Détection VWB",
|
|
"title": "Renforcer la détection des actions VWB",
|
|
"description": f"{len(vwb_actions)} actions VWB pourraient être mal détectées",
|
|
"actions": [
|
|
"Améliorer les méthodes de détection VWB",
|
|
"Ajouter plus de patterns de reconnaissance",
|
|
"Tester la détection avec toutes les actions du catalogue"
|
|
]
|
|
})
|
|
|
|
# Recommandation 4: Documentation
|
|
recommendations.append({
|
|
"priority": "LOW",
|
|
"category": "Documentation",
|
|
"title": "Documenter les cas undefined et leur résolution",
|
|
"description": "Créer une documentation pour les développeurs",
|
|
"actions": [
|
|
"Documenter tous les types d'étapes supportés",
|
|
"Expliquer la différence entre types standard et VWB",
|
|
"Créer un guide de débogage pour les propriétés vides"
|
|
]
|
|
})
|
|
|
|
self.analysis_results["recommendations"] = recommendations
|
|
|
|
print(f" ✅ {len(recommendations)} recommandations générées")
|
|
|
|
def _generate_config_example(self, step_type: str) -> str:
|
|
"""Génère un exemple de configuration pour un type d'étape."""
|
|
return f"""
|
|
{step_type}: [
|
|
{{
|
|
name: 'parameter1',
|
|
label: 'Paramètre 1',
|
|
type: 'text',
|
|
required: true,
|
|
description: 'Description du paramètre'
|
|
}},
|
|
{{
|
|
name: 'parameter2',
|
|
label: 'Paramètre 2',
|
|
type: 'boolean',
|
|
defaultValue: false
|
|
}}
|
|
],"""
|
|
|
|
def _add_finding(self, severity: str, description: str, details: Dict[str, Any]):
|
|
"""Ajoute un résultat d'analyse."""
|
|
finding = {
|
|
"severity": severity,
|
|
"description": description,
|
|
"details": details,
|
|
"timestamp": time.time()
|
|
}
|
|
|
|
self.analysis_results["detailed_findings"].append(finding)
|
|
|
|
def _save_analysis_report(self):
|
|
"""Sauvegarde le rapport d'analyse."""
|
|
try:
|
|
# Créer le répertoire docs s'il n'existe pas
|
|
docs_path = self.project_root / "docs"
|
|
docs_path.mkdir(exist_ok=True)
|
|
|
|
# Sauvegarder le rapport JSON
|
|
json_report_path = docs_path / "ANALYSE_CAS_UNDEFINED_STEPPARAMETERSCONFIG_12JAN2026.json"
|
|
with open(json_report_path, 'w', encoding='utf-8') as f:
|
|
json.dump(self.analysis_results, f, indent=2, ensure_ascii=False)
|
|
|
|
# Créer un résumé markdown
|
|
md_report_path = docs_path / "ANALYSE_CAS_UNDEFINED_STEPPARAMETERSCONFIG_12JAN2026.md"
|
|
self._create_markdown_summary(md_report_path)
|
|
|
|
print(f"\n📄 Rapport JSON sauvegardé : {json_report_path}")
|
|
print(f"📄 Résumé Markdown créé : {md_report_path}")
|
|
|
|
except Exception as e:
|
|
print(f"❌ Erreur sauvegarde rapport : {e}")
|
|
|
|
def _create_markdown_summary(self, output_path: Path):
|
|
"""Crée un résumé markdown de l'analyse."""
|
|
summary = self.analysis_results["summary"]
|
|
|
|
markdown_content = f"""# Analyse des Cas Undefined - stepParametersConfig
|
|
|
|
**Auteur :** Dom, Alice, Kiro
|
|
**Date :** 12 janvier 2026
|
|
**Version :** 1.0.0
|
|
|
|
## Résumé Exécutif
|
|
|
|
- **Types d'étapes totaux :** {summary['total_step_types']}
|
|
- **Types configurés :** {summary['configured_types']}
|
|
- **Cas undefined :** {summary['undefined_cases']}
|
|
- **Actions VWB analysées :** {summary['vwb_actions_analyzed']}
|
|
- **Problèmes potentiels :** {summary['potential_issues']}
|
|
|
|
## Types Undefined Identifiés
|
|
|
|
"""
|
|
|
|
undefined_types = self.analysis_results["step_types_analysis"].get("undefined_types", [])
|
|
if undefined_types:
|
|
markdown_content += "Les types suivants retournent `undefined` dans `stepParametersConfig`:\n\n"
|
|
for step_type in undefined_types:
|
|
markdown_content += f"- `{step_type}` - Défini en TypeScript mais pas configuré\n"
|
|
else:
|
|
markdown_content += "✅ Aucun type undefined identifié.\n"
|
|
|
|
# Ajouter les recommandations
|
|
recommendations = self.analysis_results.get("recommendations", [])
|
|
if recommendations:
|
|
markdown_content += "\n## Recommandations\n\n"
|
|
for i, rec in enumerate(recommendations, 1):
|
|
markdown_content += f"### {i}. {rec['title']} ({rec['priority']})\n\n"
|
|
markdown_content += f"**Catégorie :** {rec['category']} \n"
|
|
markdown_content += f"**Description :** {rec['description']}\n\n"
|
|
|
|
if 'actions' in rec:
|
|
markdown_content += "**Actions :**\n"
|
|
for action in rec['actions']:
|
|
markdown_content += f"- {action}\n"
|
|
|
|
if 'code_example' in rec:
|
|
markdown_content += f"\n**Exemple de code :**\n```typescript\n{rec['code_example']}\n```\n"
|
|
|
|
markdown_content += "\n"
|
|
|
|
# Sauvegarder le markdown
|
|
with open(output_path, 'w', encoding='utf-8') as f:
|
|
f.write(markdown_content)
|
|
|
|
|
|
def main():
|
|
"""Fonction principale."""
|
|
print("🔍 Analyse des Cas Undefined - stepParametersConfig")
|
|
|
|
analyzer = AnalyseCasUndefinedStepParametersConfig()
|
|
results = analyzer.run_complete_analysis()
|
|
|
|
# Afficher le résumé final
|
|
print("\n" + "="*70)
|
|
print("📊 RÉSUMÉ DE L'ANALYSE DES CAS UNDEFINED")
|
|
print("="*70)
|
|
|
|
summary = results['summary']
|
|
print(f"✅ Analyse terminée avec succès")
|
|
print(f"📊 Types d'étapes totaux : {summary['total_step_types']}")
|
|
print(f"✅ Types configurés : {summary['configured_types']}")
|
|
print(f"⚠️ Cas undefined : {summary['undefined_cases']}")
|
|
print(f"🎯 Actions VWB analysées : {summary['vwb_actions_analyzed']}")
|
|
|
|
undefined_types = results["step_types_analysis"].get("undefined_types", [])
|
|
if undefined_types:
|
|
print(f"\n🚨 Types undefined identifiés :")
|
|
for step_type in undefined_types:
|
|
print(f" - {step_type}")
|
|
else:
|
|
print(f"\n🎉 Aucun type undefined critique identifié !")
|
|
|
|
recommendations = results.get("recommendations", [])
|
|
if recommendations:
|
|
print(f"\n💡 Recommandations : {len(recommendations)}")
|
|
for rec in recommendations:
|
|
print(f" - {rec['priority']}: {rec['title']}")
|
|
|
|
print(f"\n📄 Rapport complet disponible dans docs/")
|
|
|
|
# Code de sortie basé sur les cas undefined critiques
|
|
if summary['undefined_cases'] > 0:
|
|
print("⚠️ Cas undefined détectés - correction recommandée")
|
|
return 1
|
|
else:
|
|
print("🎉 Aucun cas undefined critique détecté !")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main()) |