Appearance
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ère | Couvert par |
|---|---|---|
| 1 | « Tester jusqu'ici » exécute les blocs dans l'ordre connecté du workflow, pas dans l'ordre d'ajout sur le canvas | computeAncestors (reverse BFS) + filtrage des nœuds isolés |
| 2 | Le bouton de prévisualisation réapparaît après reconfiguration d'un bloc sans rechargement de page | configDirtyAfterRun ref + watchers sur toutes les configs de traitement |
| 3 | La colonne calculée supporte les comparaisons avec un littéral texte ([col] = "valeur") | Détection du contexte texte dans compileColonneCalculeeExpressionToSql |
| 4 | Fractionner la colonne permet de traiter plusieurs colonnes sources dans un seul bloc, avec un nombre de parties configurable par colonne | Nouvelle 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
| Fichier | Modification |
|---|---|
back/src/api/workflows/execution/workflow-execution-order.ts | Ajout de computeAncestors (reverse BFS) |
back/src/api/workflows/staging/workflow-run-staging-execution.service.ts | Retourne graphEdges pour startUntilNode |
back/src/api/workflows/workflow-debug-run.service.ts | startUntilNode utilise computeAncestors pour filtrer les nœuds isolés |
back/src/api/workflows/execution/workflow-colonne-calculee.engine.ts | Détection du contexte texte dans compare |
back/src/api/workflows/execution/workflow-decouper-colonne.engine.ts | Nouveau type DecouperColonneSplitEntry, structure splits[], backward compat |
back/src/api/workflows/staging/workflow-decouper-colonne-staging.service.ts | SQL multi-splits |
back/src/api/workflows/staging/workflow-traitement-type-overrides.util.ts | buildDecouperColonneTypeOverrides lit splits.flatMap(...) |
front/src/pages/admin/workflows/WorkflowEditorPage.vue | configDirtyAfterRun ref + watchers, correction prop show-design-preview |
front/src/pages/admin/workflows/workflow-execution-order.js | Miroir JS de computeAncestors |
front/src/pages/admin/workflows/workflow-decouper-colonne.engine.js | Structure splits[], backward compat, préservation séparateur espace |
front/src/pages/admin/workflows/workflow-traitement-output-columns.helpers.js | buildDecouperColonneOutputColumns lit splits.flatMap(...) |
front/src/components/workflows/WorkflowDecouperColonnePanel.vue | UI multi-entrées avec q-expansion-item |
