Plano — módulo de back-end no padrão das skills wehive
TLDR: refactor puramente estrutural sobre a fundação da USER-001, em 5 fases: tirar os metadados de repo de dentro do módulo, completar os entrypoints, mover o
app/para a Arrow Architecture, espelhar a árvore de testes e documentar. A suíte Minitest existente é a rede de segurança — nenhuma fase muda comportamento.
Spec: Módulo de back-end no padrão das skills wehive
Branch: refactor/backend_skills_standard, criada de feat/rails_backend_scaffold_foundation — o
scaffold que este plano corrige ainda não estava em main.
Stack: Rails 8.1 (API), Zeitwerk, Minitest, RuboCop (rails-omakase), targets de make do commons
(make backend.<entrypoint>).
Divergências do executado: a camada de terceiros ficou como
app/bridges/, nãoapp/external/;app/core/acabou subdividido emmodels/euse_cases/(ambos autoload roots), entãoapplication_record.rbestá emapp/core/models/; e os entrypoints migraram depois debin/pararun/. O estado final está em Camadas do app Rails.
Restrições globais
- Commits de uma linha, máximo 60 caracteres, em português, sem menção a IA.
- Nenhuma mudança de comportamento em nenhuma fase — a suíte tem que ficar verde ao fim de cada uma.
- Os binstubs do Rails vindos do
rails newsão mantidos (decisão do owner) — não apagar nenhumbin/*existente. - Todo move de arquivo via
git mv, para preservar histórico.
Fases
mermaid
graph LR
F1["1 · Limpar<br/>metadados"] --> F2["2 · Entrypoint<br/>lint"]
F2 --> F3["3 · app/ para<br/>Arrow"]
F3 --> F4["4 · Espelhar<br/>test/"]
F4 --> F5["5 · Documentar"]
style F3 fill:#1f2937,color:#fff
Fase 1 — Remover os metadados de repo do módulo
Apagar modules/backend/.claude/ (symlinks commands, skills), modules/backend/.codex/ (idem) e
modules/backend/.project/ai/ (só .gitkeeps).
bash
git rm -r modules/backend/.claude modules/backend/.codex modules/backend/.project
Verificar que nada ficou rastreado nem em disco:
bash
git ls-files modules/backend | grep -E '\.claude|\.codex|modules/backend/\.project' # vazio
ls -a modules/backend
O .gitignore já cobre modules/**/ para os três, então eles não voltam silenciosamente. Rodar
make backend.test (mesma contagem de antes) e commitar:
chore: remove metadata de repo do modules/backend.
Resultado: um módulo contendo apenas .module/, Makefile, os entrypoints e as fontes Rails.
Fase 2 — Adicionar o entrypoint lint
O conjunto padrão é runtime, install, test, lint; falta o último. Cada entrypoint vira
make backend.<nome> automaticamente, via make/core/commands.mk do commons.
```bash #!/usr/bin/env bash set -e
exec bundle exec rubocop “$@” ```
Tornar executável (chmod +x) e rodar make backend.lint — o target tem que sair com 0. Se o
RuboCop apontar offenses nos arquivos de scaffold, corrigir nesta fase. Commit:
chore: adiciona bin/lint no backend.
Fase 3 — Mover o app/ para a Arrow Architecture
O núcleo do plano. Os nomes de classe não mudam — só os caminhos.
| De | Para |
|---|---|
app/controllers/application_controller.rb |
app/ports/controllers/application_controller.rb |
app/controllers/health_controller.rb |
app/ports/controllers/health_controller.rb |
app/controllers/api/v1/base_controller.rb |
app/ports/controllers/api/v1/base_controller.rb |
app/controllers/concerns/paginatable.rb |
app/ports/controllers/concerns/paginatable.rb |
app/jobs/application_job.rb |
app/ports/jobs/application_job.rb |
app/models/application_record.rb |
app/core/application_record.rb |
bash
cd modules/backend
mkdir -p app/ports/controllers/api/v1 app/ports/controllers/concerns app/ports/jobs \
app/core app/external app/platform
git mv app/controllers/application_controller.rb app/ports/controllers/
git mv app/controllers/health_controller.rb app/ports/controllers/
git mv app/controllers/api/v1/base_controller.rb app/ports/controllers/api/v1/
git mv app/controllers/concerns/paginatable.rb app/ports/controllers/concerns/
git mv app/jobs/application_job.rb app/ports/jobs/
git mv app/models/application_record.rb app/core/
git rm app/controllers/concerns/.keep app/models/concerns/.keep
touch app/external/.keep app/platform/.keep
git add app/external/.keep app/platform/.keep
Registrar os autoload roots de ports em config/application.rb, logo depois de
config.autoload_lib(ignore: %w[assets tasks]):
ruby
%w[controllers controllers/concerns jobs].each do |dir|
path = root.join("app/ports/#{dir}")
config.autoload_paths << path
config.eager_load_paths << path
end
app/core, a camada de terceiros e app/platform não precisam de registro — todo diretório app/* é
autoload root por convenção do Rails, e os .keep são ignorados pelo Zeitwerk.
Verificar antes de commitar:
bash
cd modules/backend && bin/rails zeitwerk:check # All is good!
ls modules/backend/app # as 4 camadas
make backend.test # mesma contagem de antes
Commit: refactor: layout arrow no app do backend.
Fase 4 — Espelhar a árvore de testes
| De | Para |
|---|---|
test/controllers/health_controller_test.rb |
test/ports/controllers/health_controller_test.rb |
test/controllers/api/v1/base_controller_test.rb |
test/ports/controllers/api/v1/base_controller_test.rb |
test/controllers/concerns/paginatable_test.rb |
test/ports/controllers/concerns/paginatable_test.rb |
O conteúdo dos arquivos de teste não muda — as referências de classe continuam as mesmas.
test/integration/ e test/models/ ficam como estão.
Atenção na verificação: make backend.test tem que passar com a mesma contagem da Fase 3. O
runner faz glob em test/**/*_test.rb; uma contagem menor significa que algum arquivo movido deixou
de ser coletado — corrigir antes de commitar.
Commit: refactor: espelha test com layout arrow.
Fase 5 — Documentar o layout do back-end
Escrever a seção de arquitetura do back-end cobrindo as quatro camadas: core (negócio: entidades e
use cases nomeados substantivo + verbo), ports (controllers e jobs finos — um use case por ação,
zero ifs de negócio), a camada de terceiros (sempre Micro::Case devolvendo Success/Failure) e
platform (maquinaria transversal de transporte). Registrar que os autoload roots de app/ports/*
são declarados em config/application.rb.
A regra que a seção precisa deixar explícita: um controller faz exatamente autenticar, extrair params, chamar um use case e renderizar pelo resultado — sem query direta nem chamada externa.
Commit: docs: arquitetura arrow do backend.
Na época esta seção foi anexada ao fim do doc de arquitetura, que era um arquivo único. Hoje ela é um doc próprio: Camadas do app Rails.
Verificação
Verificação final, correspondente ao “Como verificar” da spec:
bash
make backend.test # verde
make backend.lint # rubocop, exit 0
cd modules/backend && bin/rails zeitwerk:check # All is good!
make backend.up && curl -s localhost:4010/health # 200 {"status":"ok",...}
ls modules/backend/app # as 4 camadas da Arrow
git ls-files modules/backend | grep -E '\.claude|\.codex|modules/backend/\.project' # vazio