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ão app/external/; app/core/ acabou subdividido em models/ e use_cases/ (ambos autoload roots), então application_record.rb está em app/core/models/; e os entrypoints migraram depois de bin/ para run/. 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 new são mantidos (decisão do owner) — não apagar nenhum bin/* 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