Tarefas Externas
Opera o ciclo de vida de uma EXTERNAL_TASK (ver Tarefas Externas
para o conceito) de fora do processo Java que hospeda o motor — o caso típico de um worker em outra linguagem,
uma tela de tarefas humanas, ou um sistema externo que sinaliza conclusão via webhook.
| Operação | Endpoint |
|---|---|
Reivindicar (claim) | PUT /external-tasks/{id}/claim/{assignee} |
Liberar (unclaim) | PUT /external-tasks/{id}/unclaim |
| Completar | POST /external-tasks/{id}/complete |
| Buscar por id | GET /external-tasks/{id} |
| Formulário da tarefa | GET /external-tasks/{id}/form |
| Listar | GET /external-tasks |
| Contar | GET /external-tasks/count |
Comandos (claim/unclaim/complete) requerem KikwiflowEngine; consultas ({id}/form/listar/contar)
requerem QueryRepository.
Reivindicar
PUT /external-tasks/{id}/claim/{assignee}
Marca assignee como responsável pela tarefa, sinalizando a outros workers/operadores que ela já está sendo
tratada. Resposta 204 No Content. claim não é pré-requisito para complete — é só uma convenção para
evitar processamento duplicado do mesmo item; nada impede completar uma tarefa nunca reivindicada.
Liberar
PUT /external-tasks/{id}/unclaim
Desfaz o claim atual. Resposta 204 No Content.
Completar
POST /external-tasks/{id}/complete
Content-Type: application/json
{ "variables": { "resultadoAnalise": { "name": "resultadoAnalise", "value": "APROVADO" } } }
Resposta 202 Accepted com a ProcessInstance atualizada — o fluxo avança de forma síncrona dentro desta
mesma chamada até o próximo ponto de espera ou o fim do processo (mesmo modelo de
completeExternalTask via KikwiflowEngine).
Se a tarefa declara um contrato de dados (inputs/outputs), ele
é validado contra o estado da instância já mesclado com as variables enviadas — um campo obrigatório
preenchido numa etapa anterior não precisa ser reenviado. Se falhar, a resposta é 422
(VARIABLE_VALIDATION_FAILED, com um erro por campo — ver
Convenções, Autenticação e Erros),
nada é gravado e a tarefa continua pendente.
:::info Dois campos do corpo não têm efeito hoje
CompleteExternalTaskRequest também aceita tenant e targetFlowNodeId, mas o controller REST não os repassa
ao motor — só variables chega em KikwiflowEngine.completeExternalTask. Envie-os se quiser (não geram erro),
mas não espere que mudem o comportamento da chamada; se sua integração precisa validar tenant ou redirecionar
para um nó específico ao completar, a camada REST não oferece isso.
:::
Buscar por id
GET /external-tasks/{id}
200 OK com a ExternalTask completa, ou 404 (NOT_FOUND).
Formulário da tarefa
GET /external-tasks/{id}/form
Descreve os campos para concluir a tarefa — um FormDescriptor montado a partir dos inputs do nó e do
catálogo de variáveis do processo, com value pré-preenchido pelas variáveis atuais da instância (ver
Catálogo de Variáveis e Formulários
para o formato completo):
{
"processDefinitionId": "fc451f6f-a944-4dbb-b2ba-b5fb6433f40a",
"processDefinitionKey": "abertura-de-conta",
"nodeId": "APROVAR_ABERTURA",
"nodeName": "Aprovar Abertura",
"fields": [
{ "key": "decisao", "label": "Decisão", "format": "SINGLE_SELECT", "required": true,
"options": [ { "value": "APROVADA", "label": "Aprovar" }, { "value": "RECUSADA", "label": "Recusar" } ],
"value": null, "...": "..." }
]
}
Os campos vêm na ordem dos inputs; uma tarefa sem inputs devolve fields vazio. 404 (NOT_FOUND)
se a tarefa, sua definição ou sua instância não existirem.
:::warning Qualquer chamador vê o formulário e os valores
Como as demais consultas deste recurso, /form não recebe a identidade de quem chama: não filtra por tenant e
devolve os valores atuais das variáveis da instância, sem passar pelo VariableSecurityPolicyManager. Não
exponha este endpoint diretamente ao navegador do usuário final; faça o frontend passar por um backend seu que
autentique o usuário e decida o que ele pode ver (ver
Quem pode assumir e concluir uma tarefa externa).
:::
Listar e contar
GET /external-tasks?process-definition-id=&tenant-id=&assignee=&process-instance-id=&process-instance-id-in=&task-definition-id=&tenant-ids=
GET /external-tasks/count?process-definition-id=&tenant-id=&assignee=&process-instance-id=&process-instance-id-in=&task-definition-id=&tenant-ids=
Os dois endpoints aceitam os mesmos sete parâmetros na assinatura, mas implementam subconjuntos diferentes
— um parâmetro fora da lista suportada para aquele endpoint lança NotImplementedException → 501, em vez de
ser ignorado:
| Parâmetro | GET /external-tasks (listar) | GET /external-tasks/count |
|---|---|---|
process-definition-id | ✅ suportado | ✅ suportado |
tenant-id | ✅ suportado | ✅ suportado |
assignee | ✅ suportado | ✅ suportado |
process-instance-id | ✅ suportado | ❌ 501 |
process-instance-id-in | ❌ 501 | ❌ 501 |
task-definition-id | ❌ 501 | ❌ 501 |
tenant-ids | ❌ 501 | ❌ 501 |
Note a assimetria em process-instance-id: funciona em GET /external-tasks?process-instance-id=... mas
lança 501 em GET /external-tasks/count?process-instance-id=.... Todos os filtros suportados são combináveis
entre si (AND); nenhum é obrigatório — sem nenhum parâmetro, ambos os endpoints operam sobre todas as tarefas
externas.
Respostas: 200 OK com ExternalTask[] (não paginado) para listar; 200 OK com { "total": N } para
contar.