Desenvolvido para empresas

Sistema de controladoria financeira

ÁreaIA sobre os dados
O que fazGasto fora do padrão só aparecia no fechamento. Agora o sistema confere as contas todo dia e avisa.
FunçõesAviso diário de desvio · Comparação com orçado · Previsão de caixa
HabilidadesLevantamento de processo · Design de painel · Integração com ERP · Regras de alerta
Como foi construídoLevantei a rotina de fechamento com a controladoria e as fontes de dado. Desenhei o painel de alertas e o fluxo de aprofundamento. Construí primeiro o cálculo, conferido contra um gabarito feito à mão, depois a redação, e implantei.

O que o sistema cobre.

Sistema para a controladoria da empresa. Reúne lançamentos do ERP, extrato bancário e planilha de orçamento num histórico único e confere contas e centros de custo todo dia, com o mês em curso. Compara o gasto com o histórico e com o orçado, avisa o desvio em português, detalha por fornecedor e responsável e projeta o caixa de 13 semanas.

Para quem

Controladoria, gerente financeiro e gestores de centro de custo que precisam ver o desvio com o mês ainda aberto.

O que mudou na empresa

A conferência diária das contas passou a ser automática. O desvio vira aviso com o mês em curso, todo número é conferido antes de sair e desvio já justificado não volta a incomodar.

Módulos e funções.

8 partes do sistema, cada uma com o que faz.

Captação de lançamentos

Puxa ERP, extrato bancário e planilha de orçamento e unifica conta, fornecedor e centro de custo.

Comparação com o histórico

Gasto acumulado até o dia comparado ao mesmo dia dos 18 meses anteriores, com ajuste sazonal.

Comparação com o orçado

Realizado do mês contra o orçamento, com projeção de fechamento pelo ritmo de gasto do mês.

Alerta em português

A IA escreve o aviso com o cálculo pronto; cada número é conferido antes de publicar.

Memória de explicação

Desvio já justificado pelo gestor fica em silêncio até mudar de faixa ou de direção.

Aprofundamento guiado

Detalhe por fornecedor, responsável, documento ou orçado contra realizado, respeitando a permissão de quem pergunta.

Projeção de caixa

Caixa de 13 semanas com títulos em aberto e recorrência; semana com dado atrasado fica marcada.

Trilha de auditoria

Correção retroativa não apaga o passado; cada alerta guarda dado de origem, regra e quem viu.

Três telas.

O design é meu. Cada legenda diz o que a tela faz.

Gasto do mês até hoje comparado com a faixa normal da conta
Tela 1Gasto do mês até hoje comparado com a faixa normal da conta
Caixa de 13 semanas, semana com dado atrasado fica marcada
Tela 2Caixa de 13 semanas, semana com dado atrasado fica marcada
Cada lançamento com o mês de referência e a data de registro
Tela 3Cada lançamento com o mês de referência e a data de registro

Como funciona por dentro.

Um controller que trabalha todo dia: mede o desvio contra a própria história e contra o orçado, escreve o alerta com o modelo e oferece o próximo detalhe.

  1. IngestãoConectores de ERP, extrato bancário e planilha de orçamento puxam por janela incremental, com watermark por conector. A chave natural é conector + id do documento + número da linha. Títulos em aberto entram como snapshot datado, não como lançamento.
  2. NormalizaçãoPlano de contas, fornecedor e centro de custo viram dimensões canônicas. Competência e caixa são gravados como dois fatos do mesmo evento, com a data de conhecimento junto.
  3. Baseline e projeçãoJob diário recalcula a mediana sazonalizada em 18 competências e a curva de acumulação por dia-do-mês. Dispersão por MAD com piso em reais e fallback para IQR quando zera. O mesmo job remonta a projeção de caixa de 13 semanas. Série com buraco de cobertura fica fora da detecção.
  4. DetecçãoDuas réguas em paralelo: z-score robusto sobre o acumulado do mesmo dia-do-mês e estouro contra o orçado da competência com projeção de fechamento. Materialidade em percentual e em reais. Quem passa ganha assinatura com a origem da régua e atravessa o filtro de supressão.
  5. DossiêO desvio é fechado em JSON com os derivados já calculados: delta em reais, delta percentual, concentração por fornecedor, baseline, orçado, cobertura. É tudo que o modelo vai enxergar.
  6. NarrativaO modelo redige o alerta a partir dos slots. O validador normaliza cada numeral do texto e exige casamento com um slot ou com o arredondamento declarado dele.
  7. AprofundamentoO alerta expõe o catálogo de drills daquele tipo de desvio. A pergunta do usuário é roteada para uma query parametrizada, executada sob a RLS dele.
  8. RegistroAlerta, dossiê, régua de origem, versão do prompt, modelo, tokens e latência ficam gravados. O estado do alerta alimenta a supressão do dia seguinte.

