Zum Hauptinhalt springen
DokumentLaufenManuelle Genehmigung

Manuelle Genehmigung

In jedem Schritt eine manual_approval-Steuerung hinzufügen: Bearbeitung über die drei Kanäle in der App, per E-Mail und über die API, mit editierbaren Werten und automatischer Ablehnung bei Zeitüberschreitung.

manual_approval kodiert „auf die Bestätigung einer Person warten, bevor fortgefahren wird“ als Schrittmodifikator: Erreicht die Ausführung einen Schritt, der ihn konfiguriert hat, pausiert sie und führt den eigentlichen Schritt erst nach der Genehmigung aus. Vor der Genehmigung führt das System weder diesen Schritt noch irgendeine nachgelagerte Aktion aus.

Konfiguration

yaml
  - step: apply_changes
    agent: executor
    input: "把已审核的变更应用到线上"
    manual_approval:
      enabled: true
      approvers:            # 平台用户 ID;留空 = 发起人 / 有执行权限者可批
        - "usr_team_lead"
      timeout: 86400        # 秒;24 小时无人批复自动拒绝
      approval_message: |
        请确认是否应用本轮变更。
        拒绝或超时不会做任何线上修改。

Er lässt sich an jeden Schritt hängen (agent, code, sub_workflow usw.) und wird oft auch bei einem leichtgewichtigen code-Schritt eingesetzt, der nur den Status ausgibt, als reines „manuelles Gate“.

Parameter

FeldTypStandardBeschreibung
enabledbooleanOb das Genehmigungs-Gate aktiviert ist (Pflichtfeld)
approversstring[][]Legt die Genehmiger fest (Plattform-Nutzer-IDs). Ist die Liste nicht leer, können nur die aufgeführten Nutzer und Administratoren entscheiden — auch der Auslöser der Ausführung nicht, was von Natur aus die Funktionstrennung erfüllt; bleibt sie leer, kann der Auslöser der Ausführung oder ein Mitarbeiter mit Ausführungsrechten für diesen Workflow entscheiden
timeoutlong3600Timeout in Sekunden. Entscheidet bis dahin niemand, erfolgt eine automatische Ablehnung mit dem Status TIMED_OUT
approval_messagestringnullDer dem Genehmiger angezeigte Hinweis, der auf der Genehmigungskarte und in der Benachrichtigungs-E-Mail erscheint
reviewable_actionsarray[]Gruppen des bearbeitbaren Genehmigungsformulars; der Genehmiger kann eine Teilmenge auswählen und Werte bearbeiten, bevor er genehmigt (siehe unten)

Genehmigungsprozess

  1. Erreicht die Ausführung einen Schritt mit konfiguriertem manual_approval, pausiert sie, und der Ausführungsstatus wechselt zu AWAITING_APPROVAL
  2. Erstellt einen Genehmigungsdatensatz und startet den Timeout-Zähler; die Konsole erhält über WebSocket die Echtzeitbenachrichtigung approval_request, und der Genehmiger kann zugleich eine Benachrichtigungs-E-Mail erhalten
  3. Der Genehmiger entscheidet über einen von drei Kanälen: die In-App-Genehmigungsliste, den Ein-Klick-Link in einer Nachricht oder die API
  4. Genehmigen → der Schritt wird fortgesetzt; ablehnen → der Schritt wird als Fehler behandelt (per on_failure lässt sich ein Benachrichtigungszweig anschließen); Timeout → automatische Ablehnung

Kanal 1: In-App-Genehmigungsliste

DieFreigaben-Seite der Konsole listet alle für Sie sichtbaren Genehmigungen auf und unterstützt eine Karten- und eine Tabellenansicht sowie einen Statusfilter. Beim Genehmigen oder Ablehnen lässt sich eine Anmerkung anfügen, die im Genehmigungsdatensatz gespeichert wird. Genehmigungen mit konfigurierten reviewable_actions werden zu einer auswähl- und bearbeitbaren Tabelle aufgeklappt.

Nach Aktivierung der E-Mail-Benachrichtigung erhält die Konto-E-Mail-Adresse des Genehmigers (bei nicht angegebenen approvers der Auslöser der Ausführung) eine E-Mail mit folgendem Inhalt: Workflow- und Schrittname, Ausführungs-ID, Anzahl der prüfbaren Aktionen, Timeout-Hinweis („automatische Ablehnung in ca. N Stunden“), der Hinweistext aus approval_message sowie ein Link zur Genehmigungsliste.

In Nachrichten wie E-Mail, Slack, Telegram, die keine benutzerdefinierten Request-Header erlauben, lässt sich zudem ein Ein-Klick-Entscheidungslink einbetten:

text
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_...

