← Todos os projetos
05Produto próprio · 2026

APM SaaS.

O caixa da associação de pais e mestres, com regras que o próprio banco garante.

RLS em 33 tabelasLedger imutávelTestcontainers
Caixa da associação com saldo, valores a receber e a pagar e a lista de parcelas

O problema

A APM de uma escola mexe com dinheiro das famílias, troca de diretoria a cada mandato e precisa prestar contas. A contribuição é associativa, não é mensalidade. Os dados são de alunos, então a LGPD vale. Se um lançamento puder ser editado depois, ninguém mais confia no saldo.

O que construí

Escrevi tudo sozinho: caixa, contribuições, projetos, importação de extrato com parser OFX, prestação de contas e a passagem de mandato de uma gestão para a outra. As notificações respeitam uma janela de silêncio das 21h às 8h. As regras mais importantes não ficam no código da aplicação. Elas estão no banco, e os testes quebram se alguém esquecer delas.

Decisões técnicas

  1. 01A regra mora no banco

    33 tabelas com FORCE ROW LEVEL SECURITY, 38 policies, 11 funções SECURITY DEFINER, 3 constraint triggers e um EXCLUDE. Se a aplicação tiver um bug, o Postgres ainda recusa o dado que quebra a regra.

  2. 02Ledger que não se edita

    Lançamento não é alterado nem apagado. A correção é um estorno, que fica no histórico. O dinheiro é guardado em centavos, como inteiro. Sem ponto flutuante, sem centavo sumindo no arredondamento.

  3. 03Testes que cobram toda tabela

    rls.test.ts falha se existir tabela sem policy, e audit.test.ts falha se existir tabela sem auditoria. Tabela nova não entra desprotegida por esquecimento. Os testes rodam contra um Postgres de verdade, com Testcontainers.

    Onde está no código: rls.test.ts · audit.test.ts

  4. 04Nenhuma chamada HTTP dentro de transação

    O que precisa sair do sistema vai para um outbox e é processado por jobs no pg-boss, fora da transação. Os jobs são idempotentes, e um teste roda o job de novo para provar isso. Uma API externa lenta não segura lock no banco, e um retry não duplica nada.

Números

31

commits, autor único

~165

testes

37

tabelas

15

migrações

Stack

  • TanStack Start
  • React 19
  • Better Auth
  • PostgreSQL
  • Drizzle
  • Zod 4
  • Tailwind 4
  • pg-boss
  • Vitest
  • Testcontainers
  • Playwright

Telas

Cobranças de contribuição por núcleo familiar, com desconto por irmão
Prestação de contas do período, com entradas, saídas, resultado e a impressão digital do relatório
Próximo case

CRM Next