O problema e a saída.

O problema

Controladoria roda no calendário: o desvio de agosto vira pauta em setembro, com a nota já paga. Ninguém varre 40 centros de custo por dia, e o BI responde só a primeira pergunta, subiu. Quem gastou, com qual fornecedor, sob qual responsável, não.

A saída

Quatro camadas com contrato explícito. Duas réguas em código, história e orçado, medem o acumulado no mesmo dia-do-mês. O modelo recebe um dossiê fechado e redige; reprovou duas vezes no validador, sai tabular. Drill por catálogo, sob a RLS do tenant.

Arquitetura.

Como as partes se encaixam.

São quatro camadas com contrato explícito entre elas: ingestão, razão canônico, motor de cálculo e camada de conversa. O modelo de linguagem só aparece na quarta. As três primeiras são código determinístico, com teste unitário e resultado reproduzível. O razão é bitemporal: cada lançamento guarda a competência e a data em que o sistema tomou conhecimento dele. Isso permite perguntar "o que sabíamos em 05/08" e reproduzir o alerta daquele dia mesmo depois de o ERP corrigir retroativamente. Ao lado do realizado, que é append-only, o razão guarda um segundo fluxo: títulos em aberto de contas a pagar e a receber, gravados como snapshot datado, porque vencimento e valor mudam até a liquidação. Desse snapshot sai a projeção de caixa de 13 semanas, títulos com vencimento futuro mais recorrência inferida, de contrato quando existe e de repetição do histórico quando não existe (mesmo fornecedor, mesma conta, intervalo regular). Cada semana da projeção carrega o watermark do conector que a alimentou; conector atrasado marca a semana como cobertura incompleta em vez de exibir caixa otimista. A tabela é particionada por competência e protegida por RLS, por tenant e por centro de custo.

O motor de cálculo tem duas réguas em paralelo e nenhuma delas passa por modelo. A primeira é o desvio contra a própria história. Cada par conta × centro de custo vira uma série mensal com janela de 18 competências, e a mediana carrega ajuste sazonal para pontos conhecidos: 13º, férias, tributos anuais, contratos com reajuste em data fixa. Como o mês corre, a comparação nunca é acumulado parcial contra mês inteiro médio: o realizado até o dia D é medido contra a mediana do acumulado até o mesmo dia-do-mês nas competências anteriores. A dispersão vem de MAD, mas MAD zero é caso comum em série contábil esparsa, o motor aplica piso de dispersão em reais e cai para IQR quando o MAD zera, e a série diária crua fica reservada a contas de alta frequência, nunca a par conta × centro com meia dúzia de lançamentos no mês. A segunda régua é orçamentária: realizado da competência contra o budget, mais projeção de fechamento pelo ritmo acumulado do mês. Conta que está na média histórica mas estourou o orçado nasce alerta pela segunda régua. Um desvio só vira alerta se passar por materialidade dupla, percentual e valor absoluto, e recebe uma assinatura, origem da régua, conta, centro, período, direção e faixa de magnitude. A assinatura é a chave de deduplicação e de supressão. Alerta reincidente não é alerta novo; volta a falar quando muda de faixa.

