O CLAUDE.md da API descrevia entidades que não existem, e o tenant errado¶
Motivação¶
Continuação direta do tweak anterior do mesmo dia, que deixou este arquivo de fora por ser grande demais para ir de carona.
O apps/api/CLAUDE.md é carregado sempre que alguém mexe na API, e duas coisas nele desalinhavam qualquer implementação antes de ela começar. A primeira: dizia que "each tenant is a real estate company (imobiliária)", quando o tenant é a garantidora e a imobiliária é a parceira, modelada como PartnerAgency dentro de um tenant. Quem lesse isso escoparia por imobiliária o que se escopa por garantidora — e escopo errado é a classe de defeito que as specs 0034 e 0035 pagaram, e que as rubricas tratam como Critical.
A segunda: o diagrama de domínio inteiro falava em entidades aposentadas — Persons, PersonDocuments, Proposals, ProposalTenants, ProposalOwners, PropertyOwners, Analysis. Nenhum desses nomes resolve em app/models/ hoje.
Comportamento atual¶
Além dos dois acima:
TenantSettingsdocumentava 9 campos; existem 23. Faltavam o encargo de atraso inteiro, os seis de taxa de adesão, os sete de consulta de crédito e ocollection_methodda spec 0054. E documentava dois campos que não existem mais —covers_property_damageemax_property_damage_value, removidos na spec 0006 —, um deles com regra de validação cruzada que não é executada por ninguém.- A rota de aprovação estava errada:
POST /proposals/{id}/analysis/approve. Não há rota/proposalsnenhuma. Eapproved_initial_fee_valuenão era mencionado, o que ajudou o ROADMAP a listar "taxa setup arbitrada pelo analista" como pendência por dois meses. - Os exemplos de permissão não existiam (
proposals:create,analysis:approve), e a contagem de papéis estava em 6 — são 7 desde que a spec 0051 criouAGENCY_MANAGER. CommitRoutenão era mencionado, apesar de os 26 routers reais o usarem e de a spec 0037 ter perdido uma rodada de validador por um router sem ele devolvendo 201 sem gravar.app/services/scoping.pynão era mencionado — o eixo de escopo por imobiliária, inteiro, invisível no documento.app/domain/,app/worker.pyeapp/templates/não estavam na árvore, e a receita de "Adding a New Feature" não citava porteiro, escopo,downgradenemCommitRoute.TENANT_SECRETS_KEYnão aparecia nas variáveis de ambiente, sendo a única sem default: sem ela a aplicação não sobe.REDIS_URLtambém faltava.make setupera anunciado como "publica no tailnet", que saiu em 2026-09-17.
Comportamento desejado¶
Cada afirmação do arquivo confere com o código, e o que mudou diz o que mudou — para que quem leu a versão antiga reconheça o próprio erro em vez de só ver um texto diferente.
Escopo¶
apps/api/CLAUDE.md (a reescrita), mais as pontas soltas do mesmo defeito achadas no caminho: CLAUDE.md da raiz, ROADMAP.md, apps/web/CLAUDE.md, apps/api/README.md, infra/local/README.md e .claude/skills/make/SKILL.md.
Fora do escopo¶
A dívida técnica em si, de novo: este ajuste corrige a descrição, não o código. Em particular, o .env.example da API não lista quatro variáveis que o config.py lê (PASSWORD_RESET_TOKEN_EXPIRE_MINUTES, PASSWORD_RESET_MAX_REQUESTS, MAX_UPLOAD_SIZE_MB, BCRYPT_ROUNDS) — é defeito de arquivo de exemplo, não de documentação, e não foi tocado.
Alterações propostas¶
apps/api/CLAUDE.md— abertura (quem é o tenant), tech stack (arq/Redis, Fernet, openpyxl), comandos (dev-worker, os quatrowiki-*, e a nota de queuv run pytestpressupõeuvno host), árvore de diretórios comdomain//worker.py/templates/e a regra dodomain/, seção nova deCommitRoute, multi-tenancy com o segundo eixo e a tabela doscoping.py, RBAC com 7 papéis e permissões reais, diagrama de domínio reescrito,Documentcom as cinco FKs,TenantSettingsem quatro blocos, a rota de aprovação correta com as duas arbitragens, a receita de feature com porteiro/escopo/downgrade/CommitRoute, as fixtures que existem, e as variáveis de ambiente que faltavam.CLAUDE.md(raiz) — sete papéis comAGENCY_MANAGER; as cinco FKs doDocument(o texto dizia quatro, e listavacontract, que virouguaranteena 0027);PartnerAgencieseCreditChecksna árvore de entidades, com o aviso de que a imobiliária é um segundo eixo de escopo;PENDINGno lugar dePENDING_DOCS(spec 0037);guarantee_service.pyno lugar decontract_service.pyna nota de cobertura; e otailnetfora domake setup.ROADMAP.md— a contagem de papéis, que este mesmo dia publicou errada como seis.apps/web/CLAUDE.md—VITE_PUBLIC_HOST, que ovite.config.tsnão lê mais.apps/api/README.md,infra/local/README.md,.claude/skills/make/SKILL.md— otailnetnomake setup, omake local-serveque não existe, oapi-seedque nunca existiu ("Popula as traduções"), e o Redis nolocal-up.
Impactos¶
Nenhum no produto: nada em apps/*/src nem em app/ foi tocado, e por isso este ajuste não publica versão nem tag.
Corrige um erro que este mesmo dia introduziu, e vale dizer com nome: o tweak anterior escreveu no ROADMAP que o código tem seis papéis. Tem sete. A contagem veio da linha do CLAUDE.md da raiz, que estava errada, em vez de do rbac_seed.py — exatamente o modo de falhar que a própria revisão existia para combater. A lição é a regra que já está no CLAUDE.md: contagem se pergunta na fonte, não se copia de outro documento.
Validação¶
make preflight — limpo, incluindo a checagem de citação arquivo:linha. python3 scripts/docs_lint.py — verde, catálogo consistente.
Todos os alvos citados no .claude/skills/make/SKILL.md foram verificados um a um contra o Makefile da raiz: os 26 existem, e api-seed era o único fantasma.
Cada afirmação reescrita foi conferida no código antes de ser escrita: os 7 papéis em rbac_seed.py, as 5 FKs de document.py, os 23 campos de tenant_settings.py, a rota real em decisions.py, os 26 routers com route_class=CommitRoute, as funções de dependencies.py e scoping.py, as fixtures do conftest.py, e a ausência de covers_property_damage (confirmada também pelo comentário do router que a declara ignorada).
Não há suíte a rodar: o diff não tem uma linha de TypeScript nem de Python.
Documentos relacionados¶
ADR-0004 — documentação como código. ADR-0003 — a origem única que aposentou o tailnet citado em três arquivos. Tweak de 2026-09-27 — a primeira metade deste trabalho, que nomeou este arquivo como o próximo.