Contábil: Regras de Análise
Endpoints da WebApiAlcance para regras de análise (regra_analise) aplicadas sobre os balancetes importados do Domínio. Cada regra tem um tipo fixo que determina o formato esperado de params (conta virada, saldo negativo, soma de contas, limite de valor, fórmula, ou comparação com guias fiscais). Uma regra pode ser global (id_cliente nulo, aplicada a todos os clientes) ou de um cliente específico - na avaliação, as regras de cliente sempre se somam às globais.
Todos os endpoints exigem autenticação. Veja Autenticação para o fluxo de API Key. O Swagger oficial está em api.contabilidadealcance.com.br/docs.
Base path
/api/v1/regra-analiseEscopos necessários
regra_analise:read- listagem e busca por IDregra_analise:write- criação, teste (dry-run), atualização e exclusão
O escopo é derivado do prefixo público da rota: /regra-analise vira o recurso regra_analise (hífen → underscore), e o método HTTP define a ação (read para GET, write para POST/PATCH/DELETE).
Envelope de resposta
{
"status": "success",
"message": "Mensagem em PT-BR",
"data": {}
}DELETE /regra-analise/{regra_id} responde 204 No Content, sem corpo.
Dois formatos de erro
Erros de regra de negócio (registro não encontrado, params/formula incompatíveis com o tipo da regra já persistida) respondem { "message": "<mensagem>" } no status HTTP correspondente. Já a validação do corpo de POST /regra-analise/ e de POST /regra-analise/testar (shape de params por tipo, sintaxe da formula) roda dentro do schema Pydantic e, quando falha, segue o formato padrão do FastAPI: { "detail": [...] }, sempre 422.
Endpoints
POST /regra-analise/
Cria uma regra global (id_cliente omitido ou null) ou de um cliente (id_cliente informado). O formato de params é validado de acordo com tipo - ver Parâmetros por tipo. Para tipo="formula", a sintaxe da fórmula também é validada (ast.parse) já na criação.
Parâmetros
Sem parâmetros de rota ou query - o corpo é um RegraAnaliseCreate.
Request
{
"id_cliente": null,
"tipo": "soma_total",
"nome": "Soma do Ativo Circulante confere com o total do grupo 1",
"params": {
"contas": ["1.1.01", "1.1.02", "1.1.03"],
"conta_total": "1.1",
"tolerancia_cents": 100
},
"gravidade": "erro",
"ativo": true
}Response 201 Created
{
"status": "success",
"message": "Regra criada com sucesso",
"data": {
"id": 58,
"id_usuario_created": 7,
"id_cliente": null,
"tipo": "soma_total",
"nome": "Soma do Ativo Circulante confere com o total do grupo 1",
"params": {
"contas": ["1.1.01", "1.1.02", "1.1.03"],
"conta_total": "1.1",
"tolerancia_cents": 100
},
"formula": null,
"gravidade": "erro",
"ativo": true,
"data_hora_criacao": "2026-08-10T09:00:00-03:00"
}
}Escopo: regra_analise:write
GET /regra-analise/
Lista regras globais + do cliente. Sem id_cliente, retorna apenas as regras globais; com id_cliente, retorna as globais e as daquele cliente.
Parâmetros de query
| Parâmetro | Tipo | Obrigatório | Observações |
|---|---|---|---|
id_cliente | int | não | > 0. Quando omitido, lista só as regras globais. |
Request
GET /api/v1/regra-analise/?id_cliente=1234Response 200 OK
{
"status": "success",
"message": "Regras recuperadas com sucesso",
"data": [
{
"id": 58,
"id_usuario_created": 7,
"id_cliente": null,
"tipo": "soma_total",
"nome": "Soma do Ativo Circulante confere com o total do grupo 1",
"params": {
"contas": ["1.1.01", "1.1.02", "1.1.03"],
"conta_total": "1.1",
"tolerancia_cents": 100
},
"formula": null,
"gravidade": "erro",
"ativo": true,
"data_hora_criacao": "2026-08-10T09:00:00-03:00"
}
]
}Lista vazia retorna 200 OK com data: [] e a mensagem "Nenhuma regra encontrada.".
Escopo: regra_analise:read
POST /regra-analise/testar
Executa um dry-run: avalia uma regra ad-hoc (não precisa existir no banco) contra os dados de um balancete já importado, sem persistir nada. Útil para validar uma regra antes de salvá-la.
Parâmetros
Sem parâmetros de rota ou query - o corpo é um TestarRegraRequest com regra (RegraAnaliseCreate) e id_balancete. Quando regra usa um tipo que lê guias fiscais (guia_vs_conta, guia_presente, guia_consistencia ou formula com guia(...)), as guias do mesmo cliente e período do balancete entram na avaliação.
Request
{
"id_balancete": 771,
"regra": {
"id_cliente": 1234,
"tipo": "guia_vs_conta",
"nome": "DAS bate com a conta de tributos a pagar",
"params": {
"tipo_guia": "DAS",
"componente": "principal",
"operador": "=",
"alvo": "conta",
"codigos": ["2.1.05.001"],
"tolerancia_cents": 100
},
"gravidade": "alerta"
}
}Response 200 OK
{
"status": "success",
"message": "Teste executado",
"data": {
"id_regra": 0,
"nome": "DAS bate com a conta de tributos a pagar",
"tipo": "guia_vs_conta",
"gravidade": "alerta",
"origem": "cliente",
"status": "passou",
"evidencia": "DAS/principal 1.245,00 = conta 1.245,00 (Δ 0,00)",
"ocorrencias": []
}
}id_regra sempre vem 0 (regra rascunho, nunca persistida). origem é "cliente" quando id_cliente foi informado no corpo, senão "global". id_balancete inexistente retorna 404 com { "message": "Balancete nao encontrado." }.
Escopo: regra_analise:write
GET /regra-analise/{regra_id}
Busca uma regra pelo ID.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
regra_id | int | rota | sim | ID da regra. |
Response 200 OK
{
"status": "success",
"message": "Regra encontrada",
"data": {
"id": 58,
"id_usuario_created": 7,
"id_cliente": null,
"tipo": "soma_total",
"nome": "Soma do Ativo Circulante confere com o total do grupo 1",
"params": {
"contas": ["1.1.01", "1.1.02", "1.1.03"],
"conta_total": "1.1",
"tolerancia_cents": 100
},
"formula": null,
"gravidade": "erro",
"ativo": true,
"data_hora_criacao": "2026-08-10T09:00:00-03:00"
}
}ID inexistente retorna 404 com { "message": "Regra de analise nao encontrada." }.
Escopo: regra_analise:read
PATCH /regra-analise/{regra_id}
Atualiza campos mutáveis. tipo e id_cliente são imutáveis - ausentes do schema de atualização.
Parâmetros
regra_id na rota; corpo em RegraAnaliseUpdate.
params/formula revalidados contra o tipo já persistido
Se params ou formula forem enviados, são revalidados na borda contra o tipo já gravado da regra (a mesma checagem da criação). Enviar um params incompatível com o tipo responde 422 com { "message": "<motivo>" }, e não grava a alteração.
Request
{
"params": {
"contas": ["1.1.01", "1.1.02", "1.1.03", "1.1.04"],
"conta_total": "1.1",
"tolerancia_cents": 200
},
"ativo": false
}Response 200 OK
{
"status": "success",
"message": "Regra atualizada",
"data": {
"id": 58,
"id_usuario_created": 7,
"id_cliente": null,
"tipo": "soma_total",
"nome": "Soma do Ativo Circulante confere com o total do grupo 1",
"params": {
"contas": ["1.1.01", "1.1.02", "1.1.03", "1.1.04"],
"conta_total": "1.1",
"tolerancia_cents": 200
},
"formula": null,
"gravidade": "erro",
"ativo": false,
"data_hora_criacao": "2026-08-10T09:00:00-03:00"
}
}ID inexistente retorna 404 com { "message": "Regra de analise nao encontrada." }.
Escopo: regra_analise:write
DELETE /regra-analise/{regra_id}
Remove uma regra.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
regra_id | int | rota | sim | ID da regra. |
Response 204 No Content
Sem corpo de resposta. ID inexistente retorna 404 com { "message": "Regra de analise nao encontrada." }.
Escopo: regra_analise:write
Parâmetros por tipo
O campo params (dict) tem um formato diferente para cada tipo, validado na criação e (quando enviado) na atualização:
tipo | params obrigatórios | params opcionais | O que avalia |
|---|---|---|---|
conta_virada | alvo ("grupo" | "conta"); grupo (1-4, se alvo="grupo") ou codigos (lista de classificações, se alvo="conta") | natureza_esperada ("D" | "C") | Linhas cuja natureza do saldo diverge da esperada pelo grupo contábil (1/3 = devedora, 2/4 = credora), ou da natureza_esperada informada. |
saldo_negativo | alvo ("grupo" | "conta") + grupo/codigos conforme alvo | - | Linhas com saldo bruto negativo (sinal cru: +devedor / -credor) dentro do escopo. Escopar por alvo é necessário - contas credoras (grupos 2 e 4) são negativas por construção. |
soma_total | contas (lista de classificações), conta_total (classificação) | tolerancia_cents (default 0) | Se a soma das contas bate com o saldo de conta_total. |
limite_valor | limite_cents (int) | base ("saldo_atual" default, "debito", "credito"), alvo/grupo/codigos | Linhas cujo valor da base ultrapassa limite_cents. |
formula | formula no nível da regra (mini-linguagem, não em params) | - | Expressão aritmética/comparação - ver Fórmula. |
guia_vs_conta | tipo_guia, componente, alvo + grupo/codigos conforme alvo | operador ("=" default, "<=", ">="), tolerancia_cents | Soma de um componente de guia fiscal do tipo_guia no período vs. saldo das contas do escopo. |
guia_presente | tipo_guia | - | Passa se existir ao menos uma guia daquele tipo_guia no período do balancete/cliente. |
guia_consistencia | tipo_guia | tolerancia_cents | Se a soma dos componentes de cada guia do tipo_guia bate com o valor_total dela. |
Fórmula
Para tipo="formula", o campo formula (string, até 2000 caracteres) aceita uma mini-linguagem restrita, validada por allow-list de nós (sem execução de código arbitrário):
- Aritmética:
+,-,*,/e parênteses. - Comparação (resultado booleano):
==,!=,<,<=,>,>=. conta("codigo")- saldo atual (em reais) da classificação informada;0.0se ausente no balancete.guia("tipo", "componente")- soma (em reais) do componente daquela guia fiscal no período;0.0se ausente.
Exemplo: conta("1.1.01") + conta("1.1.02") >= guia("DAS", "principal"). Sintaxe fora do permitido responde 422 com { "message": "Fórmula com sintaxe inválida." } (na criação) ou é rejeitada pelo schema ({ "detail": [...] }, quando a validação ocorre na borda do corpo).
Schemas
RegraAnaliseCreate
Corpo de POST /regra-analise/ e do campo regra em POST /regra-analise/testar.
| Campo | Tipo | Obrigatório | Observações |
|---|---|---|---|
id_cliente | int | null | não | null = regra global. Default null. |
tipo | "conta_virada" | "saldo_negativo" | "soma_total" | "limite_valor" | "formula" | "guia_vs_conta" | "guia_presente" | "guia_consistencia" | sim | Define o formato de params - ver tabela acima. |
nome | str (1-200) | sim | Nome descritivo da regra. |
params | dict | não | Formato depende de tipo. Default {}. |
formula | str (≤ 2000) | condicional | Obrigatória quando tipo="formula". |
gravidade | "erro" | "alerta" | não | Default "erro". |
ativo | bool | não | Default true. |
RegraAnaliseUpdate
Corpo de PATCH /regra-analise/{regra_id}. Todos os campos são opcionais; apenas os enviados são atualizados. tipo, id_cliente, id e data_hora_criacao não fazem parte deste schema.
| Campo | Tipo | Observações |
|---|---|---|
nome | str (1-200) | Novo nome. |
params | dict | Revalidado contra o tipo já persistido (ver Callout acima). |
formula | str (≤ 2000) | Revalidada contra o tipo já persistido. |
gravidade | "erro" | "alerta" | - |
ativo | bool | Ativa/inativa a regra. |
RegraAnaliseRead
data de POST, GET /{regra_id}, GET / (itens da lista) e PATCH.
| Campo | Tipo | Notas |
|---|---|---|
id | int | ID da regra. |
id_usuario_created | int | Usuário que criou a regra. |
id_cliente | int | null | null = regra global. |
tipo | str | Ver valores em RegraAnaliseCreate. |
nome | str | Nome descritivo. |
params | dict | Formato depende de tipo. |
formula | str | null | Preenchido só quando tipo="formula". |
gravidade | str | erro | alerta. |
ativo | bool | Se a regra é avaliada. |
data_hora_criacao | datetime | Localizado em America/Sao_Paulo. |
ValidacaoResultado
data de POST /regra-analise/testar (resultado único, não uma lista).
| Campo | Tipo | Notas |
|---|---|---|
id_regra | int | Sempre 0 para regra ad-hoc (não persistida). |
nome | str | - |
tipo | str | - |
gravidade | str | erro | alerta. |
origem | "global" | "cliente" | "cliente" quando id_cliente veio preenchido no corpo. |
status | "passou" | "falhou" | Resultado da avaliação. |
evidencia | str | Texto legível com os valores comparados. |
ocorrencias | List[Ocorrencia] | Vazio quando status="passou". |
Ocorrencia
Item de ocorrencias[] em ValidacaoResultado.
| Campo | Tipo | Notas |
|---|---|---|
classificacao | str | Código da conta envolvida (ou marcador como "(guia)"). |
descricao | str | Descrição da conta ou do componente. |
valor_cents | int | Valor/diferença envolvida, em centavos. |
detalhe | str | Explicação legível da ocorrência. |
Notas
- Ordem de rotas (FastAPI):
POST /regra-analise/testar(path estático) é declarada antes deGET/PATCH/DELETE /regra-analise/{regra_id}(path dinâmico), para o match ocorrer na ordem correta. - Regras globais (
id_cliente=null) valem para todos os clientes; na avaliação de um cliente, elas sempre se somam às regras específicas dele. POST /regra-analise/testarnão persiste nada - nem a regra testada, nem o resultado.DELETEretorna204 No Content, sem corpo.