O problema
A empresa precisava emitir e acompanhar ordens de serviço, cadastrar clientes e embarcações, faturar por mês e mandar orçamentos para o cliente aprovar, tudo isso em duas linhas de negócio que não podem misturar dados. Desenvolvi o sistema do zero entre julho e outubro de 2026, e ele roda hoje na operação.
O que ele faz
- Emissão de OS com impressão em PDF e exportação para Excel.
- Orçamentos enviados por link seguro: o cliente aprova online e o orçamento vira OS.
- Cadastro de clientes e embarcações, faturamento mensal e painel com gráficos.
Decisões
Numeração transacional
O número de cada OS sai de um contador lido e incrementado dentro de uma transação do Firestore.
Por quê: número de OS é documento da empresa. Se duas pessoas emitem ao mesmo tempo, uma das transações é refeita com o valor novo, e nunca saem duas OS com o mesmo número.
Uma linha de negócio, um projeto Firebase
Cada linha de negócio tem seu próprio projeto Firebase, com Auth e Firestore separados.
Por quê: isolamento físico dos dados. Um filtro esquecido numa consulta não consegue vazar dados de uma empresa para a outra, porque eles nem estão no mesmo banco.
Sem backend próprio, regras do Firestore como barreira
A SPA fala direto com o Firebase. Quem pode ler e escrever o quê é decidido pelas regras de segurança do Firestore.
Por quê: custo de infraestrutura zero, o que era requisito. Em troca, as regras viram a camada de segurança de verdade, e o custo de leitura do plano gratuito foi tratado como requisito no desenho das consultas.
Repositórios como único acesso ao banco
Só os arquivos
*Repositorio.tsfalam com o Firestore. Páginas e hooks nunca chamam o banco direto.Por quê: com o acesso concentrado, os testes com Vitest rodam contra um Firestore simulado em memória, sem depender de rede nem de emulador.