MoneyLens
Um app de finanças pessoais, feito de ponta a ponta e usado de verdade, com leitura de faturas, previsão de gastos e alertas.
Nesta página
O problema
O controle financeiro começou numa planilha. Ela servia para anotar gastos, mas não dava conta do resto: faturas de cartão com parcelas que atravessam meses, contas fixas que precisam ser confirmadas, extratos de bancos diferentes e a pergunta que mais importa no meio do mês: quanto ainda dá para gastar?
Cada fatura era digitada à mão, e um erro só aparecia no fechamento. O MoneyLens troca essa digitação por leitura automática, com conferência, e responde àquela pergunta com números.
O que o app faz
- Painel do mês: receitas, gastos, saldo previsto, orçamento 50/30/20 e o que ainda falta confirmar.
- Lançamentos, parcelas e fixas: compras parceladas no cartão, no Pix ou no boleto geram as parcelas futuras; as contas fixas entram como previstas e são confirmadas com um clique.
- Importação de PDF: faturas do Inter e extratos do Nubank e do PicPay. O app confere a soma com os totais impressos, reconhece as categorias e deixa em standby o que não reconhece. Ao resolver um item com “lembrar”, ele aprende a regra.
- Cartões: faturas de cada mês, limite usado e pagamento.
- Previsão: quanto cada categoria deve fechar no mês, com um valor provável e um máximo provável.
- Tetos de gasto: por valor ou por porcentagem da renda, com alertas em 50%, 90% e 100% e sugestão a partir do histórico.
- Vários usuários: cada pessoa só enxerga os próprios dados.












Arquitetura
O front-end é um app React servido por um Cloudflare Worker, que também repassa as chamadas de API para o back-end. A API em FastAPI roda num container no Render e guarda tudo num PostgreSQL no Supabase.
A previsão tem um caminho separado: o treino roda fora do servidor, em PyTorch, e o modelo exportado em ONNX vai para o
banco, um por usuário. Na API, quem executa o modelo é o onnxruntime.
Decisões técnicas
Decisão
PyTorch só no treino; a API roda o modelo em ONNX
A imagem de produção não instala o PyTorch. O modelo é treinado fora do servidor, exportado para ONNX e gravado no banco; a API só carrega e executa. O container fica pequeno e a previsão continua rápida.
Decisão
Leitores de PDF que conferem os totais
Cada leitor soma o que leu e compara com os totais que o próprio banco imprime: o total da fatura, o saldo de cada dia, o saldo final. Se não bater, nada é importado. É melhor recusar um PDF do que gravar um número errado em silêncio.
Decisão
Isolamento entre usuários e banco fechado ao público
Toda consulta filtra pelo dono, e um teste confere que nenhuma rota da API fica de fora: o item de outra pessoa responde como se não existisse. No Supabase, o RLS fica ligado sem políticas e os papéis da API pública perdem o acesso, então o banco só atende o back-end.
Decisão
Migração publicada não se edita
O app é publicado a cada push na main, e as migrações rodam na subida. Uma migração que já foi para produção nunca é alterada: qualquer mudança vira uma migração nova, testada no SQLite e no PostgreSQL.
Decisão
Um fuso só em todo o teste
Um teste de ponta a ponta falhava só na CI, entre 21h e meia-noite: o servidor estava em UTC, o navegador em São Paulo, e os dois discordavam sobre que dia era. Hoje o servidor de testes e o navegador rodam no mesmo fuso, o de São Paulo.
Qualidade e testes
- testes no back-end
- 550
- testes no front-end
- 196
- testes de ponta a ponta
- 33
- bancos na CI
- 2
- Back-end: Pytest cobre regras de negócio, API, segurança, migrações e os leitores de PDF. Na CI, a suíte roda no SQLite e no PostgreSQL.
- Front-end: Vitest nos formulários, nos utilitários e no Worker do Cloudflare.
- Ponta a ponta: o Playwright sobe o app com um banco temporário e percorre os fluxos no computador e no celular.
- Dados reais nunca entram: as faturas e os extratos dos testes são sintéticos, gerados por código.
O que aprendi
- Conferir é mais barato que corrigir. A regra de “só importa se o total bater” evitou mais problemas do que qualquer revisão manual.
- Um modelo precisa de uma régua. Cada treino mede o erro da rede neural ao lado do erro de uma estatística simples, no mesmo mês de teste. Com essa referência, fica claro quando o modelo realmente ajuda.
- Fuso horário é requisito. Datas aparecem em faturas, parcelas e alertas; tratar o fuso desde o começo evita bugs que só aparecem à noite.
- Testes de ponta a ponta se pagam. Eles pegaram problemas que nenhum teste de unidade pegaria, como um clique caindo na página anterior durante a troca de rota.