Validations e triggers
defineValidation valida o estado consolidado antes de persistir; defineTrigger registra efeitos antes e depois da mutação.
defineValidation
Use validations para regras de negócio síncronas com mensagens claras.
const { defineValidation, GenericError } = require("@oondemand/oon-core-back");
defineValidation("Pedido", async (dados, contexto) => {
if (dados.status === "Aprovado" && !(dados.valor > 0)) {
throw new GenericError("Pedidos aprovados precisam de valor.", {
statusCode: 422, code: "PEDIDO_SEM_VALOR", details: { field: "valor" },
});
}
if (contexto.op === "update" && contexto.changedFields?.includes("fornecedor") && contexto.current.status !== "Rascunho") {
throw new GenericError("O fornecedor só pode mudar em rascunho.", { statusCode: 422, code: "FORNECEDOR_BLOQUEADO" });
}
});
O contexto
| Propriedade | Conteúdo |
|---|---|
op |
"create" ou "update" |
method |
"post", "put" ou "patch" |
id |
Identificador em updates |
current |
Registro antes da alteração |
requestedChanges |
O que o cliente enviou |
changes |
Somente os campos enviados e permitidos |
consolidated |
Registro completo usado em dados |
changedFields |
Campos cujo valor final realmente mudou (inclui derivados) |
Em inclusões, a validation recebe os dados enviados. Em PUT/PATCH, o Core carrega o registro atual e entrega o registro consolidado — por isso formulários em abas e grids podem enviar só os campos alterados sem perder referências obrigatórias.
A validation roda depois das fórmulas, das validações declarativas e das regras de processo.
defineTrigger
const { defineTrigger } = require("@oondemand/oon-core-back");
defineTrigger("Pedido", {
before: [async (doc, { op }) => {
if (op === "create" && !doc.numero) doc.numero = await gerarNumero();
}],
after: [async (doc) => {
await registrarHistorico(doc);
}],
});
Triggers são executados nos hooks save da model.
Regras
- Trigger não deve esconder regra crítica sem validação.
- Evite efeitos irreversíveis sem log.
- Integração externa deve passar por um serviço do App com timeout, idempotência e status rastreável.
- Falhas de integração devem gerar estado visível, não quebrar silenciosamente o processo.
- Não trate hooks como entrega exatamente-uma-vez de efeitos externos.
Ordem completa de uma mutação
requisição → auth → RBAC → escopo
→ readonly/computed protegidos → consolidação → fórmulas
→ validações declarativas → processo (transições, locks, bindings, invariantes)
→ defineValidation → trigger before → persistência → trigger after
→ recálculos dependentes → auditoria