Skip to content

BDD-155 — Écraser la source de sortie existante lors de la réexécution d'un workflow

1. User Story

En tant qu'utilisateur, je veux que la réexécution d'un workflow avec le même nom de source écrase la source existante sans créer de version supplémentaire, afin d'éviter l'accumulation de versions inutiles (résultat V2, V3…) dans le menu Sources.

2. Critères d'acceptance

#CritèreStatut
1Réexécution avec le même nom → la source existante est écrasée (même UUID, même version)
2L'utilisateur voit une notification toast confirmant l'écrasement
3L'utilisateur change le nom vers un nom déjà existant → une boîte de dialogue s'affiche pour choisir entre écraser ou créer une nouvelle version
4Les sources existantes dans les blocs Entrée (BDD-149) ne sont pas impactées

3. Périmètre fonctionnel

Backend

FichierRôle
back/src/api/workflows/staging/workflow-heriade-publish.service.tsAjout du paramètre overwrite?: boolean dans publishFromStaging. En mode overwrite, UPDATE le source record existant (même UUID, même version) au lieu de créer une V2. Retourne overwrote: boolean dans le résultat.
back/src/api/workflows/staging/workflow-destination-run.service.tsTransmet overwrite: config.overwriteExistingSource ?? true à publishFromStaging. Propage overwrote dans DestinationRunResult.
back/src/api/workflows/staging/workflow-run-staging-execution.service.tsPropage overwrote depuis le résultat destination vers successResult du nœud.
back/src/api/workflows/dto/workflow-run.dto.tsAjout du champ overwrote?: boolean dans WorkflowNodeRunResultDto.
back/src/api/sources/dto/workflow-published-name-check.dto.tsNouveau DTO WorkflowPublishedNameCheckResponseDto pour l'endpoint de vérification de nom.
back/src/api/sources/sources.service.tsNouvelle méthode checkWorkflowPublishedNameExists : vérifie l'existence d'une source active avec le même publish_group_key.
back/src/api/sources/sources.controller.tsNouvel endpoint GET /sources/workflow-published/check-name?name=… protégé par AuthGuard + AdminGuard.

Frontend

FichierRôle
front/src/pages/admin/workflows/workflow-destination.engine.jsnormalizeDestinationConfigForUi préserve overwriteExistingSource uniquement si explicitement défini (évite le cycle autosave). applyDestinationExecutionResult stocke overwrote dans lastResult.
front/src/composables/useWorkflowPublishNameCheck.jsComposable checkWorkflowPublishedNameExists(name) : appel GET /sources/workflow-published/check-name.
front/src/composables/useWorkflowRun.jsPropage overwrote dans l'objet execution. Déclenche une notification toast si overwrote === true après une exécution réussie.
front/src/components/workflows/WorkflowDestinationPanel.vueDétecte le changement de nom vers un nom existant (via checkWorkflowPublishedNameExists) et affiche une q-dialog pour choisir entre écraser ou créer une nouvelle version.

4. Comportement détaillé

Logique d'écrasement (backend)

Lorsque overwrite=true (valeur par défaut) et qu'une source active avec le même publish_group_key existe :

  1. Acquisition du verrou advisory PostgreSQL sur heriade_publish:{enterpriseId}:{publishGroupKey}
  2. Recherche de la source active (deprecated_at IS NULL, deleted_at IS NULL)
  3. DROP TABLE IF EXISTS + CREATE TABLE + INSERT (copie depuis staging)
  4. UPDATE sources SET row_count, last_loaded_at, published_from_run_uuidle UUID et la version sont conservés
  5. Retourne overwrote: true

Si aucune source active n'existe, la logique de création standard s'applique (overwrote: false).

Logique de changement de nom (frontend)

Lorsque l'utilisateur modifie le nom de la source dans le panneau Destination :

  1. Après 400 ms de debounce (ou au blur), appel GET /sources/workflow-published/check-name?name=…
  2. Si la réponse indique exists: true, affichage d'une q-dialog avec trois choix :
    • Annuler : le nom n'est pas appliqué
    • Créer une nouvelle version : overwriteExistingSource = false
    • Écraser : overwriteExistingSource = true
  3. Le choix est persisté dans la configuration du nœud canvas

5. Points d'attention

  • BDD-149 non impacté : normalizeDestinationConfigForUi n'injecte plus overwriteExistingSource par défaut, évitant le cycle autosave qui brisait la transmission de données Entrée → Traitement.
  • Pas de soft delete ni de hard delete : l'écrasement modifie uniquement les données de la table PostgreSQL et met à jour le record source en base. L'ancien enregistrement n'est ni déprécié ni supprimé.
  • Verrou advisory : garantit l'absence de race condition si deux exécutions parallèles publient sur le même groupe.