Skip to content

BDD-139 — Entrée dossier avec ligne de titres et nom_du_fichier

1. User Story

En tant qu'administrateur, je veux sélectionner un dossier du dépôt comme source d'un workflow (au lieu d'un seul fichier), afin de charger automatiquement tous les fichiers compatibles du dossier à l'exécution, avec une ligne d'en-tête configurable et une colonne indiquant l'origine de chaque ligne.

2. Critères d'acceptance

#CritèreStatut
1Le panneau Entrée (fichier dépôt) propose un basculement Fichier / Dossier
2En mode Dossier : sélection d'un dossier accessible + saisie de la ligne d'en-tête (1-based)
3Aperçu des données fusionnées (échantillon) avec bannière récapitulative
4À l'exécution : tous les fichiers compatibles du dossier sont chargés et empilés
5Chaque ligne porte la colonne nom_du_fichier
6En-têtes incohérents entre fichiers → erreur claire
7La configuration est sauvegardée avec le canvas workflow

3. Périmètre fonctionnel

Règles métier

  • Périmètre fichiers : enfants directs du dossier sélectionné uniquement.
  • Extensions : .csv, .xls, .xlsx, .json.
  • Tri : nom de fichier croissant.
  • Ligne d'en-tête : headerRowIndex (défaut 1), appliquée à chaque fichier.
  • Fichiers non compatibles : ignorés ; l'UI affiche le nombre retenu sur le total.
  • Mode fichier unique : comportement existant inchangé.

Frontend

FichierRôle
WorkflowDepotSourcePanel.vueBascule Fichier / Dossier dans le mode dépôt
WorkflowDepotFolderSourcePanel.vueSélection dossier, ligne d'en-tête, aperçu
WorkflowSourceSelectorPanel.vueIntégration du panneau dépôt étendu
workflow-folder-source-preview.fetch.jsAppel GET /workflows/depot-folder-preview
useWorkflowActiveSourceBindings.jsLiaisons depotSourceScope, inputFolderUuid, headerRowIndex
workflow-canvas.model.js / workflow-canvas.sync.jsPersistance canvas
workflow-traitement-preview.pipeline.jsAperçu traitements amont depuis source dossier

Backend

FichierRôle
sql/tool_20_workflow_input_folder.sqlColonne workflow_nodes.input_folder_id
workflow-canvas-folder-bindings.tsRésolution UUID dossier → id (contrôle d'accès)
workflow-source-depot-config.tsNormalisation depotSourceScope / headerRowIndex
workflow-depot-folder-parse.util.tsParse CSV / Excel / JSON avec ligne d'en-tête
workflow-depot-folder-input.service.tsFusion fichiers + nom_du_fichier → staging
workflow-depot-folder-preview.service.tsAperçu éditeur dossier
workflow-run-staging-execution.service.tsDispatch source dossier à l'exécution
workflows.controller.tsEndpoint depot-folder-preview
workflow.presenter.tsChamps dossier dans la réponse canvas

Base de données

ChangementDétail
workflow_nodes.input_folder_idFK nullable vers folders.id
workflow_nodes.configuration.sourceDepot{ depotSourceScope: "folder" | "file", headerRowIndex: number }

4. Endpoints API

MéthodeCheminGuardsDescription
GET/workflows/depot-folder-previewAuthGuard, AdminGuardAperçu fusionné d'un dossier dépôt
PUT/workflows/current/canvasAuthGuard, AdminGuardSauvegarde nœud source avec inputFolderUuid

Query GET /workflows/depot-folder-preview

ParamètreObligatoireDescription
folderUuidouiUUID du dossier
headerRowIndexnonLigne d'en-tête 1-based (défaut 1)

Exemple de réponse

json
{
  "folder": { "uuid": "…", "name": "Salaires" },
  "documentCount": 2,
  "totalDocuments": 3,
  "headerRowIndex": 1,
  "columns": [
    { "name": "code", "inferredType": "texte" },
    { "name": "nom_du_fichier", "inferredType": "texte" }
  ],
  "rows": [
    { "code": "A", "nom_du_fichier": "janvier.csv" }
  ],
  "hint": "Aperçu limité à 20 lignes."
}

Payload canvas (extrait nœud source)

json
{
  "id": "…",
  "type": "source",
  "sourceMode": "document",
  "depotSourceScope": "folder",
  "inputFolderUuid": "uuid-dossier",
  "headerRowIndex": 2
}

5. Tests

CoucheFichiers
Back unitworkflow-source-depot-config.spec.ts, workflow-canvas-folder-bindings.spec.ts, workflow-depot-folder-parse.util.spec.ts, workflow-depot-folder-input.service.spec.ts, workflows.service.spec.ts, workflow-group-by.engine.spec.ts, workflow-group-by-staging.service.spec.ts
Back e2etest/e2e/workflows-controller.e2e-spec.tsdepot-folder-preview, persistance canvas dossier, persistance canvas group_by
Front unitWorkflowDepotSourcePanel.spec.js, workflow-folder-source-preview.fetch.spec.js, useWorkflowActiveSourceBindings.spec.js, workflow-canvas.model.spec.js, workflow-group-by.engine.spec.js, workflow-traitement-preview.pipeline.spec.js, workflow-traitement.sync.spec.js, workflow-run-validation.spec.js
Front e2ee2e/pages/admin/admin-workflows.spec.js — sélection dossier + PUT canvas, aperçu group_by

6. Documentation technique

7. Extension (même branche) — Regrouper et calculer (GROUP BY)

Livré sur la branche BDD-139 : nouveau bloc de traitement distinct de la Ligne de synthèse.

Objectif

Remplacer les lignes détail par des lignes agrégées (équivalent SQL GROUP BY), sans ajouter de lignes en fin de tableau.

Périmètre

  • Sous-type Traitement : group_by (libellé UI : Regrouper et calculer).
  • Colonnes de sortie = groupByColumns + colonnes cibles des metrics ; les autres colonnes amont sont supprimées.
  • Calculs : SUM, COUNT, COUNT DISTINCT, AVG, MIN, MAX (même moteur d’agrégats que la ligne de synthèse).
  • groupByColumns vide : agrégat global sur toutes les lignes.
  • Exécution : WorkflowGroupByStagingService (CREATE TABLE … AS SELECT … GROUP BY).

Différence avec Ligne de synthèse (BDD-134)

Regrouper et calculerLigne de synthèse
EffetRemplace le détailConserve le détail + ajoute des lignes
SQLGROUP BYUNION ALL

Configuration JSONB (extrait)

json
{
  "type": "group_by",
  "groupByColumns": ["Matricule", "Mois"],
  "metrics": [
    { "sourceColumn": "Montant", "fn": "SUM", "targetColumn": "Montant_total" }
  ]
}

Fichiers principaux

RôleChemin
Moteur frontfront/src/pages/admin/workflows/workflow-group-by.engine.js
Panneau UIfront/src/components/workflows/WorkflowGroupByPanel.vue
Moteur backback/src/api/workflows/execution/workflow-group-by.engine.ts
Staging SQLback/src/api/workflows/staging/workflow-group-by-staging.service.ts