feat: import Excel → SQLite + boucle données → UI dans le VWB

- ExcelImporter : import .xlsx → SQLite auto (détection types, batch insert)
- DBIterator : lecture ligne par ligne avec filtre/tri/limite
- VWB actions : "Importer Excel" + "Pour chaque ligne" dans la palette
- DAG executor : pré-exécution import, boucle foreach avec injection
  ${current_row.colonne} dans les étapes dépendantes
- 36 tests unitaires Excel/DB (tous passent)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Dom
2026-03-16 23:10:51 +01:00
parent 5e3865d328
commit 9da804bb6e
9 changed files with 1832 additions and 4 deletions

View File

@@ -315,6 +315,23 @@ VWB_ACTION_CONTRACTS: Dict[str, ActionContract] = {
param_validators={"visual_anchor": lambda p: has_visual_anchor({"visual_anchor": p})}
),
# --- BOUCLE DONNÉES (Data Loop) ---
"import_excel": ActionContract(
action_type="import_excel",
description="Importer un fichier Excel dans la base SQLite",
required_params=["file_path"],
optional_params=["table_name", "sheet_name"],
param_validators={"file_path": lambda p: bool(p and isinstance(p, str) and p.strip())}
),
"db_foreach": ActionContract(
action_type="db_foreach",
description="Boucle sur chaque ligne d'une table et exécute les étapes dépendantes",
required_params=["table_name"],
optional_params=["where_clause", "order_by", "limit"],
param_validators={"table_name": lambda p: bool(p and isinstance(p, str) and p.strip())}
),
# --- ACTIONS DAG LLM — Exécutées via le DAGExecutor ---
"llm_analyze": ActionContract(
action_type="llm_analyze",