pular para o conteúdo
cd/
projetos

fin

As finanças lá de casa num painel, com aviso no Discord. Só lê os dados do banco, nunca mexe em dinheiro.

tl;dr#

O fin é a ferramenta de finanças lá de casa, e ela só lê. Conecta duas contas bancárias pelo Open Finance (via Pluggy), mostra tudo num dashboard e manda aviso no Discord: resumo do dia, fatura chegando, fatura que aumentou, gasto acima do normal e compra nova. Ela nunca mexe em dinheiro, não tem banco de dados e não guarda valor nenhum em disco. O repositório é privado, porque o que tá ali é dinheiro de verdade; aqui eu conto como funciona, sem mostrar dado nenhum.

o problema#

cada um da família tem a própria conta, em banco diferente. pra saber quanto a casa gastou no mês, ou se a fatura do cartão subiu, era abrir dois apps e somar de cabeça.

eu queria duas coisas: ver tudo num lugar só, e um aviso que chega sozinho, sem ninguém precisar lembrar de abrir nada.

por que Pluggy (e o Meu Pluggy)#

o Open Finance é o sistema do Banco Central que deixa você autorizar um app a ler os dados da sua conta. a Pluggy é a ponte pra isso, mas o plano comercial dela custa R$ 2.500 por mês, o que não faz sentido pra uso de família.

o caminho que eu usei foi o Meu Pluggy, o portal pessoal deles, com o Conector 200, que dá acesso à API dos seus próprios dados. é de graça e não tem prazo. só que o plano grátis tem um custo: o cache dos dados atualiza uma vez por dia, então nada aqui é tempo real (e eu aceitei isso, explico mais embaixo).

o lado bom é a privacidade: cada pessoa autoriza o próprio banco, no app do banco. ninguém vê a senha de ninguém, e o acesso é só de leitura.

como é por dentro#

o projeto tem três frentes em cima do mesmo núcleo:

Pluggy ─► fonte (única camada que sabe de onde vem o dado)
              │
              ▼
        serviços (regras puras: extrato, faturas, gastos, avisos)
              │
   ┌──────────┼──────────────────────┐
   ▼          ▼                      ▼
dashboard   relatório            notificador
(Next.js)   (terminal)           (Vercel Cron ─► Discord)

não tem banco de dados. as transações são lidas da fonte a cada execução, ficam na memória e somem quando o processo acaba.

decisões#

só leitura. o fin nunca paga fatura, nunca transfere, nunca muda cadastro. é a regra número um, e é a que mais me deixa tranquilo.

dinheiro em centavos, em número inteiro. 0.1 + 0.2 dá 0.30000000000000004 em ponto flutuante, e esse erro vai acumulando. com inteiro isso não existe; a conversão pra reais só acontece na hora de mostrar na tela.

data como string YYYY-MM-DD, nunca Date. new Date("2026-01-31") é meia-noite em UTC, que no horário de Brasília vira dia 30 e joga a transação pro mês errado, sem dar erro nenhum. como string, o mês é um slice(0, 7) e a ordem por data é a mesma da ordem alfabética.

mês é mês do calendário; ciclo de fatura é outra coisa. o mês vai do dia 1 até o último. o ciclo da fatura (fecha num dia, vence em outro, cada cartão no seu) só existe dentro do cálculo de faturas, e é feito conta por conta. misturar os lançamentos antes de calcular dava um número que parece certo e tá errado, e tem teste só pra travar isso.

nenhum valor de dinheiro em disco. a única coisa salva é o estado do notificador, e ele guarda só a chave de cada aviso e a data de envio. as chaves de transação passam por um HMAC com segredo próprio, então se o arquivo vazar não dá pra saber quanto ninguém gastou. tem um teste que confere que nada com cara de dinheiro é gravado. credencial nunca fica em texto puro.

aviso não chega duas vezes. todo aviso tem uma chave fixa, e o estado só é salvo depois que o envio dá certo. se a rede cair, o aviso sai na próxima execução em vez de sumir, e mandar o mesmo lote de novo não duplica nada.

o resumo espera o dado chegar. como o cache da Pluggy atualiza uma vez por dia, o resumo do dia anterior chegava atrasado ou faltando coisa. agora, se dá pra provar que o dado é mais velho que ontem, o envio espera e a próxima execução tenta de novo.

sem tempo real, de propósito. o dado só muda uma vez por dia, então um WebSocket ia ficar aberto esperando uma novidade que não existe. as telas leem a fonte a cada navegação, sem cache, porque número financeiro velho é número errado.

linha descartada sempre aparece. nada some calado: um total menor que o real, sem aviso, seria o pior defeito possível numa ferramenta dessas.

testes#

os testes usam node:test, sem framework, um arquivo por módulo, e já passam de 350. a regra do projeto é que toda conta de dinheiro tem teste, cobrindo virada de mês, virada de ano, ano bissexto, lista vazia e divisão por zero. o notificador também tem teste de que não manda aviso repetido e de que não grava dinheiro.

o que eu aprendi#

status#

tá em uso aqui em casa. o código é privado, então não tem link pro repositório nem demo no ar.