§1O problema
Os extratos ficavam espalhados em apps de bancos diferentes, cada um com seu formato, e nenhum mostrava o conjunto. Faltava ver tudo junto, categorizado, e saber quais contas fixas do mês já foram pagas.
§2O que eu construí
- Conexão com bancosConexão real pela API Enable Banking (Open Banking), com consentimento do banco e sincronização automática diária.
- Extrato unificadoCom filtro por subconta (a unidade do app é a subconta, não o banco).
- CategoriasClassificação que aprende regras a partir do que o usuário corrige.
- Contas fixasValor previsto, “paga ou não” detectada pelo extrato, provisão por “pocket” (subconta de reserva), períodos mensal/bimestral/quadrimestral, moedas diferentes com câmbio do BCE.
- Importação únicaPagamentos trazidos uma única vez de outro app meu, por cópia, para este app não depender dele.
- Modo demonstraçãoDados de exemplo (fixtures), sem tocar em banco nenhum.
§3As partes difíceis
5 itens- 01
Integração real com a API de Open Banking
Consentimento, redirecionamento só por HTTPS, limite diário de consultas do banco e erros passageiros que a próxima sincronização resolve.
- 02
Deduplicação
Sincronizar de novo não duplica lançamentos.
- 03
Detectar “conta fixa paga”
Mesmo quando o texto do banco não bate com o nome, usando também valor e janela de dias.
- 04
Modelar subcontas e datas
Nome do pocket e tipo de conta vêm de endpoints diferentes; vale a data da transação em vez da data de contabilização.
- 05
Migração de esquema do SQLite sem perder dados
Por exemplo, refazer restrições de períodos.
§4Resultado
- lançamentos na primeira importação
- 1.000+
- inseridos na segunda sincronização (sem duplicar)
- 0
Está rodando em produção desde setembro de 2026, com várias conexões bancárias reais e sincronização diária automática. A primeira importação trouxe mais de mil lançamentos, e uma segunda sincronização inseriu zero (a deduplicação funcionou).
§5Stack
- Next.js 16
- React 19
- TypeScript 7
- Tailwind 4
- SQLite (better-sqlite3)
- Design system próprio
- Enable Banking (Open Banking / PSD2)
- pm2
- Agendamento diário
- Tailscale