Atualizar filtro de eventos
Atualize o nome, a descrição ou a definição completa de um filtro de eventos existente.
PATCH /api/event-criterias/:id
Atualiza um filtro de eventos existente. Os três campos do corpo são todos opcionais: você pode alterar somente o nome, somente a descrição, somente a definição, ou qualquer combinação.
Auth: Obrigatória — permissão event-criteria:update
Parâmetros de rota
| Parâmetro | Tipo | Descrição |
|---|---|---|
id | UUID | ID do filtro de eventos. |
Corpo da requisição
Nível raiz (UpdateEventCriteriaDto):
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
name | string | Não | Novo nome. Se enviado, não pode ser vazio nem null. |
description | string | null | Não | Nova descrição. Enviar null a limpa. |
queryBlocks | QueryBlockDto[] | Não | Nova definição completa. Mínimo 1 elemento se enviado. Substitui os blocos existentes. |
A estrutura de cada bloco está em Definição.
Semântica do PATCH
O PATCH é parcial entre campos, mas total dentro de queryBlocks. É a
distinção que decide se uma atualização perde blocos:
| O que é enviado | O que acontece |
|---|---|
name e/ou description | Somente esses campos são atualizados. Os blocos de consulta permanecem intactos. |
queryBlocks | Todos os blocos do filtro são apagados e são criados os enviados. Não há merge por order nem por id. |
Nada (corpo {}) | O filtro não muda, exceto updatedBy e updatedAt. |
queryBlocks substitui a definição inteira. Enviar um único bloco em um filtro que
tinha três deixa o filtro com um bloco; os outros dois são apagados. Para modificar um
bloco você deve enviar a lista completa, incluindo os que não mudam.
Os blocos enviados são persistidos como blocos novos: seus id não são os que o
filtro tinha antes, mesmo que o order e o conteúdo coincidam. Um id de bloco não é um
identificador estável entre atualizações da definição.
Em toda atualização, updatedBy passa a ser o usuário que faz a requisição e
updatedAt é atualizado.
Exemplo
Alterar o nome e substituir a definição por uma que adiciona um filtro de registro sobre
items.
curl -X PATCH https://api.reten.ai/api/event-criterias/4b8e0f15-2c76-4a03-9d58-7e1f2a3b4c5d \
-H "Authorization: Bearer <token>" \
-H "x-tenant-id: <tenant-id>" \
-H "x-project-id: <project-id>" \
-H "Content-Type: application/json" \
-d '{
"name": "Ventas con ítems no-devolución",
"queryBlocks": [
{
"order": 0,
"from": { "table": "event_transactions", "joins": [] },
"select": {
"distinct": true,
"items": [
{ "kind": "column", "column": { "table": "event_transactions", "column": "event_id" } }
]
},
"where": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"column": { "table": "event_transactions", "column": "status" },
"comparisonOperator": "EQUALS",
"value": "Facturada"
},
{
"kind": "recordPredicate",
"column": { "table": "event_transactions", "column": "items" },
"subWhere": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"field": "category",
"comparisonOperator": "NOT_IN",
"value": ["devolucion"]
}
]
}
}
]
}
}
]
}'import axios from 'axios';
const id = '4b8e0f15-2c76-4a03-9d58-7e1f2a3b4c5d';
const body = {
name: 'Ventas con ítems no-devolución',
queryBlocks: [
{
order: 0,
from: { table: 'event_transactions', joins: [] },
select: {
distinct: true,
items: [
{ kind: 'column', column: { table: 'event_transactions', column: 'event_id' } },
],
},
where: {
kind: 'group',
logicalOperator: 'AND',
children: [
{
kind: 'predicate',
column: { table: 'event_transactions', column: 'status' },
comparisonOperator: 'EQUALS',
value: 'Facturada',
},
{
kind: 'recordPredicate',
column: { table: 'event_transactions', column: 'items' },
subWhere: {
kind: 'group',
logicalOperator: 'AND',
children: [
{
kind: 'predicate',
field: 'category',
comparisonOperator: 'NOT_IN',
value: ['devolucion'],
},
],
},
},
],
},
},
],
};
const response = await axios.patch(
`https://api.reten.ai/api/event-criterias/${id}`,
body,
{ headers: { Authorization: 'Bearer <token>', 'x-tenant-id': '<tenant-id>', 'x-project-id': '<project-id>' } },
);
const updated = response.data;Resposta 200 OK
Retorna o filtro atualizado como IEventCriteriaDetail — a mesma forma que
GET /event-criterias/:id, com os blocos já
persistidos e seus id novos.
{
"id": "4b8e0f15-2c76-4a03-9d58-7e1f2a3b4c5d",
"projectId": "3f6c2b1a-8d4e-4f7a-9b2c-5e1d0a7f6c34",
"name": "Ventas con ítems no-devolución",
"description": "Ventas facturadas con al menos una línea que no es devolución",
"isActive": true,
"ownerId": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
"updatedBy": "0f0e0d0c-0b0a-4090-8070-605040302010",
"createdAt": "2026-07-12T11:05:19.220Z",
"updatedAt": "2026-07-18T16:41:02.907Z",
"queryBlocks": [
{
"id": "c8d9e0f1-2a3b-4c5d-8e6f-7a8b9c0d1e2f",
"order": 0,
"setOperator": null,
"from": { "table": "event_transactions", "joins": [] },
"select": {
"distinct": true,
"items": [
{ "kind": "column", "column": { "table": "event_transactions", "column": "event_id" } }
]
},
"timeWindow": null,
"where": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"column": { "table": "event_transactions", "column": "status" },
"comparisonOperator": "EQUALS",
"value": "Facturada"
},
{
"kind": "recordPredicate",
"column": { "table": "event_transactions", "column": "items" },
"subWhere": {
"kind": "group",
"logicalOperator": "AND",
"children": [
{
"kind": "predicate",
"field": "category",
"comparisonOperator": "NOT_IN",
"value": ["devolucion"]
}
]
}
}
]
},
"groupBy": null,
"having": null
}
]
}Regras de validação
A definição é validada somente se o corpo trouxer queryBlocks, e antes de tocar em
qualquer coisa: uma substituição que não compila para SQL não apaga os blocos que já
existiam. Uma atualização que só altera name ou description não revalida a definição salva.
O catálogo completo de regras e suas mensagens exatas está em Definição → Regras de validação.
Respostas de erro
| Status | Descrição |
|---|---|
400 | O id não é um UUID válido, o DTO é inválido (tipo incorreto, enum fora do intervalo, queryBlocks vazio, propriedade desconhecida) ou uma regra de negócio violada. |
401 | Authorization: Bearer ausente ou inválido. |
403 | O usuário não tem a permissão event-criteria:update, ou o x-tenant-id não está autorizado. |
404 | Não existe um filtro de eventos com esse id no tenant (Event criteria not found). |