A camada de conversa nunca vê a base. Cada desvio detectado é serializado num dossiê fechado em JSON, e os derivados entram já calculados pelo motor: delta absoluto, delta percentual, concentração dos três maiores fornecedores, janela usada, baseline no mesmo dia-do-mês, realizado, orçado e cobertura do dado. Cada slot vem em duas formas, canônica e de exibição, com o arredondamento permitido declarado junto. O modelo escreve o alerta a partir desses slots e só deles. Antes de publicar, um validador normaliza todo numeral do texto (R$ 412.800, 412.800,00 e 412,8 mil viram o mesmo número) e exige que cada um case com um slot ou com um arredondamento declarado daquele slot. Aritmética feita pelo modelo reprova a geração, mesmo quando a conta fecha. A oferta de aprofundamento, "quer que eu detalhe os responsáveis e fornecedores?", não é improviso: cada tipo de desvio traz um catálogo de drills disponíveis, e o modelo escolhe entre ações registradas. A query roda com a identidade do usuário, sob a mesma RLS do relatório.

Diário de construção.

Por onde comecei, onde travou e o que mudou no caminho.

A ordem foi de baixo para cima. Primeiro o razão canônico e dois conectores, um ERP e um extrato OFX. Depois o motor rodando sobre uma base sintética de 24 meses, gerada a partir de um plano de contas real anonimizado, com sazonalidade e sujeira plantadas de propósito, cadastro duplicado, centro de custo vazio, lançamento retroativo. Nenhum LLM envolvido nessa fase. O gabarito foi uma lista de apontamentos que eu mesmo montei à mão sobre a mesma base, competência por competência, antes de olhar a saída do motor. Só quando a régua parou de discordar da lista é que a voz entrou. Construir na ordem inversa teria produzido um chat convincente em cima de uma estatística errada, que é o modo mais caro de errar aqui.

O trabalho difícil foi o falso positivo. O primeiro corte usava média e desvio padrão sobre seis meses e disparava dezenas de alertas por dia: uma nota atrasada de dezembro contaminava a média e todo mês seguinte virava anomalia. Trocar por mediana e MAD resolveu metade e abriu outro buraco, em série esparsa o MAD zera, o z-score explode e qualquer lançamento vira anomalia infinita. O que ficou de pé foram quatro correções: janela de 18 competências para a mediana, piso de dispersão em reais com fallback para IQR quando o MAD zera, detecção sobre o acumulado da competência no mesmo dia-do-mês em vez de lançamento isolado, e memória de explicação. Desvio que o gestor já justificou fica silenciado enquanto permanecer na mesma faixa; mudou de faixa ou de direção, volta a falar.

O segundo problema foi o número fantasma. Mesmo recebendo o dossiê pronto, o modelo arredondava, somava dois campos e escrevia um total que não existia em lugar nenhum. A saída não foi prompt melhor, foi mudar o contrato: o dossiê passou a carregar os derivados já calculados, cada slot com forma canônica, forma de exibição e arredondamento permitido, e o validador confere numeral por numeral contra esse conjunto. Reprovou, regenera; reprovou de novo, publica em formato tabular sem narrativa. O terceiro foi custo. Gerar narrativa para cada desvio, todo dia, por tenant, sai caro, e quem corta custo aí é a supressão, não o cache: desvio reincidente na mesma faixa simplesmente não regenera texto. O cache pega o resto, com chave por assinatura mais faixa de magnitude, porque o dossiê de mês em curso muda todo dia e chave por versão de dossiê nunca acertaria. Roteamento da pergunta e escolha de template rodam em modelo pequeno; só a redação final usa o modelo grande.

Tecnologias e o porquê.

