Saltar al contenido principal
DocumentoCorrerAprobación manual

Aprobación manual

Agregue un control manual_approval a cualquier paso: resolución por tres canales (dentro de la App, correo y API), valores editables y rechazo automático por tiempo de espera.

manual_approval codifica «esperar a que alguien confirme antes de continuar» como un modificador de paso: cuando la ejecución llega al paso que lo tiene configurado, se pausa y solo tras la aprobación se ejecuta el cuerpo del paso. Antes de aprobar, el sistema no ejecuta ese paso ni ninguna acción de sus pasos posteriores.

Configuración

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

Se puede acoplar a cualquier paso (agent, code, sub_workflow, etc.), y también se usa a menudo en un ligero paso de code que solo imprime un estado, como una pura «compuerta manual».

Parámetros

campoTipoPredeterminadoDescripción
enabledbooleanSi se habilita el control de aprobación (obligatorio)
approversstring[][]Indica los aprobadores (ID de usuario de la plataforma). Cuando no está vacío, solo los usuarios de la lista y los administradores pueden resolver — ni siquiera el iniciador de la ejecución, lo que satisface de forma natural la separación de funciones; cuando se deja vacío, pueden resolver el iniciador de la ejecución o los colaboradores con permiso de ejecución sobre ese workflow
timeoutlong3600Segundos de timeout. Si nadie resuelve a tiempo, se rechaza automáticamente y el estado se marca como TIMED_OUT
approval_messagestringnullLa explicación que se muestra al aprobador, aparece en la tarjeta de aprobación y en el correo de notificación
reviewable_actionsarray[]Grupos del formulario de aprobación editable; el aprobador puede marcar un subconjunto y editar valores antes de aprobar (ver más abajo)

Proceso de aprobación

  1. Cuando la ejecución llega al paso con manual_approval configurado, se pausa y el estado de la ejecución pasa a AWAITING_APPROVAL
  2. Crea el registro de aprobación e inicia el contador de timeout; la consola recibe por WebSocket una alerta approval_request en tiempo real, y el aprobador puede recibir además un correo de notificación
  3. El aprobador resuelve por uno de tres canales: la lista de aprobaciones dentro de la App, el enlace de un clic del mensaje, o la API
  4. Aprobar → el paso continúa; rechazar → el paso se trata como fallido (se puede conectar una rama de notificación con on_failure); timeout → rechazo automático

Canal uno: lista de aprobaciones dentro de la App

de la consolaAprobacionesLa página lista todas las aprobaciones visibles para usted, admite dos vistas (tarjeta/tabla) y filtro por estado. Al aprobar o rechazar puede añadir un comentario, que se guarda en el registro de aprobación. Las aprobaciones con reviewable_actions configurado se despliegan en una tabla marcable y editable.

Canal dos: notificación por correo y enlace de un clic

Con la notificación por correo habilitada, el aprobador (si no se han indicado approvers, el iniciador de la ejecución) recibe un correo en el correo de su cuenta, con: el nombre del workflow y del paso, el ID de ejecución, el número de acciones revisables, el aviso de timeout («rechazo automático dentro de unas N horas»), el texto explicativo de approval_message y el enlace a la lista de aprobaciones.

En mensajes como los de correo, Slack o Telegram, donde no se pueden personalizar los headers de la solicitud, también se puede incrustar un enlace de resolución de un clic:

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

El enlace se autentica con una API Key (scope APPROVAL_RESPOND), y la Key va en el parámetro de query api_key. Para evitar que los bots de vista previa de enlaces (la expansión de Slack, la precaptura de los clientes de correo) lo activen por error, la primera vez que se abre solo se renderiza una página de confirmación y no ejecuta ninguna acción; solo cuando se pulsa el botón de confirmación y se hace una segunda solicitud con confirm=1 se resuelve realmente. La página lleva los headers no-store y noindex, para evitar el cacheo o la reejecución por parte de los buscadores.

Canal tres: API

La API abierta v1 ofrece 5 endpoints de aprobación, todos requieren el scope de permiso APPROVAL_RESPOND:

EndpointFunción
GET /api/v1/approvalsLista de aprobaciones, se puede filtrar por status
GET /api/v1/approvals/{id}Detalle de aprobación
GET /api/v1/approvals/execution/{executionId}Consultar las aprobaciones asociadas a una ejecución
POST /api/v1/approvals/{id}/approveAprobar; el body puede llevar comment y editedItems
POST /api/v1/approvals/{id}/rejectRechazar; el body puede llevar comment
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 envía, por nombre de grupo, el subconjunto marcado/editado, con una estructura que corresponde al formulario de aprobación editable de la siguiente sección; si no se envía, se considera una aprobación completa tal cual.

Formulario de aprobación editable (reviewable_actions)

Algunas aprobaciones tienen su grano en una recomendación individual: de un lote de recomendaciones solo se ejecuta una parte y en filas concretas hay que cambiar valores. reviewable_actions convierte este tipo de aprobación en una tabla — el aprobador marca las filas que se van a ejecutar, edita directamente las columnas marcadas con editable: true (por ejemplo cambiar la puja) y luego pulsa aprobar.

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 — Nombre interno del grupo, que también se usa como prefijo del archivo de salida (tras aprobar, el motor escribe reviewed_<name>.json)
  • source_var — Apunta a una variable cuyo valor es la lista de recomendaciones generada por el paso upstream (la ruta de un archivo de array JSON)
  • output_var — Variable que se establece tras aprobar; su valor es la ruta del archivo del subconjunto marcado/editado; los pasos de ejecución posteriores la leen y así solo procesan las filas aprobadas
  • key_field — Campo de identidad de fila; tras editar, se alinea por él; por defecto se alinea por el índice del array
  • columns — Definición de columnas de la tabla; las columnas con editable: true las puede cambiar el aprobador, type: number se renderiza como una entrada numérica
Validación en el servidor

El subconjunto enviado se valida en el servidor: los datos que no pertenecen a ningún grupo se filtran; cuando se ha definido key_field, cada fila debe poder encontrar su correspondiente en la lista original, y fabricar una fila inexistente no puede saltarse la validación; las columnas con editable: false prevalecen con su valor original, y cambiarlas no tiene efecto. Cuando en un grupo no se ha marcado ninguna fila, se escribe un array vacío y el paso posterior lo trata como «todo vacío, se salta».

Rechazo y timeout: cero cambios

La promesa central del control de aprobación es: antes de aprobar, el sistema no ejecuta ninguna acción. En caso de rechazo o timeout —

  • El cuerpo del paso no se ejecuta, y los pasos posteriores que dependen de él tampoco se disparan
  • Se puede conectar con on_failure una rama de notificación o de archivado de «aprobación rechazada»
  • El timeout lo rechaza el sistema automáticamente y el decisor se registra como system; cada decisión de aprobación (incluidos decisor, hora y comentario) se escribe en el registro de auditoría
Cuando se reinicia el servicio

El registro de aprobación se almacena de forma persistente. Tras reiniciar el servicio, las aprobaciones pendientes se restauran tal cual, el contador de timeout continúa según el plazo límite original, y el aprobador resuelve con normalidad.

Páginas relacionadas