Manual de trabalho · desenvolvedor solo + IA
Guia de Produto Solo
O processo para sair de uma ideia e chegar a um SaaS em produção, e depois mantê-lo, sem se perder. Cada etapa tem o que fazer, para que serve, um exemplo e um checklist. O exemplo usado do começo ao fim é um SaaS de gestão de processos para escritórios de advocacia, com matriz (tenant) e filiais (subtenants).
Instrução inicial para o agente
Preencha os dados do projeto abaixo: a instrução de início sai completa. Copie e cole como primeira mensagem, numa pasta vazia, quando começar o produto. O que ficar em branco, o agente pergunta. Ele conduz a Fase 0 e a Fase 1 com você e cria os arquivos de documentação, inclusive o CLAUDE.md, que passa a guiar as próximas sessões.
A partir daí, toda sessão nova começa com a instrução de retomada, que é bem mais curta.
Vamos começar um produto novo do zero. Eu desenvolvo sozinho e você é meu par de desenvolvimento. Leia esta instrução inteira antes de agir. ## O produto (rascunho) - Ideia: [descreva em 2 a 5 frases] - Público: [quem usa] - Multi-tenant: [sim/não]. Subtenants: [sim/não, ex.: matriz → filiais] - Stack preferida: [ex.: Go + Postgres + React] (ou "me sugira") - Hospedagem: [ex.: VPS própria com Nginx] (ou "me sugira") - Idioma da interface: [pt-BR] ## Como vamos trabalhar Papéis: eu sou o arquiteto e revisor (decido o quê e aprovo o como); você propõe, implementa, testa e revisa. Nenhuma decisão de arquitetura fica só no chat: tudo vira arquivo no repositório. O processo tem fases. Não avance de fase sem minha aprovação explícita. ### Fase 0: Descoberta → docs/PRD.md Me entreviste antes de escrever qualquer coisa. Uma pergunta por vez, com opções e uma recomendação quando fizer sentido. Cubra: problema, personas, 3 a 5 fluxos principais, o que fica fora do MVP, modelo de cobrança, métrica de sucesso e restrições (LGPD, integrações). No máximo 12 perguntas. Depois escreva docs/PRD.md e peça aprovação. ### Fase 1: Fundação Na ordem, pedindo aprovação ao fim de cada item: 1. Modelo de domínio: entidades e relações, com diagrama Mermaid. 2. ADRs em docs/adr/NNNN-titulo.md (contexto, decisão, alternativas descartadas, consequências), no mínimo: stack; isolamento de tenant; hierarquia de subtenants e o que cada nível enxerga; autenticação; RBAC; hospedagem e deploy. 3. docs/ARCHITECTURE.md: módulos, fluxo de uma requisição, onde fica cada responsabilidade. No máximo duas páginas. 4. CLAUDE.md na raiz: invariantes, regras de trabalho, comandos e convenções. Curto, só regras. Inclua as invariantes abaixo. 5. Estrutura do repositório, README (como rodar), .env.example, docs/ROADMAP.md, docs/TECH-DEBT.md, CHANGELOG.md. 6. Walking skeleton: login → tenant resolvido → uma tela que lista dados → deploy. Nenhuma feature de negócio ainda. 7. CI com lint, typecheck, testes, build e testes de isolamento entre tenants em tests/isolation/. 8. Backup automático do banco e um teste de restauração. ### Fase 2 em diante: ciclo de cada feature spec em docs/features/nome.md (objetivo, regras, critérios de aceite, casos de borda, permissões) → plano dividido em fatias, sem código, para eu aprovar → branch feature/nome → uma fatia por vez, com testes, commit por fatia → revisão de segurança do diff → PR com CI verde → atualizar ROADMAP, CHANGELOG e spec. Bugs: primeiro um teste que reproduz e falha, depois a causa raiz, depois a correção mínima. ## Padrões iniciais para multi-tenant (confirme comigo nos ADRs) - Banco único com tenant_id uuid NOT NULL em toda tabela de negócio, Postgres RLS ativo e forçado. - Hierarquia com parent_id + ltree; o pai vê a subárvore, irmãos não se veem. - O tenant vem só do token autenticado, resolvido em middleware. Nunca de parâmetro, corpo ou query string. - RBAC: papel vinculado a usuário × tenant; herança para baixo explícita. - Usuário do banco da aplicação não é dono das tabelas; migrations rodam com outro usuário. ## Invariantes (vão para o CLAUDE.md) - Toda tabela de negócio: tenant_id + RLS. Tabelas globais listadas em ADR. - Toda feature adiciona casos em tests/isolation/. - Toda ação nova tem permissão RBAC e teste do 403. - Logs incluem tenant_id e nunca dados pessoais em claro (CPF, e-mail, senha). - Segredos só em .env, que fica no .gitignore. - Migrations no padrão expand/contract. ## Regras de trabalho - Plano antes de código em qualquer mudança com mais de um arquivo. - Passos pequenos; testes passando a cada commit. - Nunca altere um teste existente para fazê-lo passar: pare e explique. - Não adicione dependências nem serviços externos sem minha aprovação. - Prefira soluções simples: monolito modular, um banco, deploy simples. Nada de microserviços ou Kubernetes sem motivo registrado em ADR. - Quando algo for ambíguo, pergunte em vez de supor. - Quando eu corrigir o mesmo erro seu duas vezes, proponha uma regra nova para o CLAUDE.md. - Textos da interface em [pt-BR]; mensagens de erro dizem o que houve e como resolver. - Ao fim de cada sessão, atualize docs/ROADMAP.md com a próxima ação concreta. ## Agora Confirme em até 5 linhas que entendeu o processo e comece a Fase 0 com a primeira pergunta.
Leia CLAUDE.md e docs/ROADMAP.md. Me diga em até 5 linhas: em que fase estamos, o que foi feito por último e qual é a próxima ação. A tarefa de hoje é: [ex.: fatia 3 de docs/features/convites.md]. Leia a spec correspondente e proponha o plano antes de escrever código.
Por que duas instruções: a de início monta o processo e gera os documentos. Depois disso, as regras já estão no CLAUDE.md, que o agente lê sozinho, e a memória do projeto está no ROADMAP. Colar a instrução longa toda vez seria redundante e poderia contradizer decisões que vocês já tomaram nos ADRs.
A ideia central
A IA escreve código rápido, mas esquece tudo entre uma sessão e outra. Se as decisões do projeto ficam só no chat, cada sessão começa do zero, a IA reinventa o que já foi decidido, e o sistema vira uma colcha de retalhos. É aí que você se perde.
A solução é guardar a memória do projeto no repositório: documentos curtos, decisões registradas e testes. A cada sessão, você e a IA leem o mesmo material e partem do mesmo ponto.
Divisão de papéis. Você é o arquiteto e o revisor: decide o quê, aprova o como e lê o que é crítico. A IA é a implementadora: propõe planos, escreve código e testes e revisa quando você pede. Sozinho, você faz o papel de toda a equipe; os documentos e a CI substituem os colegas que você não tem.
Cinco regras que valem para todo o guia:
- Nada importante fica só no chat. Decidiu? Escreva num arquivo.
- Plano antes de código. Errar no plano custa minutos; errar no código custa dias.
- Passos pequenos. Uma fatia, teste passando, commit. Sempre dá para voltar.
- Os testes são o contrato. Eles dizem se o sistema faz o que deveria.
- A segurança fica no banco e na CI, não na sua memória. Você e a IA vão esquecer coisas; o sistema precisa barrar o erro sozinho.
Mapa do processo
As fases 0 e 1 acontecem uma vez por produto. As fases 2 a 5 se repetem durante toda a vida do produto.
Ciclo do dia a dia: 2 → 4 → 2 → 4… com 3 quando aparece um bug e 5 no calendário.
Glossário
Os termos que aparecem neste guia, na ordem em que você os encontra no processo.
Documentos
- PRDProduct Requirements Document
Documento do produto: o que o sistema faz, para quem e por quê. Não diz como é construído.
Ex.: "Escritórios com filiais precisam que cada filial veja só os próprios processos, e a matriz veja todos."
- MVPMinimum Viable Product
A menor versão do produto que já resolve o problema principal para um cliente real. Tudo o que não é essencial fica para depois.
Ex.: cadastrar processos e prazos com filiais. Relatórios e integração com tribunais ficam fora.
- ARCHITECTURE.md
Visão técnica do sistema: módulos, como os dados fluem, onde fica cada responsabilidade. Uma ou duas páginas.
Ex.: "API Go → camada de serviço → repositório → Postgres. O tenant é resolvido no middleware."
- ADRArchitecture Decision Record
Arquivo curto que registra uma decisão técnica difícil de desfazer: contexto, decisão, alternativas descartadas, consequências. Um arquivo por decisão, numerado.
Ex.:
adr/0002-postgres-com-rls.md. Daqui a 6 meses, a resposta para "por que foi feito assim?" está escrita.- Spec de feature
Meia página descrevendo uma funcionalidade antes de codar: objetivo, regras, critérios de aceite, casos de borda.
Ex.:
docs/features/convite-de-usuario.md.- Critério de aceite
Frase verificável que define quando a feature está pronta. Cada critério vira um teste.
Ex.: "Convite expira em 7 dias; link expirado mostra 'Este convite expirou. Peça um novo ao administrador.'"
- CLAUDE.md
Arquivo de regras que a IA lê no início de toda sessão. Contém invariantes, comandos e convenções. Não é documentação, é uma lista de regras.
Ex.: "Toda tabela de negócio tem
tenant_id NOT NULLe política RLS."- Invariante
Regra que nunca pode ser quebrada, em nenhuma circunstância.
Ex.: "Um usuário nunca lê dados de um tenant ao qual não pertence."
- ROADMAP.md
A lista do que está feito, em andamento e próximo. É o primeiro arquivo que você lê ao voltar ao projeto depois de dias.
- CHANGELOG.md
Histórico das mudanças por versão, escrito para humanos.
Ex.: "v0.4.0 · Convites de usuário por e-mail; correção no filtro de prazos."
- Definition of Done
A lista fixa de condições para considerar qualquer tarefa "pronta". Neste guia, é o checklist da Fase 2.
Multi-tenant e segurança
- Tenant
Cada cliente do SaaS, com seus dados isolados dos demais. Todos usam o mesmo sistema, mas um não enxerga o outro.
Ex.: o escritório "Silva Advogados" é um tenant.
- Subtenant
Um tenant dentro de outro, formando uma árvore. O pai pode ver os filhos; os irmãos não se veem.
Ex.: "Silva Advogados" → filial SP e filial RJ.
- Autenticação
Confirmar quem é a pessoa (login, senha, token).
- Autorização
Decidir o que essa pessoa pode fazer, depois de autenticada.
- RBACRole-Based Access Control
Autorização por papéis: você cria papéis com permissões e atribui papéis às pessoas, dentro de um tenant.
Ex.: Maria é "Advogada" na filial SP (lê e edita processos), mas não tem papel na filial RJ.
- RLSRow-Level Security
Recurso do Postgres que filtra as linhas da tabela pelo tenant atual, direto no banco. Mesmo que o código esqueça o
WHERE tenant_id, o banco não devolve dados de outro cliente.É a rede de segurança contra o pior erro de um SaaS: vazar dados entre clientes.
- Segredo
Senha, chave de API ou token. Fica só em variável de ambiente ou no arquivo
.env, que nunca entra no git.
Git e fluxo de código
- Commit
Uma foto salva do código, com mensagem. Faça commits pequenos, cada um funcionando.
Ex.:
feat(convites): envia e-mail de convite- Branch
Uma linha de trabalho separada. A
mainé o que vai para produção; cada feature tem sua branch.Ex.:
feature/convites,fix/prazo-fuso-horario.- Diff
A lista exata do que mudou: linhas adicionadas e removidas. É o que você revisa.
- PRPull Request · no GitLab: MR
Pedido para juntar uma branch na
main. Mostra o diff, roda a CI e guarda a descrição do porquê. Mesmo sozinho, vale usar: obriga você a revisar e deixa histórico.- Merge
Juntar a branch na
main, depois que a PR foi aprovada e a CI passou.- Rebase / conflito
Conflito acontece quando duas mudanças alteram as mesmas linhas. Branches curtas (1 a 3 dias) quase eliminam o problema.
Qualidade e automação
- CIContinuous Integration
Um robô (GitHub Actions, GitLab CI) que roda lint, testes e build a cada push. Se algo quebrar, a PR fica vermelha e não deve ser mergeada.
Sozinho, é o seu revisor que nunca esquece de rodar os testes.
- CDContinuous Delivery/Deployment
Deploy automatizado: depois do merge na
main, o sistema vai para produção (ou para staging) sem passos manuais.- Lint
Ferramenta que aponta código mal escrito ou suspeito (variável não usada, erro comum).
Ex.:
golangci-lint,eslint.- Typecheck
Verificação de tipos sem executar o programa. Pega erros como passar texto onde se espera número.
Ex.:
tsc --noEmit,go vet.- Teste unitário
Testa uma função isolada, rápido.
Ex.: "calculaPrazo pula feriados".
- Teste de integração
Testa várias partes juntas, geralmente com banco real.
Ex.: "o endpoint de processos devolve só os do tenant logado".
- Teste E2Eend-to-end
Simula o usuário no navegador, do login ao fim do fluxo. É lento, então use só nos fluxos principais.
Ex.: Playwright.
- Regressão
Algo que funcionava e parou de funcionar depois de uma mudança. O teste criado na correção de um bug evita que ele volte.
Operação
- Ambientes
dev (sua máquina), staging (cópia de produção para testar) e prod (clientes reais). Sozinho, no começo, dev + prod bastam; crie staging quando tiver clientes pagando.
- Migration
Script versionado que altera o banco (cria tabela, adiciona coluna). Roda em ordem e fica no git.
Ex.:
0007_add_prazo_to_processos.sqlcom goose.- Expand / contract
Forma segura de mudar o banco em duas etapas: primeiro adiciona o novo sem remover o antigo (expand); depois que o código novo está no ar, remove o antigo (contract). Assim, um rollback não quebra nada.
- Deploy
Colocar uma versão nova em produção.
- Rollback
Voltar para a versão anterior quando o deploy deu errado. Precisa estar planejado antes do deploy.
- Smoke test
Verificação rápida pós-deploy: o site abre, o login funciona, a tela principal carrega.
- Observabilidade
Logs (o que aconteceu), métricas (quanto e quão rápido) e alertas (avisam você quando algo sai do normal).
- Backup / restore
Cópia do banco e o teste de restaurá-la. Backup que nunca foi restaurado não é backup confiável.
- Feature flag
Interruptor para ligar uma feature só para alguns tenants, ou desligá-la sem novo deploy.
- Dívida técnica
Atalho que você tomou conscientemente e que vai custar mais depois. Fica anotado em lista, não escondido.
Estrutura do repositório
Cada arquivo tem uma função. Se você não sabe onde escrever algo, use esta tabela.
meu-saas/ ├── CLAUDE.md regras e invariantes (a IA lê sempre) ├── README.md como rodar o projeto em 5 minutos ├── CHANGELOG.md o que mudou em cada versão ├── docs/ │ ├── PRD.md o quê e por quê │ ├── ARCHITECTURE.md como o sistema é organizado │ ├── ROADMAP.md feito / fazendo / próximo │ ├── TECH-DEBT.md atalhos conscientes a pagar │ ├── adr/ │ │ ├── 0001-stack.md │ │ ├── 0002-isolamento-de-tenant.md │ │ └── 0003-rbac.md │ └── features/ │ ├── convites.md │ └── prazos.md ├── server/ backend │ └── migrations/ mudanças de banco versionadas ├── web/ frontend ├── tests/ inclui tests/isolation/ (tenants) ├── .env.example nomes das variáveis, sem valores reais └── .github/workflows/ci.yml
| Quero registrar… | Vai em |
|---|---|
| Uma regra que a IA não pode quebrar | CLAUDE.md |
| Uma decisão técnica com alternativas | docs/adr/NNNN-*.md |
| Como uma funcionalidade deve se comportar | docs/features/*.md |
| Onde eu parei e o que vem depois | docs/ROADMAP.md |
| Um atalho que tomei de propósito | docs/TECH-DEBT.md |
| Uma senha ou chave | .env (nunca no git) |
FASE 0Descoberta
Para que serve: decidir o que construir antes de construir. Sem isso, você e a IA codam a ideia do dia, e o produto muda de direção a cada sessão.
- Escreva o problema em duas frases."Escritórios com filiais controlam prazos em planilhas separadas. A matriz não enxerga atrasos das filiais."
- Descreva quem usa e o que faz hoje.Sócio da matriz, advogado da filial, estagiário. Como resolvem o problema hoje e onde dói.
- Liste de 3 a 5 fluxos principais, passo a passo."Advogado cadastra processo → define prazo → recebe alerta 3 dias antes."
- Escreva o que fica fora.A lista "fora do escopo" é o que protege o MVP de crescer sem fim.
- Defina como vai cobrar e como vai medir sucesso.Cobrança por tenant ou por usuário afeta o modelo de dados.
Use a IA aqui como entrevistadora: peça para ela fazer perguntas sobre a ideia antes de escrever o PRD.
Quero criar um SaaS de [ideia]. Antes de escrever qualquer documento, me faça até 10 perguntas, uma de cada vez, para entender usuários, fluxos principais, o que fica fora do MVP e como vou cobrar. Depois, escreva docs/PRD.md usando o modelo que vou colar.
FASE 1Fundação
Para que serve: tomar as decisões que são caras de mudar depois e montar o esqueleto que garante a qualidade de tudo o que vier. Faça uma vez, com calma. É a fase que mais economiza tempo no futuro.
- Desenhe o modelo de domínio.Entidades e relações: Tenant, Usuário, Vínculo (usuário × tenant × papel), Processo, Prazo. Peça para a IA gerar um diagrama Mermaid e revise.
- Registre as decisões estruturais em ADRs.Stack, isolamento de tenant, hierarquia de subtenants, autenticação, RBAC. Veja a seção Multi-tenant.
- Escreva o ARCHITECTURE.md e o CLAUDE.md.Módulos, fluxo de uma requisição, invariantes, comandos.
- Construa o walking skeleton.A versão mais fina possível que passa por todas as camadas: login → tenant resolvido → uma tela que lista dados → deploy em produção. Sem features ainda.
- Monte a CI e os testes de isolamento.A partir daqui, toda mudança passa pela CI.
Por que o esqueleto antes das features: se o deploy, a autenticação ou o isolamento estiverem errados, você descobre no dia 3, quando consertar é barato, e não no mês 4, com 40 tabelas para ajustar.
Escolhas sensatas para quem trabalha sozinho
- Monolito modular, não microserviços. Um processo, módulos bem separados por pasta.
- Um banco Postgres com RLS. Banco por tenant só se um cliente exigir por contrato.
- Deploy simples: uma VPS com systemd/Docker e Nginx, ou uma plataforma gerenciada. Kubernetes não.
- Autenticação pronta (biblioteca ou serviço) em vez de escrever do zero.
name: ci
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
services:
postgres:
image: postgres:16
env: { POSTGRES_PASSWORD: test }
ports: ["5432:5432"]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with: { go-version: "1.23" }
- run: make lint
- run: make test # inclui tests/isolation
- run: make buildFASE 2Ciclo de feature
Para que serve: transformar uma ideia de funcionalidade em código que funciona, testado e documentado, sem quebrar o resto. É o ciclo que você vai repetir centenas de vezes, sempre igual.
- Spec.Escreva
docs/features/convites.md: objetivo, regras, critérios de aceite, casos de borda, permissões. Meia página. - Plano.Nova sessão com a IA em plan mode. Ela lê a spec e o CLAUDE.md e propõe arquivos, tabelas, endpoints e fatias. Você revisa e corrige o plano. É onde a arquitetura é protegida.
- Branch.
git switch -c feature/convites - Fatias.Implemente uma fatia por vez (ex.: 1. tabela + migration; 2. endpoint de criar convite; 3. e-mail; 4. tela). Cada fatia: testes passando → commit.
- Testes dos critérios de aceite.Cada critério da spec vira pelo menos um teste. Nas partes críticas, peça o teste antes do código.
- Revisão.Leia o diff. Autenticação, tenant, permissões e dinheiro: linha a linha. Depois peça para a IA revisar segurança.
- PR e merge.Abra a PR com descrição, espere a CI ficar verde e faça o merge.
- Atualize os documentos.Spec (se mudou algo), ROADMAP, CHANGELOG e, se surgiu uma regra nova, CLAUDE.md.
Exemplo de fatiamento
| Fatia | Entrega | Teste que prova |
|---|---|---|
| 1 | Tabela convites com tenant_id e RLS | Tenant B não lê convites do A |
| 2 | POST /convites (só admin) | Advogado recebe 403; admin cria |
| 3 | E-mail com link de 7 dias | Link expirado devolve mensagem clara |
| 4 | Tela de convidar e aceitar | E2E: convidar → aceitar → entrar |
FASE 3Correção de bug
Para que serve: corrigir a causa, não o sintoma, e garantir que o bug nunca volte. A regra é simples: sem reproduzir, não se corrige.
- Descreva.Passos para reproduzir, resultado esperado, resultado obtido, tenant e usuário afetados.
- Escreva um teste que falha.Ele reproduz o bug. Se você não consegue escrever o teste, ainda não entendeu o bug.
- Encontre a causa raiz.Peça para a IA explicar a causa antes de propor a correção.
- Faça a correção mínima.Sem refatorar junto. Refatoração vai em outra PR.
- Procure o mesmo erro em outros lugares.O padrão que causou o bug costuma se repetir.
Bug: [descrição]. Passos: [...]. Esperado: [...]. Obtido: [...]. 1. Escreva primeiro um teste que reproduz o bug e confirme que ele falha. 2. Explique a causa raiz antes de propor a correção. 3. Faça a correção mínima, sem refatorar outras partes. 4. Procure o mesmo padrão em outros arquivos e me liste onde aparece.
FASE 4Release
Para que serve: levar o código para produção sem perder dados e com caminho de volta. Sozinho, você não tem quem segure as pontas; por isso o checklist.
Migrations seguras (expand / contract)
Exemplo: renomear a coluna prazo para data_limite.
- Deploy 1 (expand): adiciona
data_limite, copia os dados, e o código passa a escrever nas duas e ler da nova. - Deploy 2 (contract): dias depois, com tudo estável, remove
prazo.
Se o deploy 1 der errado, a versão anterior ainda funciona, porque a coluna antiga continua lá.
FASE 5Manutenção
Para que serve: impedir que o sistema apodreça. Sem rotina, dependências envelhecem, dívida acumula e o CLAUDE.md fica cheio de regras que já não valem.
Refatoração
Só com os testes passando antes e depois, em PR separada de feature. Peça para a IA não mudar comportamento: se algum teste precisar mudar, a refatoração mudou o comportamento.
Multi-tenant com subtenants
Estas são as decisões que você toma na Fase 1 e registra em ADR. Mudar depois significa migrar todas as tabelas.
| Decisão | Opções | Recomendado para solo |
|---|---|---|
| Isolamento | Banco compartilhado com tenant_id · schema por tenant · banco por tenant | Compartilhado + tenant_id + RLS |
| Hierarquia | parent_id simples · caminho materializado (ltree) · closure table | parent_id + ltree |
| Origem do tenant | Token de login · subdomínio · cabeçalho | Do token validado; nunca do corpo da requisição |
| Visibilidade na árvore | Pai vê filhos? Filho vê pai? Irmãos se veem? | Pai vê a subárvore; filhos e irmãos não |
| Autorização | RBAC por tenant · RBAC com herança na árvore | Papel vinculado a um nó; herança explícita para baixo |
| Dados globais | Tabelas sem tenant (ex.: lista de tribunais) | Listar no ADR e marcar no código |
1. Tabela de tenants com hierarquia
CREATE EXTENSION IF NOT EXISTS ltree; CREATE TABLE tenants ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), parent_id uuid REFERENCES tenants(id), slug text NOT NULL UNIQUE, -- "silva", "silva_sp" (ltree não aceita hífen) path ltree NOT NULL, -- matriz: 'silva' · filial: 'silva.silva_sp' nome text NOT NULL ); -- matriz e todas as filiais abaixo dela: SELECT * FROM tenants WHERE path <@ 'silva';
2. RLS: o banco filtra sozinho
ALTER TABLE processos ENABLE ROW LEVEL SECURITY;
ALTER TABLE processos FORCE ROW LEVEL SECURITY;
-- vê linhas do tenant atual e dos tenants abaixo dele
CREATE POLICY isolamento ON processos
USING (
tenant_id IN (
SELECT id FROM tenants
WHERE path <@ (SELECT path FROM tenants
WHERE id = current_setting('app.tenant_id')::uuid)
)
);
-- em cada requisição, dentro da transação:
SET LOCAL app.tenant_id = '…uuid do tenant do usuário logado…';FORCE ROW LEVEL SECURITY, como acima). Senão o RLS é ignorado em silêncio. Use um usuário separado para rodar migrations.3. Middleware: o tenant vem do login
func TenantMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
claims, ok := auth.FromContext(r.Context()) // token já validado
if !ok {
http.Error(w, "Sessão expirada. Entre novamente.", http.StatusUnauthorized)
return
}
ctx := tenant.With(r.Context(), claims.TenantID)
next.ServeHTTP(w, r.WithContext(ctx))
})
}
// O repositório lê tenant.From(ctx) e executa SET LOCAL app.tenant_id
// no início de cada transação. Nenhum handler recebe tenant_id do cliente.4. RBAC com escopo por tenant
CREATE TABLE papeis (id text PRIMARY KEY); -- 'admin', 'advogado', 'estagiario'
CREATE TABLE permissoes (papel_id text REFERENCES papeis,
acao text, -- 'processo.ler', 'processo.editar'
PRIMARY KEY (papel_id, acao));
CREATE TABLE vinculos (usuario_id uuid, tenant_id uuid, papel_id text,
PRIMARY KEY (usuario_id, tenant_id));
-- Maria: (maria, silva_sp, 'advogado') → edita processos de SP, nada no RJ.5. O teste que não pode faltar
func TestTenantNaoVeDadosDeOutro(t *testing.T) {
a := criaTenant(t, "silva")
b := criaTenant(t, "souza")
criaProcesso(t, a, "Processo do Silva")
lista := listaProcessos(t, comoUsuarioDe(b))
if len(lista) != 0 {
t.Fatalf("vazamento: tenant %s viu %d processo(s) de %s", b, len(lista), a)
}
}
func TestFilialNaoVeIrma(t *testing.T) { /* SP não vê RJ */ }
func TestMatrizVeFiliais(t *testing.T) { /* matriz vê SP e RJ */ }Invariantes para o CLAUDE.md
- Toda tabela de negócio tem
tenant_id uuid NOT NULL, RLS ativo e forçado. - O tenant vem só do contexto autenticado. Nunca de parâmetro, corpo ou query string.
- Toda feature nova adiciona casos em
tests/isolation/. - Chaves de cache, arquivos em storage e jobs de fila carregam o
tenant_id. - Logs incluem
tenant_ide nunca dados pessoais em claro. - Tabelas globais (sem tenant) estão listadas no ADR 0002. Qualquer outra precisa de tenant.
Trabalhando com a IA
Faça
- Uma sessão por tarefa. Ao mudar de assunto, comece uma nova.
- Comece apontando para arquivos: "leia CLAUDE.md e docs/features/x.md".
- Peça plano primeiro, código depois.
- Peça que ela faça perguntas quando algo estiver ambíguo.
- Use a IA como revisora de um código que ela não escreveu nesta sessão.
- Quando ela errar a mesma coisa duas vezes, adicione uma regra no CLAUDE.md.
- Faça commit a cada fatia que funciona.
Evite
- "Faz o sistema todo" num prompt só.
- Sessões enormes misturando três assuntos.
- Aceitar diff sem ler em autenticação, tenant ou cobrança.
- Deixar a IA alterar um teste para ele passar.
- Decidir arquitetura no chat e não registrar em ADR.
- Pedir "melhore o código" sem dizer o que é melhor.
- Instalar dependência nova sem você aprovar.
Prompts prontos
Leia CLAUDE.md, docs/ARCHITECTURE.md e docs/features/[nome].md. Proponha um plano: arquivos que vai criar ou alterar, tabelas e migrations, endpoints, permissões RBAC e testes. Divida em fatias que possam ser commitadas separadamente. Não escreva código ainda. Se algo na spec estiver ambíguo, pergunte antes.
Implemente apenas a fatia [N] do plano aprovado. Escreva os testes dos critérios de aceite desta fatia. Rode make test e make lint. Não altere testes existentes; se algum quebrar, pare e me explique por quê.
Revise o diff desta branch contra a main com foco em: 1. alguma query, cache, arquivo ou job sem tenant_id? 2. algum handler aceita tenant_id vindo do cliente? 3. tabela nova sem RLS ou sem FORCE ROW LEVEL SECURITY? 4. ação nova sem checagem de permissão RBAC? 5. dado pessoal em log? Liste os problemas com arquivo e linha. Não corrija ainda.
A feature está pronta. Atualize docs/ROADMAP.md (mova para "feito" e escreva o próximo passo), adicione a entrada no CHANGELOG.md e ajuste docs/features/[nome].md se o comportamento mudou durante a implementação. Sugira regras novas para o CLAUDE.md, se houver.
Rotina de sessão
O que fazer ao sentar para trabalhar e ao parar. É o que evita o "onde eu estava mesmo?".
Modelos prontos
Copie, cole no arquivo indicado e preencha.
PRD docs/PRD.md
# PRD: [Nome do produto] ## Problema [Duas frases: quem sofre, com o quê.] ## Usuários - [Persona]: [o que faz hoje, onde dói] ## Fluxos principais 1. [Fluxo]: passo → passo → resultado ## MVP inclui - ... ## Fora do escopo (por enquanto) - ... ## Cobrança [Por tenant / por usuário / por uso. Faixas.] ## Sucesso [Métrica e prazo. Ex.: 3 escritórios usando por 30 dias.] ## Restrições [LGPD, prazos, integrações obrigatórias.]
ADR docs/adr/NNNN-titulo.md
# ADR 0002: Isolamento de tenants com Postgres RLS Data: AAAA-MM-DD · Status: aceito ## Contexto SaaS multi-tenant com filiais. Um vazamento entre clientes é o pior erro possível. Desenvolvedor solo; custo de operação precisa ser baixo. ## Decisão Banco único, coluna tenant_id em toda tabela de negócio, RLS ativo e forçado. Tenant definido por SET LOCAL a partir do token. ## Alternativas descartadas - Banco por tenant: isolamento máximo, mas migrations e custo multiplicam por N. - Schema por tenant: meio-termo, complica conexões e migrations. ## Consequências - Toda tabela nova precisa de política RLS (regra no CLAUDE.md). - Usuário da aplicação não pode ser dono das tabelas. - Relatórios entre tenants exigem usuário separado e auditado.
Spec de feature docs/features/nome.md
# Feature: Convite de usuário
## Objetivo
Admin do tenant convida pessoas por e-mail para entrar com um papel.
## Regras
- Só papel admin convida.
- Convite vale 7 dias e é de uso único.
- Admin da matriz pode convidar para qualquer filial; admin de filial
só para a própria.
## Critérios de aceite
- [ ] Admin envia convite; e-mail chega com link.
- [ ] Advogado tenta convidar: 403 com mensagem
"Só administradores podem convidar pessoas."
- [ ] Link expirado: "Este convite expirou. Peça um novo ao administrador."
- [ ] Tenant B não vê convites do tenant A.
## Casos de borda
- E-mail já cadastrado em outro tenant: cria só o vínculo novo.
- Convite reenviado: invalida o anterior.
## Permissões (RBAC)
- convite.criar: admin
- convite.listar: admin
## Fora do escopo
- Convite em massa por planilha.
## Dúvidas abertas
- ...CLAUDE.md raiz do repositório
# [Produto] [Uma frase sobre o produto.] Documentos: docs/PRD.md, docs/ARCHITECTURE.md, docs/adr/, docs/features/. ## Invariantes (nunca quebrar) - Toda tabela de negócio: tenant_id uuid NOT NULL + RLS ativo e forçado. - Tenant vem só do contexto autenticado; nunca do cliente. - Toda feature adiciona casos em tests/isolation/. - Toda ação nova tem permissão RBAC e teste do 403. - Logs: incluir tenant_id; nunca CPF, e-mail ou senha em claro. - Segredos só em .env (gitignored). ## Como trabalhar - Plano antes de código; uma fatia por vez; commit por fatia. - Não alterar testes existentes para fazê-los passar. Se quebrar, pare e explique. - Não adicionar dependências sem aprovação. - Migrations no padrão expand/contract. ## Comandos - make run · make test · make lint · make migrate ## Convenções - Textos em pt-BR. Erros dizem o que houve e como resolver. - Commits: feat(escopo): … · fix(escopo): … · docs: …
Relato de bug issue ou descrição da PR
## Bug: [resumo] Tenant/usuário afetado: [id, sem dados pessoais] Ambiente: prod / staging / dev Passos: 1. ... Esperado: ... Obtido: ... Causa raiz: ... Correção: ... Teste de regressão: [arquivo/nome do teste] Mesmo padrão em outros lugares? [sim/não, onde]
Descrição de PR ao abrir a PR
## O quê [Resumo da mudança.] ## Por quê Spec: docs/features/[nome].md ## Como testar 1. ... ## Checklist - [ ] Testes dos critérios de aceite - [ ] Tabelas novas com tenant_id + RLS - [ ] Permissões RBAC + teste do 403 - [ ] Migrations expand/contract - [ ] Docs atualizados (ROADMAP, CHANGELOG)
ROADMAP docs/ROADMAP.md
# Roadmap ## Próxima ação [Uma frase concreta. Ex.: "Convites, fatia 3: e-mail de convite."] ## Em andamento - [ ] Convites (docs/features/convites.md): fatias 1–2 feitas ## Próximos - [ ] Prazos com alerta - [ ] Painel da matriz ## Feito - [x] Walking skeleton em produção (v0.1.0) - [x] Login e RBAC básico (v0.2.0)