Fórmulas e validações
Campos computed, a AST de expressões, validações entre campos e a prévia reativa nos formulários — uma única declaração, autoridade no backend.
Campos calculados
computed é permitido em campos number, currency e currencyConverted.
{
"kind": "currency",
"computed": {
"expression": { "op": "multiply", "args": [{ "field": "quantidade" }, { "field": "valorUnitario" }] },
"precision": 2,
"nullAsZero": true
}
}
| Propriedade | Padrão | Descrição |
|---|---|---|
expression |
— | Expressão obrigatória. |
precision |
2 |
Casas decimais, de 0 a 8. |
nullAsZero |
true |
Trata campos ausentes ou vazios como zero. |
Campos calculados:
- são automaticamente
readonly; - são recalculados no backend em criação, edição, patch e importação;
- são calculados em ordem de dependência e não podem formar ciclos;
- aparecem na metadata com
readonly: truee a declaraçãocomputed.
Expressões
Uma expressão declara exatamente um destes nós:
{ "value": 100 }
{ "field": "valorUnitario" }
{ "op": "multiply", "args": [{ "field": "quantidade" }, { "field": "valorUnitario" }] }
Operadores
| Grupo | Operadores |
|---|---|
| Aritméticos | add, subtract, multiply, divide, min, max, abs, negate, coalesce |
| Comparação | eq, neq, gt, gte, lt, lte |
| Lógicos e presença | and, or, not, present, in |
| Somente em processos | if, concat, formatCurrency |
Divisão por zero e valores não numéricos geram DomainRuleError com status 422.
Validações entre campos
As validações rodam depois que o Core consolidou o registro e recalculou todos os dependentes.
{
"name": "valor-pago-valido",
"code": "PAGAMENTO_ACIMA_CONTRATADO",
"field": "valorPago",
"message": "O valor pago não pode superar o valor contratado.",
"when": { "op": "present", "args": [{ "field": "valorPago" }] },
"assert": { "op": "lte", "args": [{ "field": "valorPago" }, { "field": "valorContratado" }] }
}
| Propriedade | Obrigatória | Descrição |
|---|---|---|
name |
sim | Identificador único dentro da model. |
message |
sim | Mensagem apresentada ao usuário. |
assert |
sim | Expressão que deve resultar em verdadeiro. |
when |
não | Condição para executar a regra. |
field |
não | Campo associado ao erro. |
code |
não | Código em maiúsculas para tratamento programático. |
Falhas geram DomainRuleError com statusCode: 422, code, field, rule e detalhes compatíveis com o envelope de erros.
Prévia reativa no frontend
Campos computed são recalculados imediatamente nos formulários padrão do oon-core-front — sem repetir a fórmula no frontend.
- O backend carrega e valida
central.domain.json. - A metadata expõe
readonlyecomputed. - O frontend interpreta a mesma AST fechada para exibir a prévia.
- Calculados e readonly são removidos do payload enviado.
- O backend recalcula, valida e persiste o valor autoritativo.
- O formulário passa a exibir o registro devolvido pelo servidor.
Formulários atendidos: formulário dinâmico de coleções, formulário principal da modal com abas, criação e edição, e formulários com apresentação local desde que a model venha da metadata.
Usando o avaliador no seu código
O frontend exporta o mesmo avaliador para páginas próprias:
import { evaluateDomainExpression, applyReactiveFormulas, buildDomainMutationPayload } from "@oondemand/oon-core-front";
const total = evaluateDomainExpression(
{ op: "multiply", args: [{ field: "quantidade" }, { field: "valorUnitario" }] },
{ quantidade: 2, valorUnitario: 50 },
); // 100
Quando usar código local
Não crie funções de cálculo em componentes para campos já descritos por computed. Use código local (no backend) apenas quando a regra:
- não puder ser representada pela AST;
- depender de consulta externa;
- exigir agregação de registros relacionados — prefira os bindings de processo;
- ainda não possuir contrato declarativo.