Você vai trabalhar no OnlineImóveis (/home/fisgar/onlineimoveis, repo
Fisgar/onlineimoveis, branch de trabalho feat/self-host-migration). Leia o
CLAUDE.md do repo antes de qualquer coisa — ele é longo, é a fonte da verdade
compartilhada entre as sessões, e cobre a arquitetura de banco, a captação e as
convenções do time.
Dois usuários rodam múltiplas sessões simultâneas do Claude Code no mesmo repositório. Hoje elas se atropelam, e os modos de atropelo silencioso são os caros:
| Superfície | Como atropela | Sinal? |
|---|---|---|
Container único oimoveis-app-dev-1 |
último deploy vence; você testa a feature do outro achando que é a sua | nenhum |
| Banco de dev compartilhado | migração de um muda o schema debaixo do outro | nenhum |
/root/onlineimoveis no fisgar99 (cópia scp, sem git) |
scripts sobrescritos sem histórico nem diff | nenhum |
Crons + kill-switches (/root/STOP_*) |
um pausa o pipeline, o outro monitora e não entende | nenhum |
| Checkout local único | duas sessões editando o mesmo arquivo | conflito de git (visível) |
Memória do Claude (~/.claude/projects/.../memory/) |
é por usuário — o outro nunca vê; já gerou memória duplicada | fraco |
Evidência real, medida em 2026-08-07: durante uma sessão de monitoramento,
outro agente disparou o deploy 2026-08-07-29-dev sem que a primeira soubesse; e
duas sessões do mesmo usuário escreveram memórias duplicadas sobre o mesmo fato.
Verificado no repo e no servidor em 2026-08-07:
.github/workflows/deploy.yml:69-71já temconcurrency: group: deploy-<prod|dev>, cancel-in-progress: false. Dois deploys pro mesmo ambiente enfileiram. A corrida de CI está resolvida.infra/scripts/deploy-remote.sh:89já lêAPP_CONTAINERdo env (CONTAINER="$(envget APP_CONTAINER)"), com os nomes fixos por ambiente só como fallback (oimoveis-app-1/oimoveis-app-dev-1). A parametrização que o preview env precisa já está lá.- O swap no box faz healthcheck e rollback automático pra imagem anterior se a nova não responder 200 pelo Kong.
infra/scripts/kong-ingress.shpublica hosts no Kong da Fisgar de forma idempotente e aditiva, tudo prefixadooimoveis-.- O runner não tem shell no box: a chave de deploy tem
command="/usr/local/sbin/oimoveis-deploy",restrictnaauthorized_keys, e o único caminho édeploy <env> <sha>com o tarball no stdin (infra/scripts/ci-deploy-wrapper.sh). infra/scripts/release.sh dev|prodmarca release à mão a partir de qualquer branch e cai na mesma CI.
- O certificado é wildcard de UM nível. É um único LE
*.onlineimoveis.com.br+ apex, emitido por DNS-01 (o token do Cloudflare disponível é só DNS, não cria Origin Certificate). Ele cobrepr-foo.onlineimoveis.com.bre NÃO cobrepr-foo.dev.onlineimoveis.com.br— wildcard não desce dois níveis. Ou os previews ficam num nível só, ou o cert precisa ser reemitido incluindo*.dev.onlineimoveis.com.br. Decida isso antes de escrever qualquer rota, e confira o cert você mesmo:openssl x509 -in /root/oimoveis-selfhost/cf/letsencrypt/live/onlineimoveis.com.br/cert.pem -noout -text | grep -A2 "Subject Alternative Name" - O container do Kong do Supabase é
oimoveis-supabase-kong-1(dev:oimoveis-dev-supabase-kong-dev-1), nãooimoveis-kong-1. O serviço foi renomeado porquekongcolidia com o gateway da Fisgar na rede compartilhada. Documentação antiga ainda diz o nome errado; apontar pra ele derruba a API. Confira comcurl 127.0.0.1:8001/services/<nome>. - O Kong do fisgar99 é o ingress de ~50 aplicações da Fisgar, DB-backed,
container
kong, redesnginx+kong_kong-postgres. Rota errada não quebra só o OnlineImóveis. Tudo que você criar é aditivo e prefixadooimoveis-. /root/onlineimoveisno fisgar99 NÃO é um repositório git — é cópia manual porscp. É a armadilha mais séria da lista: dois agentes se sobrescrevem sem erro, sem log e sem diff.- Container novo precisa estar na rede
nginxpro Kong resolver por DNS, e isso não é declarativo hoje em alguns casos — umdocker compose up -dque recrie o container o tira da rede e o host quebra em silêncio.
Meça, não presuma. O CLAUDE.md e as memórias são fotografias e podem estar
desatualizados — verifique tudo que for usar como premissa, e diga
explicitamente o que encontrou diferente do documentado.
- Leia
deploy.yml,deploy-remote.sh,ci-deploy-wrapper.sh,kong-ingress.sh,release.sh,setup-ci.sh. - No fisgar99 (
ssh root@116.202.146.114): inventarie os containersoimoveis-*, as redes, as rotas/services/SNIsoimoveis-já no Kong (curl 127.0.0.1:8001/routes,/services,/certificates), e os recursos livres (RAM e disco). - Determine o custo real de um container de app (RSS de
oimoveis-app-dev-1) pra saber quantos previews cabem. - Levante como o DNS é gerenciado (token Cloudflare é só DNS; A records proxied).
- Confira se há algum lock/lease já em uso no box.
Apresente a arquitetura antes de implementar, com o custo de cada peça. A direção recomendada (mas questione se a medição contradisser):
O app é barato e sem estado; o dado é caro. Isole o app, compartilhe o dado. Clonar a captação por sessão está fora de questão — são ~3,8M anúncios e ~77M fotos.
As camadas propostas:
- Worktree por sessão —
git worktree add ../oi-<topico> -b feat/<usuario>/<topico>. Custo zero, elimina colisão de edição. Nunca duas sessões na mesma branch. - Preview env por branch —
ENVIRON=previewnodeploy-remote.sh(a variávelAPP_CONTAINERjá existe) + rota dinâmica nokong-ingress.sh, apontando pro mesmo Supabase de dev. TTL: derruba no merge/fechamento da branch ou após N horas ocioso. Precisa de um garbage collector — preview órfão acumulando é como o disco enche. - Migração aditiva-only em dev compartilhado — coluna nullable, tabela nova,
função com nome novo. Nada de
DROP/RENAME/troca de tipo. Quem precisar de mudança destrutiva sobe um Postgres próprio só com opublic(supabase/schema_bootstrap.sql, 92 tabelas, minutos) e mantém a captação por FDW apontando pro capture DB de dev em leitura. - Estado mutável do box vira código — os scripts de cron deveriam chegar em
/root/onlineimoveispelo deploy, não porscpad-hoc. Enquanto não for assim, um lease explícito com dono/sessão/expiração. - Pre-flight obrigatório antes de qualquer deploy —
gh run list --workflow=deploy.yml --limit 5(se houverin_progress, esperar) +git fetch && git log --oneline origin/dev -5.
Implemente o que for aprovado. Escreva as convenções no CLAUDE.md, não na
memória do Claude: a memória é por usuário e o outro usuário nunca a vê; o
CLAUDE.md é versionado e as duas pessoas leem. Fato de projeto → CLAUDE.md.
Preferência pessoal → memória.
Teste de verdade: suba dois previews simultâneos de branches diferentes, confirme que cada URL serve o código certo, e derrube-os pelo GC.
- Nunca
git pushemmainnemdev— as duas fazem deploy automático em produção sem confirmação humana. Trabalhe em branch própria e empurre pra ela. - Deploy de produção é decisão do dono, nunca de sessão de agente.
- O fisgar99 é servidor de produção de ~50 aplicações da Fisgar e não tem
firewall de perímetro (o escopo vem de
/root/oimoveis-firewall.sh). Só ações escopadas e não destrutivas: não reinicie o daemon do Docker, não mexa em firewall/rede global, não reinicie o box, não toque nos containers de terceiros. Confirme antes de qualquer coisa que possa afetar as outras aplicações. - Antes de deployar, cheque se outro agente não está deployando (o pre-flight acima). Isso é o motivo desta tarefa existir.
- Rode
ghpra CI; não invente credencial nova. - Varra por segredo antes de qualquer commit.
infra/.env,/opt/fisgar-alerts/config.she/opt/data/.envcontêm chaves — leia se precisar, nunca imprima nem commite.
- Um relatório curto do que você mediu na Fase 1, marcando o que diverge da documentação.
- A arquitetura proposta com custo por peça.
- O código, testado com dois previews simultâneos reais.
- As convenções no
CLAUDE.md. - Commit + push na sua branch de trabalho (nunca em
main/dev).