O que muda quando seu software deixa de servir um cliente e passa a servir muitos — multi-tenancy, RLS e as decisões que não dá pra desfazer.
org_id em toda tabela · RLS no banco, não no app · terceirize billing · decida cedo o que não dá pra desfazer
Construir software para um cliente é diferente de construir um produto. No primeiro, você resolve um problema específico, com regras de negócio conhecidas e um único conjunto de usuários. No segundo, você precisa servir N empresas que não se conhecem — e não podem se ver.
A primeira vez que tentamos transformar uma feature de cliente em produto, descobrimos que quase nada do código era reutilizável. Schema, autenticação, permissões, billing, onboarding — tudo precisava ser repensado.
O que parecia uma extensão era um projeto novo.
A diferença real entre um app de cliente e um SaaS multi-tenant não está no frontend. Está na forma como os dados são isolados, no modelo de auth e na fronteira entre o que é da plataforma e o que é da empresa que assina.
Toda decisão de SaaS começa por aqui: como duas empresas dividem o mesmo banco sem nunca verem os dados uma da outra. A escolha errada nesse ponto custa um rewrite no segundo cliente.
→ Quando o isolamento depende do código do frontend, basta um bug numa query para vazar dados entre clientes. Com RLS, mesmo um SELECT * sem filtro retorna apenas o que a org logada pode ver.
Construir SaaS sozinho ou em equipe pequena exige uma stack que reduza decisões. Cada peça tem um motivo concreto — quase sempre porque elimina código de infraestrutura que não agrega valor pro produto.
→ Nenhuma dessas peças é opinião — são consequência de duas regras: (1) não escrever o que dá pra terceirizar, (2) deixar o banco resolver o que pode resolver.
Algumas escolhas no início são quase invisíveis e se tornam impossíveis de reverter quando o produto já tem clientes pagantes. Vale parar e decidir antes de a primeira linha de código.
user pertence a 1 org? a várias? convite por e-mail? Mudar isso depois quebra todo schema de permissão
cobra por usuário, por uso ou por plano fixo? Define schema de planos e limites — refatorar é doloroso
self-service ou liberação manual? Define tudo: signup, criação de org, trial, ativação de Stripe
cliente pediu pra sair com os dados, você consegue? GDPR e LGPD exigem — pensar antes evita correria depois
como liberar funcionalidade pra alguns clientes sem subir branch? Decidir cedo evita if(orgId === 'X') no código
Nenhuma dessas decisões precisa estar perfeita no MVP. Mas todas precisam estar conscientes — escolha errada por desconhecimento é a única que machuca de verdade.
Defina o problema com um único cliente real. Quem é, o que dói, quanto pagaria. Sem cliente concreto, qualquer SaaS é hipótese.
Modele o schema com org_id em todas as tabelas desde o primeiro CREATE TABLE. Crie políticas de RLS antes de qualquer query no app.
MVP funcional: signup → criar org → fluxo principal → 1 caso de uso completo. Sem Stripe ainda. Foco é validar o uso, não cobrar.
Stripe + planos + limites. Onboarding self-service. Logs de uso por org. A partir daqui é produto, não protótipo.
Iterar com base no que os primeiros 3 clientes fazem (e o que não fazem). Cortar features que ninguém usa. Ouvir o pedido recorrente.
SaaS não é tecnologia — é distribuição de software com cobrança recorrente. Se o seu produto não resolve um problema que alguém pagaria todo mês para resolver, nenhuma stack salva. Comece pelo cliente, não pelo schema.