Der Link authentifiziert sich über einen API Key (APPROVAL_RESPOND-Scope), der Key liegt im Abfrageparameter api_key. Um ein versehentliches Auslösen durch Link-Vorschau-Bots (Slack-Aufklappen, Vorab-Abruf von E-Mail-Clients) zu verhindern, rendert das erste Öffnen nur eine Bestätigungsseite und führt keine Aktion aus; erst eine erneute Anfrage mit confirm=1 nach einem Klick auf die Bestätigungsschaltfläche entscheidet tatsächlich. Die Seite trägt die Header no-store und noindex, um Caching oder ein Replay durch Suchmaschinen zu vermeiden.

Kanal 3: API

Die offene v1-API stellt 5 Genehmigungs-Endpunkte bereit, die alle den Berechtigungs-Scope APPROVAL_RESPOND erfordern:

EndpointFunktion
GET /api/v1/approvalsGenehmigungsliste, filterbar nach status
GET /api/v1/approvals/{id}Genehmigungsdetails
GET /api/v1/approvals/execution/{executionId}Die mit einer bestimmten Ausführung verknüpften Genehmigungen abfragen
POST /api/v1/approvals/{id}/approveGenehmigen; der body kann comment und editedItems enthalten
POST /api/v1/approvals/{id}/rejectAblehnen; der body kann comment enthalten
bash
# 批准(可附备注)
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 reicht je Gruppenname die ausgewählte/bearbeitete Teilmenge ein; die Struktur entspricht dem bearbeitbaren Genehmigungsformular im nächsten Abschnitt. Wird es nicht übergeben, gilt dies als unveränderte Genehmigung aller Elemente.

Bearbeitbares Genehmigungsformular (reviewable_actions)

Manche Genehmigungen fallen auf der Granularität einzelner Empfehlungen an: Aus einer Reihe von Empfehlungen wird nur ein Teil ausgeführt, und bei einzelnen Zeilen sind Werte zu ändern. reviewable_actions gestaltet solche Genehmigungen als Tabelle — der Genehmiger wählt die auszuführenden Zeilen aus, bearbeitet direkt die mit editable: true gekennzeichneten Spalten (etwa das Gebot ändern) und klickt dann auf Genehmigen.

yaml
    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 — Interner Name der Gruppe, zugleich als Präfix der Ausgabedatei verwendet (nach der Genehmigung schreibt die Engine reviewed_<name>.json)
  • source_var — Verweist auf eine Variable, deren Wert die von einem vorgelagerten Schritt erzeugte Empfehlungsliste ist (Pfad einer JSON-Array-Datei)
  • output_var — Die nach der Genehmigung gesetzte Variable, deren Wert der Dateipfad der ausgewählten/bearbeiteten Teilmenge ist; liest der nachgelagerte Ausführungsschritt sie stattdessen, verarbeitet er nur die genehmigten Zeilen
  • key_field — Zeilen-Identitätsfeld, nach dem nach der Bearbeitung ausgerichtet wird; ohne Angabe wird nach dem Array-Index ausgerichtet
  • columns — Definition der Tabellenspalten; Spalten mit editable: true kann der Genehmiger ändern, type: number wird als Zahleneingabe gerendert
Serverseitige Validierung

Die eingereichte Teilmenge wird serverseitig validiert: Daten, die zu keiner Gruppe gehören, werden herausgefiltert; ist key_field definiert, muss sich jede Zeile in der Originalliste wiederfinden, und eine zusammengebastelte, nicht existierende Zeile lässt sich nicht umgehen; für Spalten mit editable: false ist der Originalwert maßgeblich, eine Änderung ist wirkungslos. Ist in einer Gruppe keine einzige Zeile ausgewählt, wird ein leeres Array geschrieben, und der nachgelagerte Schritt behandelt dies als „komplett leer, überspringen“.

Ablehnung und Timeout: keinerlei Änderung

Das zentrale Versprechen des Genehmigungs-Gates lautet: Vor der Genehmigung führt das System keine Aktion aus. Bei Ablehnung oder Timeout —

  • Der eigentliche Schritt läuft nicht, und die von ihm abhängigen nachgelagerten Schritte werden ebenfalls nicht ausgelöst
  • Per on_failure-Zweig lässt sich ein Benachrichtigungs- oder Archivierungsschritt für „Genehmigung abgelehnt“ anschließen
  • Ein Timeout wird vom System automatisch abgelehnt, mit system als Entscheider; jede Genehmigungsentscheidung (inkl. Entscheider, Zeit, Anmerkung) wird in das Audit-Log geschrieben
Wenn der Dienst neu startet

Genehmigungsdatensätze werden persistent gespeichert. Nach einem Serviceneustart werden ausstehende Genehmigungen unverändert wiederhergestellt, der Timeout-Zähler läuft nach der ursprünglichen Frist weiter, und der Genehmiger kann wie gewohnt entscheiden.

Verwandte Seiten