CamadaEscolhaPor quê
Razão e leituraPostgreSQL particionado por competência, RLS por tenant e por centro de custoEscrita append-only para o realizado, snapshot datado para título em aberto, leitura quase sempre por janela de mês. A partição mantém o índice pequeno, e a RLS garante que o dossiê do chat só enxerga o que o usuário já enxergaria no relatório impresso.
IngestãoWorkers em fila com backoff, DLQ, watermark incremental e chave natural conector + documento + linhaERP cai, responde em 40 segundos e devolve página repetida. Hash de conteúdo não serve de chave: dois reembolsos legítimos e idênticos no mesmo dia colidiriam e um sumiria, subestimando a despesa e enviesando o baseline. Quando o ERP não expõe id de linha, o desempate é o sequencial dentro do documento; o hash fica só para detectar reescrita retroativa.
Motor de cálculoJob Python agendado com numpy e pandas; janela, sazonalidade e piso de dispersão versionados em arquivoMediana sazonalizada, MAD com piso, comparação por dia-do-mês e checagem contra orçado precisam de teste unitário e mesmo resultado a cada execução. Nada disso pode depender de amostragem de modelo.
NarrativaModelo grande só na redação do alerta; modelo pequeno na classificação da pergunta e na escolha do template por tipo de desvioO modelo pequeno nunca decide se é desvio, isso já saiu do motor. Ele roteia pergunta e escolhe template. O dossiê cabe em poucos milhares de tokens, e usar modelo grande nessas duas tarefas dobraria o custo diário sem mudar uma linha do texto final.
AprofundamentoCatálogo de queries parametrizadas versionadas, sem SQL gerado em runtimeLatência previsível, plano de execução conhecido e nenhuma chance de uma pergunta mal formulada varrer o razão inteiro.
ObservabilidadeUma linha por alerta com dossiê, régua de origem, hash do prompt, modelo, tokens e latênciaQuando alguém pergunta por que o alerta de julho dizia outra coisa, dá para reabrir exatamente o que o sistema viu, qual régua disparou e com qual versão de prompt ele escreveu.

Decisões de projeto.

O cálculo fica fora do modelo

Duas réguas em código decidem, corte em % e em reais; o LLM só entrou quando pararam de discordar do gabarito que montei à mão. Ganho: mesmo mês, mesmo número. Perda: padrão sutil escapa.

Razão bitemporal, não sobrescrita

Competência e data de conhecimento lado a lado. Ganho: separa "o gasto mudou" de "a informação chegou depois" e reproduz o alerta de ontem. Perda: todo query carrega recorte temporal.

Supressão corta o custo, não o cache

Assinatura e quatro estados: novo, reincidente, explicado, silenciado. Ganho: reincidente não custa token; o cache pega o resto por assinatura + faixa. Perda: pode calar o que mudou.

Escopo.

O que o sistema cobre

  • Vigilância diária de contas, centros de custo, orçamento e caixa, com o mês ainda em curso.
  • Duas réguas: desvio contra a própria história e estouro contra o orçado da competência, com projeção de fechamento.
  • Alerta em português com o cálculo aberto, janela, baseline no mesmo dia-do-mês, realizado, materialidade, e todo número casando com um slot do dossiê.
  • Aprofundamento guiado por fornecedor, responsável, documento ou orçado contra realizado, sempre sob a RLS de quem perguntou.
  • Projeção de caixa em 13 semanas móveis, sobre títulos em aberto e recorrência inferida, com semana de cobertura incompleta marcada como tal.
  • Trilha completa por alerta: dado de origem, régua que disparou, versão de prompt, modelo, custo e quem viu o quê.

O que não está publicado

  • Nome da empresa e números de operação não são divulgados aqui.
  • O código não é público. O que dá para ver: o processo, as telas e as decisões.

Da mesma faixa.

IA sobre os dados

Quer ver este sistema de perto?

Mostro o processo que mudou, os módulos, as telas e como foi construído.

Contato

Quer ver isso de perto?

Diegorafacarvalho@gmail.com +55 47 98801-8335

Santa Catarina, Brasil, remoto. Costumo responder no mesmo dia.

Sem formulário

  • Recrutador não preenche formulário, copia o e-mail. Ele está aí em cima.
  • A versão rápida é uma página só, imprime em A4 e serve para encaminhar ao tech lead.
  • Qualquer sistema daqui eu mostro em chamada: o processo que mudou, os módulos, as telas e como foi construído.
  • Os sistemas foram desenvolvidos para empresas e o código não é público. Este site também é meu, do motor de scroll ao design: veja como funciona.