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