Approbation manuelle
Ajoutez un contrôle manual_approval à n'importe quelle étape : validation via trois canaux — dans l'App, par e-mail et par API —, valeurs modifiables, rejet automatique en cas de dépassement du délai.
manual_approval encode « attendre la confirmation de quelqu'un avant de continuer » sous forme de modificateur d'étape : lorsque l'exécution atteint une étape qui le configure, elle se met en pause et le corps de l'étape ne s'exécute qu'après approbation. Avant l'approbation, le système n'exécute aucune action de cette étape ni de ses étapes en aval.
Configuration
- step: apply_changes
agent: executor
input: "把已审核的变更应用到线上"
manual_approval:
enabled: true
approvers: # 平台用户 ID;留空 = 发起人 / 有执行权限者可批
- "usr_team_lead"
timeout: 86400 # 秒;24 小时无人批复自动拒绝
approval_message: |
请确认是否应用本轮变更。
拒绝或超时不会做任何线上修改。Il peut être rattaché à n'importe quelle étape (agent, code, sub_workflow, etc.) et sert aussi souvent, sur une étape code légère qui ne fait qu'afficher un état, de pur « portail humain ».
Paramètres
| Champ | Tapez | Par défaut | Description |
|---|---|---|---|
enabled | boolean | — | Indique si le contrôle d'approbation est activé (obligatoire) |
approvers | string[] | [] | Désigne les approbateurs (ID d'utilisateur de la plateforme). Lorsqu'il est non vide, seuls les utilisateurs figurant sur la liste et les administrateurs peuvent rendre une décision — pas même l'initiateur de l'exécution, ce qui satisfait naturellement la séparation des responsabilités ; lorsqu'il est vide, l'initiateur de l'exécution ou tout collaborateur ayant le droit d'exécution sur ce workflow peut rendre une décision |
timeout | long | 3600 | Délai d'expiration en secondes. À échéance, en l'absence de décision, le rejet est automatique et l'état est marqué TIMED_OUT |
approval_message | string | null | Texte explicatif présenté à l'approbateur, apparaissant sur la carte d'approbation et dans l'e-mail de notification |
reviewable_actions | array | [] | Groupes de formulaire d'approbation modifiables ; l'approbateur peut cocher un sous-ensemble et modifier des valeurs avant d'approuver (voir ci-dessous) |
Processus d'approbation
- L'exécution se met en pause lorsqu'elle atteint une étape configurant manual_approval, et l'état d'exécution devient AWAITING_APPROVAL
- Un enregistrement d'approbation est créé et le décompte du délai commence ; la console reçoit une alerte approval_request en temps réel via WebSocket, et l'approbateur peut recevoir simultanément un e-mail de notification
- L'approbateur rend sa décision via l'un des trois canaux : la liste d'approbation dans l'application, le lien en un clic dans un message, ou l'API
- Approbation → l'étape se poursuit ; rejet → l'étape est traitée comme un échec (une branche de notification peut être raccordée via on_failure) ; expiration → rejet automatique
Canal 1 : liste d'approbation dans l'application
Le/laApprobationsde la console liste toutes les approbations qui vous sont visibles, avec deux vues (cartes/tableau) et un filtrage par état. Vous pouvez joindre une note lors de l'approbation ou du rejet, et cette note est conservée dans l'enregistrement d'approbation. Une approbation configurant reviewable_actions est développée en un tableau cochable et modifiable.
Canal 2 : notification par e-mail et lien en un clic
Une fois les notifications par e-mail activées, l'adresse e-mail du compte de l'approbateur (l'initiateur de l'exécution lorsque approvers n'est pas spécifié) reçoit un e-mail comprenant : les noms du workflow et de l'étape, l'ID d'exécution, le nombre d'actions à examiner, un rappel de délai (« rejet automatique dans environ N heures »), le texte explicatif de approval_message, ainsi qu'un lien vers la liste d'approbation.
Dans les messages ne permettant pas de personnaliser les en-têtes de requête, comme les e-mails, Slack et Telegram, il est aussi possible d'intégrer un lien de décision en un clic :
GET https://braidrun.com/api/webhook-trigger/approval/{approvalId}/approve?api_key=dyk_...
GET https://braidrun.com/api/webhook-trigger/approval/{approvalId}/reject?api_key=dyk_...Le lien s'authentifie par API Key (scope APPROVAL_RESPOND), la Key étant placée dans le paramètre de requête api_key. Pour éviter tout déclenchement accidentel par les robots de prévisualisation de liens (expansion Slack, pré-extraction des clients de messagerie), la première ouverture ne fait que rendre la page de confirmation sans exécuter la moindre action ; la décision n'est réellement rendue qu'après un nouveau clic sur le bouton de confirmation, avec confirm=1. La page porte les en-têtes no-store et noindex, afin d'éviter la mise en cache ou la réémission par les moteurs de recherche.
Canal 3 : API
L'API ouverte v1 propose 5 endpoints d'approbation, requérant tous le scope de permission APPROVAL_RESPOND :
| Endpoint | Rôle |
|---|---|
GET /api/v1/approvals | Liste des approbations, filtrable par status |
GET /api/v1/approvals/{id} | Détails d'une approbation |
GET /api/v1/approvals/execution/{executionId} | Consulter les approbations associées à une exécution |
POST /api/v1/approvals/{id}/approve | Approuver ; le body peut inclure comment et editedItems |
POST /api/v1/approvals/{id}/reject | Rejeter ; le body peut inclure comment |
# 批准(可附备注)
curl -X POST https://braidrun.com/api/v1/approvals/<approval-id>/approve \
-H "Authorization: Bearer dyk_..." \
-H "Content-Type: application/json" \
-d '{"comment": "确认执行"}'
# 拒绝
curl -X POST https://braidrun.com/api/v1/approvals/<approval-id>/reject \
-H "Authorization: Bearer dyk_..." \
-H "Content-Type: application/json" \
-d '{"comment": "本轮预算已用完"}'editedItems soumet, par nom de groupe, le sous-ensemble coché/modifié, dont la structure correspond au formulaire d'approbation modifiable de la section suivante ; s'il est omis, tout est approuvé tel quel.
Formulaire d'approbation modifiable (reviewable_actions)
Certaines approbations ont une granularité à l'échelle de la recommandation individuelle : au sein d'un lot de recommandations, seule une partie est exécutée, et certaines lignes nécessitent une modification de valeur. reviewable_actions transforme ce type d'approbation en tableau — l'approbateur coche les lignes à exécuter, modifie directement les colonnes marquées editable: true (par exemple l'enchère), puis clique sur Approuver.
manual_approval:
enabled: true
timeout: 86400
approval_message: |
请审核本轮调价建议:可勾选要执行的行,并直接修改建议出价。
reviewable_actions:
- name: raise_bid
title: 加价建议
source_var: raise_bid_file # 变量值 = 建议清单 JSON 数组文件路径
output_var: raise_bid_approved_file # 批准后 = 勾选/编辑后的子集文件路径
key_field: item_id
columns:
- { key: item_name, label: 名称, editable: false }
- { key: current_bid, label: 当前出价, type: number, editable: false }
- { key: proposed_bid, label: 建议出价, type: number, editable: true }
- { key: reason, label: 理由, editable: false }name— Nom interne du groupe, utilisé également comme préfixe du fichier de sortie (après approbation, le moteur écrit reviewed_<name>.json)source_var— Pointe vers une variable dont la valeur est la liste de recommandations générée par l'étape en amont (chemin d'un fichier de tableau JSON)output_var— Variable définie après approbation, dont la valeur est le chemin du fichier du sous-ensemble coché/modifié ; l'étape d'exécution en aval, en lisant cette variable à la place, ne traite que les lignes approuvéeskey_field— Champ d'identité de ligne, utilisé pour l'alignement après modification ; à défaut, l'alignement se fait par indice de tableaucolumns— Définition des colonnes du tableau ; l'approbateur peut modifier les colonnes editable: true, et type: number s'affiche comme une saisie numérique
Le sous-ensemble soumis est validé côté serveur : les données n'appartenant à aucun groupe sont filtrées ; lorsque key_field est défini, chaque ligne doit correspondre à un élément de la liste d'origine, et il est impossible de contourner cela en fabriquant une ligne inexistante ; les colonnes editable: false conservent leur valeur d'origine, et toute modification est sans effet. Lorsqu'aucune ligne d'un groupe n'est cochée, un tableau vide est écrit, et l'étape en aval le traite selon la règle « tout vide, ignorer ».
Rejet et expiration : aucune modification
La promesse centrale du contrôle d'approbation est la suivante : avant l'approbation, le système n'exécute aucune action. En cas de rejet ou d'expiration —
- Le corps de l'étape ne s'exécute pas, et les étapes en aval qui en dépendent ne se déclenchent pas non plus
- Une branche on_failure peut raccorder une étape de notification ou d'archivage « approbation rejetée »
- L'expiration est rejetée automatiquement par le système, avec system consigné comme décideur ; chaque décision d'approbation (dont le décideur, la date et la note) est inscrite dans le journal d'audit
Les enregistrements d'approbation sont stockés de façon persistante. Après un redémarrage du service, les approbations en attente sont restaurées à l'identique, le décompte du délai se poursuit selon l'échéance d'origine, et l'approbateur peut rendre sa décision normalement.