Boucles de rejet et de reprise
Comment rédiger des flux de séquence arrière — branches de rejet d'approbation et renvoi manuel — et comment la réouverture pilotée par les dépendances protège le travail terminé tout en refaisant exactement ce qui doit l'être.
Comment l'aborder. Un modèle de Process Flow est une séquence de phases (Stages). La progression vers l'avant suit le flux de séquence BPMN normal. Les branchements et le parallélisme se situent à l'intérieur d'une Stage — rédigez-les sous forme de workflow de canevas rattaché à une action workflow (le bloc router pour les passerelles exclusives, des sous-processus parallèles pour la répartition). Le rejet et la reprise se produisent entre les Stages : lorsqu'une porte d'approbation rejette, ou qu'un relecteur renvoie une carte sur le tableau Kanban, la plateforme achemine l'exécution vers une Stage antérieure — le motif BPMN de boucle de reprise. Le modèle à trois niveaux (Stage / Task / Action) reprend la terminologie des plan items de CMMN, mais le modèle d'exécution est BPMN : un flux de séquence orienté avec des arcs arrière pilotés par des événements.
Trois façons de revenir en arrière dans un processus
1. Branche de rejet d'approbation
Une action approval peut déclarer ce qui se passe lorsque l'approbateur clique sur Reject. Définissez onReject.returnToStage dans les metadata de l'action avec le slug d'une Stage antérieure. Lorsque cet approbateur rejette la porte, la plateforme renvoie automatiquement l'instance vers cette Stage.
import { defineAction } from '@scrydon/sdk-authoring/process-flows'
defineAction({
name: 'Approve rollout plan',
actionType: 'approval',
isRequired: true,
executionMode: 'manual',
metadata: {
persona: 'champion',
onReject: {
returnToStage: 'planning', // ← slug of the earlier stage to reopen
},
},
})Le slug doit se résoudre en une Stage antérieure dans la séquence de Stages du modèle. La plateforme le valide à l'import de l'extension — une branche de rejet pointant vers l'avant ou vers la même Stage est rejetée avec une erreur de validation.
Lorsque le rejet se déclenche :
- La porte d'approbation enregistre le rejet (acteur, horodatage, éventuel commentaire).
- L'instance revient à la
returnToStage. - La plateforme applique les règles de réouverture pilotée par les dépendances décrites ci-dessous pour décider quel travail en aval est réactivé et lequel reste intact.
Le rejet ne supprime pas l'historique. Le journal d'activité conserve les événements terminés de l'exécution précédente — documents, uploads, approbations — même pour les actions rouvertes. Les relecteurs voient la chronologie complète de ce qui a changé entre les tours.
2. Renvoi manuel
Sur le tableau Kanban, un administrateur d'espace de travail ou le propriétaire du flow peut faire glisser une carte vers une colonne de Stage antérieure déjà terminée, ou utiliser le menu Send back to… de la carte. C'est l'équivalent manuel de la branche de rejet d'approbation.
Avant que le déplacement ne soit validé, une boîte de dialogue de confirmation indique :
- La Stage à laquelle l'instance va revenir.
- Les tâches et actions en aval qui seront rouvertes en conséquence (en fonction des dépendances déclarées — voir ci-dessous).
- Le travail terminé qui sera préservé (tâches indépendantes sans dépendance déclarée envers la Stage cible).
La boîte de dialogue donne au relecteur les informations nécessaires pour prendre une décision éclairée avant de valider.
Le renvoi manuel est disponible pour les administrateurs d'espace de travail et les propriétaires de process flow. Les simples assignataires de tâches voient la carte mais ne peuvent pas initier eux-mêmes le renvoi.
3. Soumettre à nouveau directement une porte rejetée
Si la correction d'une porte rejetée ne nécessite pas de revenir à une Stage antérieure — par exemple, rattacher à nouveau un fichier manquant qui appartient à la Stage de la porte elle-même — le panneau de détail de tâche de l'approbateur propose un bouton Resubmit for decision directement sur le verdict de rejet, dans chaque vue (Kanban, List et Wizard). Cela remet la porte — et, pour un flow sequential, chaque Stage ultérieure — dans un état exploitable, exactement comme un renvoi manuel vers cette même Stage, sans obliger le relecteur à naviguer d'abord vers une autre Stage.
L'approbateur est invité à saisir un motif (prérempli à partir du commentaire de rejet d'origine, modifiable), et la plateforme notifie à nouveau la personne qui doit prendre la décision suivante. Le verdict précédent n'est jamais supprimé en silence — il reste visible sous forme de note « Previously rejected on… » une fois la porte revenue en attente de décision.
Ce qui se passe lors de l'aller-retour
Réouverture pilotée par les dépendances
Lorsqu'une Stage est réintégrée — que ce soit par une branche de rejet d'approbation ou par un renvoi manuel — la plateforme ne rouvre pas aveuglément tout le travail en aval. Elle ne rouvre que les tâches et actions qui ont déclaré une dépendance envers la Stage concernée ou ses tâches.
Le travail terminé indépendant est préservé. Si une piste parallèle s'est terminée et n'a aucune dépendance déclarée envers la Stage rouverte, elle reste terminée avec son historique d'origine intact. Cela évite des reprises inutiles et maintient la cohérence de la piste d'audit.
Les dépendances déclarées pilotent précisément la réouverture. Une action workflow qui a déclaré metadata.retrieval.inputs: [{ fromTask: "upload-documents" }] sait qu'elle dépend de la sortie de la tâche upload-documents. Lorsque la Stage de cette tâche est réintégrée et que l'action upload-documents est rouverte, l'action workflow en aval est également rouverte — car son entrée a pu changer.
Les flux de Stages séquentiels sont la seule exception. Si votre modèle utilise la valeur par défaut stageFlow: 'sequential', chaque Stage située après la cible de réouverture est toujours incluse dans la réouverture, que vous ayez déclaré une dépendance ou non — le verrouillage séquentiel est en soi une relation inter-Stages, de sorte qu'une Stage qui n'était atteignable que parce qu'une précédente s'était terminée est considérée comme dépendante de celle-ci. Les dépendances déclarées (fromTask, dependsOn) restent importantes pour les flows parallel / flexible, et pour aller au-delà des Stages sœurs de la Stage immédiatement rouverte dans un flow séquentiel qui comporte aussi des arêtes explicites intra-Stage.
Conseils d'authoring : déclarez vos dépendances inter-Stages
La logique de réouverture suit le graphe de dépendances que vous rédigez, plus — pour les flows séquentiels — la séquence de Stages elle-même. Les dépendances non déclarées dans un flow parallel ou flexible sont invisibles pour la plateforme — si une tâche en aval devrait logiquement être réexécutée après la reprise d'une Stage amont mais n'a aucune dépendance déclarée envers elle, la plateforme la laissera terminée.
Déclarez explicitement les dépendances de données inter-Stages. Utilisez
metadata.retrieval.inputs[].fromTasksur les actionsworkflowet des arêtesdependsOnsur les tâches pour câbler le graphe de dépendances. Plus le graphe est complet, plus le rayon d'impact de la réouverture est précis — exactement le bon travail est refait, ni plus ni moins.
Un graphe bien déclaré signifie :
- Une réouverture correcte : les tâches qui dépendent de données retravaillées sont réactivées automatiquement.
- Un travail préservé : les tâches indépendantes traversent la boucle intactes.
- Une lecture claire pour les relecteurs : la boîte de dialogue de confirmation avant renvoi montre exactement ce qui va changer.
Restreindre les Stages vers lesquelles une Stage peut être renvoyée
Par défaut, n'importe quelle Stage peut être renvoyée manuellement vers n'importe quelle Stage antérieure de la séquence. Si votre modèle comporte des contraintes de gouvernance — par exemple, une Stage de revue juridique ne devrait jamais revenir qu'à la Stage précédente, jamais à la Stage 1 — déclarez allowedReturnStages sur la Stage :
import { defineProcessFlow, defineStage } from '@scrydon/sdk-authoring/process-flows'
defineProcessFlow({
// ...
template: {
// ...
stages: [
defineStage({
slug: 'drafting',
name: 'Drafting',
transitionMode: 'automatic',
}),
defineStage({
slug: 'legal-review',
name: 'Legal Review',
transitionMode: 'manual',
allowedReturnStages: ['drafting'], // ← only this stage is a valid send-back target
}),
defineStage({
slug: 'sign-off',
name: 'Sign-off',
transitionMode: 'manual',
allowedReturnStages: ['legal-review', 'drafting'], // ← both are valid targets
}),
],
// ...
},
})Lorsque allowedReturnStages est défini :
- Le menu Send back to… du tableau Kanban ne propose que les Stages listées.
- La plateforme applique cette liste côté serveur sur la route de renvoi manuel. Si un appelant tente un renvoi vers une Stage absente de
allowedReturnStages, la requête est rejetée avec403 target_not_allowed. Le menu de l'interface est une commodité — l'application fait autorité au niveau de l'API. - La branche de rejet d'approbation (
onReject.returnToStage) est déclarée par l'auteur et est exemptée du contrôleallowedReturnStages— sa cible est validée à la place au moment de l'import de l'extension. - Gardez le
onReject.returnToStagede chaque approbation dans lesallowedReturnStagesde la Stage afin que la boucle de reprise déclarée reste cohérente avec la liste de gouvernance. - Un tableau vide (
[]) signifie que le tableau Kanban ne propose aucune cible de renvoi manuel depuis cette Stage, et toute requête de renvoi manuel sera rejetée par l'API. - Omettre complètement
allowedReturnStagessignifie que le renvoi est libre vers n'importe quelle Stage antérieure (comportement par défaut).
Tous les slugs listés dans allowedReturnStages doivent être des Stages qui apparaissent plus tôt dans la séquence de Stages du modèle. La plateforme le valide à l'import de l'extension et rejette toute référence vers l'avant ou vers elle-même.
Rédiger une boucle de reprise complète
L'exemple suivant câble les deux mécanismes — une branche de rejet sur la porte d'approbation et une restriction de gouvernance sur la Stage de signature — dans un court flow de revue de contrat en trois Stages.
import {
defineProcessFlow,
defineStage,
defineTask,
defineAction,
} from '@scrydon/sdk-authoring/process-flows'
export default defineProcessFlow({
manifestVersion: 1,
package: { id: 'acme-contract-review', name: 'Acme Contract Review', version: '1.0.0' },
template: {
slug: 'contract-review',
name: 'Contract Review',
version: '1.0.0',
stages: [
defineStage({
slug: 'drafting',
name: 'Drafting',
transitionMode: 'automatic',
}),
defineStage({
slug: 'legal-review',
name: 'Legal Review',
transitionMode: 'manual',
// Legal review can only be sent back to Drafting, not skipped further back.
allowedReturnStages: ['drafting'],
}),
defineStage({
slug: 'sign-off',
name: 'Sign-off',
transitionMode: 'manual',
// Sign-off can return to either earlier stage.
allowedReturnStages: ['legal-review', 'drafting'],
}),
],
taskTemplates: [
defineTask({
slug: 'draft-contract',
stageSlug: 'drafting',
name: 'Draft contract',
actions: [
defineAction({
name: 'Upload contract draft',
actionType: 'file_upload',
isRequired: true,
metadata: { persona: 'author', acceptedExtensions: ['.pdf', '.docx'] },
}),
],
}),
defineTask({
slug: 'legal-check',
stageSlug: 'legal-review',
name: 'Legal check',
actions: [
defineAction({
name: 'Review contract draft',
actionType: 'approval',
isRequired: true,
metadata: {
persona: 'legal',
onReject: {
// Rejection routes back to Drafting — the author must revise.
returnToStage: 'drafting',
},
},
}),
],
}),
defineTask({
slug: 'executive-sign-off',
stageSlug: 'sign-off',
name: 'Executive sign-off',
actions: [
defineAction({
name: 'Approve contract',
actionType: 'approval',
isRequired: true,
metadata: {
persona: 'executive',
onReject: {
// Rejection routes back to Legal Review for another pass.
returnToStage: 'legal-review',
},
},
}),
],
}),
],
personas: [
{ slug: 'author', name: 'Author' },
{ slug: 'legal', name: 'Legal Counsel' },
{ slug: 'executive', name: 'Executive' },
],
voiceTriggers: [],
},
})Dans ce flow :
- L'approbation Legal Review rejette → retour à Drafting (la branche
onReject). - L'approbation Sign-off rejette → retour à Legal Review pour un second passage.
- Un administrateur d'espace de travail peut renvoyer manuellement la carte Kanban de Sign-off vers Legal Review ou Drafting (selon
allowedReturnStages), mais Legal Review ne peut revenir qu'à Drafting — sans le contourner vers Sign-off.
Liste de contrôle de validation
extension validate applique ces règles avant la construction d'une archive :
| Règle | Erreur affichée |
|---|---|
onReject.returnToStage doit nommer une Stage qui apparaît avant la Stage courante | returnToStage "sign-off" is not an earlier stage |
onReject.returnToStage doit figurer dans allowedReturnStages lorsque la Stage le déclare | returnToStage "drafting" is not in allowedReturnStages for stage "legal-review" |
Les slugs de allowedReturnStages doivent être des Stages antérieures | allowedReturnStages contains forward reference "sign-off" |
onReject n'est valide que sur actionType: "approval" | onReject is not valid on actionType "checklist" |
Voir aussi
La référence complète des huit types d'actions, y compris le bloc de métadonnées approval complet.
Livrez la logique de workflow en ligne dans un modèle de process flow — privée, propre à chaque instance et invisible en dehors du flow.
La page parente — anatomie d'un modèle, exemple complet, étapes de build/upload, plafonds de sécurité.