Skip to content

BDD-152 — Corrections canvas, prévisualisation, colonne calculée et fractionner la colonne

Contexte

Quatre anomalies ou lacunes fonctionnelles ont été identifiées dans l'éditeur de workflow :

  • L'ordre d'exécution de « Tester jusqu'ici » suivait l'ordre d'ajout des blocs sur le canvas au lieu de l'ordre topologique du graphe.
  • Le bouton de prévisualisation disparaissait après une exécution et ne réapparaissait pas même après reconfiguration d'un bloc.
  • Le bloc Colonne calculée ne supportait pas les comparaisons de type texte ([Statut] = "Actif").
  • Le bloc Fractionner la colonne ne permettait de traiter qu'une seule colonne source par bloc.

Critères d'acceptance

#CritèreCouvert par
1« Tester jusqu'ici » exécute les blocs dans l'ordre connecté du workflow, pas dans l'ordre d'ajout sur le canvascomputeAncestors (reverse BFS) + filtrage des nœuds isolés
2Le bouton de prévisualisation réapparaît après reconfiguration d'un bloc sans rechargement de pageconfigDirtyAfterRun ref + watchers sur toutes les configs de traitement
3La colonne calculée supporte les comparaisons avec un littéral texte ([col] = "valeur")Détection du contexte texte dans compileColonneCalculeeExpressionToSql
4Fractionner la colonne permet de traiter plusieurs colonnes sources dans un seul bloc, avec un nombre de parties configurable par colonneNouvelle structure splits[] dans la config, UI multi-entrées avec q-expansion-item

Corrections détaillées

1 — Ordre d'exécution « Tester jusqu'ici »

Cause : Le tri topologique (Kahn) attribuait un ordre déterministe aux nœuds isolés (sans arête) basé sur leur UUID. Un bloc Destination ajouté avant un bloc Traitement obtenait un rang inférieur et s'exécutait en premier.

Correctif : Ajout de computeAncestors (reverse BFS) dans workflow-execution-order.ts. Cette fonction remonte le graphe depuis le nœud cible et collecte tous ses ancêtres. startUntilNode filtre ensuite la liste ordonnée pour ne conserver que les nœuds connectés et ancêtres du nœud cible, excluant les nœuds isolés.

2 — Bouton de prévisualisation après reconfiguration

Cause : showNodeRunIo restait true après une exécution, masquant le bouton de prévisualisation via :show-design-preview="!showNodeRunIo". Modifier la configuration d'un bloc ne réinitialisait pas cet état.

Correctif : Introduction d'une ref configDirtyAfterRun dans WorkflowEditorPage.vue. Un watcher profond sur toutes les configs de traitement actives positionne ce flag à true dès qu'une modification intervient après une exécution. La prop devient :show-design-preview="!showNodeRunIo || configDirtyAfterRun", ce qui restaure le bouton de prévisualisation immédiatement après toute reconfiguration.

3 — Comparaison texte dans la colonne calculée

Cause : La compilation SQL du cas compare forçait systématiquement le contexte numérique (::NUMERIC), rendant impossible la comparaison d'une colonne avec un littéral texte (chaîne entre guillemets simples).

Correctif : Dans compileColonneCalculeeExpressionToSql, le cas compare détecte si l'un des opérandes est un nœud de type string. Si c'est le cas, les deux opérandes sont compilés en contexte texte (TRIM(COALESCE(...))) au lieu du contexte numérique.

4 — Fractionner plusieurs colonnes dans un seul bloc

Cause : La configuration DecouperColonneConfig ne décrivait qu'une seule entrée { sourceColumn, separator, outputColumns }.

Correctif : La structure de configuration passe à { type, splits: DecouperColonneSplitEntry[] } où chaque entrée décrit une colonne source à fractionner avec son séparateur et ses colonnes de sortie. La compatibilité ascendante est assurée : l'ancienne config à champ plat est automatiquement migrée en splits[0] lors de la normalisation, sans perte de données.

L'interface utilisateur adopte le pattern q-expansion-item (même modèle que « Ligne de synthèse ») : chaque entrée est une carte repliable affichant le nom de la colonne source, le séparateur et la liste des parties. Un bouton « Ajouter une colonne à fractionner » permet d'ajouter de nouvelles entrées.

Correction additionnelle : La normalisation du séparateur utilisait sanitizeText (qui appelle .trim()), ce qui effaçait silencieusement un séparateur espace et le remplaçait par la virgule par défaut. Le séparateur est désormais converti en chaîne sans trim, préservant les espaces.

Architecture

Nouvelle structure de configuration

// Ancien format (toujours accepté — migration automatique)
{ type: 'decouper_colonne', sourceColumn, separator, outputColumns[] }

// Nouveau format
{ type: 'decouper_colonne', splits: [{ sourceColumn, separator, outputColumns[] }, ...] }

La normalisation (normalizeDecouperColonneConfig / normalizeDecouperColonneConfigForUi) détecte la présence ou l'absence du champ splits pour décider du chemin de migration.

La validation parcourt tous les splits et vérifie l'unicité des noms de colonnes de sortie toutes entrées confondues.

Le SQL généré par le staging enchaîne les split_part(...) de chaque entrée dans un seul SELECT, en incrémentant l'offset des colonnes de sortie à chaque entrée.

Fichiers modifiés

FichierModification
back/src/api/workflows/execution/workflow-execution-order.tsAjout de computeAncestors (reverse BFS)
back/src/api/workflows/staging/workflow-run-staging-execution.service.tsRetourne graphEdges pour startUntilNode
back/src/api/workflows/workflow-debug-run.service.tsstartUntilNode utilise computeAncestors pour filtrer les nœuds isolés
back/src/api/workflows/execution/workflow-colonne-calculee.engine.tsDétection du contexte texte dans compare
back/src/api/workflows/execution/workflow-decouper-colonne.engine.tsNouveau type DecouperColonneSplitEntry, structure splits[], backward compat
back/src/api/workflows/staging/workflow-decouper-colonne-staging.service.tsSQL multi-splits
back/src/api/workflows/staging/workflow-traitement-type-overrides.util.tsbuildDecouperColonneTypeOverrides lit splits.flatMap(...)
front/src/pages/admin/workflows/WorkflowEditorPage.vueconfigDirtyAfterRun ref + watchers, correction prop show-design-preview
front/src/pages/admin/workflows/workflow-execution-order.jsMiroir JS de computeAncestors
front/src/pages/admin/workflows/workflow-decouper-colonne.engine.jsStructure splits[], backward compat, préservation séparateur espace
front/src/pages/admin/workflows/workflow-traitement-output-columns.helpers.jsbuildDecouperColonneOutputColumns lit splits.flatMap(...)
front/src/components/workflows/WorkflowDecouperColonnePanel.vueUI multi-entrées avec q-expansion-item