Pular para conteúdo

0007 — Adotar a lib xadm-comum-web (infra web)

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-11 · Decidido em: 2026-08-05

Contexto

O webstorm-ecom estava meio-migrado na infra web. Coexistiam dois corpos de erro: um ProblemDetail local (record de 5 campos, RFC-7807 completo, usado pelos handlers de auth) e um Problema pobre (record de 3 campos, montado à mão pelo ProdutoController). Havia ainda cópias de VersaoInfo (versão em runtime) e SaudeController (/health). A adoção do xadm-seguranca (decisão 0006) deixou AuthExceptionHandler/ViewRejectionHandler apontando para o ProblemDetail local, com a re-extração para a lib adiada para esta fase.

A casa extraiu esse núcleo web para a lib br.com.xadm:xadm-comum-web (pacote br.com.xadm.comum.web; ADR 0019 no repo central). O ProblemDetail da lib é idêntico ao local (mesmo record, mesmo .of(HttpStatus, String, String), mesmo CONTENT_TYPE) — dois corpos de erro divergentes são dívida ativa e superfície de drift cross-client.

Decisão

webstorm-ecom depende da xadm-comum-web (registro Maven Forgejo, org xadm pública) — adotada na 0.1.0; a versão corrente é a do build.gradle.kts (fonte única, hoje 0.8.0) e elimina as cópias locais da infra web:

  • Corpo de erro único — deletados dto/ProblemDetail local e comum/Problema. AuthExceptionHandler/ViewRejectionHandler repontam o import para o ProblemDetail da lib (lógica idêntica). O ProdutoController passa a montar o corpo via ProblemDetail.of(status, status.name(), detail) + ProblemDetail.CONTENT_TYPE — ganha os campos detail/code que o Problema não tinha. Mudança de campo: a mensagem, que ia no title, passa para detail; o title vira a razão do status e entra o code estável — é o efeito da unificação (provado por ProdutoControllerIT, que assere code+status no corpo do 400).
  • Versão e health da lib — deletados a VersaoInfo (raiz) e o comum/SaudeController locais. A versão vem da VersaoInfo da lib (@Singleton implements InfoSource; também exposta em /info); o /health passa a ser o HealthController da lib (@Secured(IS_ANONYMOUS), mesmo shape {status, versao}). O /health já era anônimo no intercept-url-map e no ViewWhitelist.
  • Fallback de versão — quando version.properties falta, o canônico da lib é "desconhecida" (o local era "dev"). Só observável sem o arquivo gerado; nos testes ele existe no classpath.

Fica local (não migrado nesta fase)

  • SentryInitializer — a versão do thoms tem extras app-específicos (tag cliente, skip por MICRONAUT_ENVIRONMENTS, sendDefaultPii, diagnosticLevel) ausentes na lib. Parametrizar a lib para absorvê-los é follow-up, não este PR. (Resolvido em 2026-08-11 — ver Atualização abaixo.)
  • Error-flow — o thoms não tem UnifiedErrorResponseProcessor (handlers distribuídos) nem hierarquia de exceção HTTP. Centralizar o error-flow na lib é refactor maior, fora deste lift.

Consequências

  • Correções/evoluções do corpo de erro e do health passam a vir por bump de versão da lib, não por editar cópia — é o ganho central (mesmo racional do xadm-seguranca).
  • Nova superfície /info (management, anônima via /management/**) com a versão — inócua, subproduto do InfoSource da lib.
  • xadm-comum-web continua em 0.1.0 (ainda pré-1.0.0): esta é a primeira adoção — a API estabiliza quando ela assentar.

Alternativas descartadas

  • Manter os dois corpos de erro — zero trabalho, mas perpetua a dívida (o motivo da extração) e deixa o ProdutoController fora do contrato RFC-7807 rico.
  • Adotar só o ProblemDetail, manter VersaoInfo/SaudeController locais — meio-passo; as cópias de versão/health seguem drift-prone sem ganho.
  • Migrar Sentry e error-flow junto — alarga o PR e espalha o risco; ambos ficam como follow-up explícito.

Linhagem de trabalho: .ia/009-adota-xadm-comum-web-*.

Atualização 2026-08-11 — bump das libs + SentryInitializer absorvido

Junto da migração da constituição 0.26.6 → 0.28.0, os follow-ups desta decisão fecharam:

  • xadm-comum-web 0.1.0 → 0.4.0. A 0.3.0 implementou o seam de code/title do processor de erro da casa (o ProblemDetail ganhou invalidParams e o overload of(status, code, title, detail); o .of(status, code, detail) de 3 args continua). Este app usa handlers de auth distribuídos, não o UnifiedErrorResponseProcessor — o corpo de erro segue igual, apenas com o campo aditivo invalidParams (vazio no caminho atual).
  • SentryInitializer deixa de ser local — passa a vir do xadm-comum-web. A lib absorveu os extras app-específicos (tag cliente, skip por MICRONAUT_ENVIRONMENTS, sendDefaultPii), então a cópia de br.com.xadm.webstormecom.comum foi deletada (com seu teste) e o Application.main chama br.com.xadm.comum.web.SentryInitializer.inicializar() (assinatura da lib; era initFromEnvironment()). O comportamento agora é testado na lib.
  • xadm-seguranca 0.2.0 → 0.3.0 (bump de acompanhamento; mesmo conjunto de classes, aditivo). A ViewSecurityRule local permanece por desenho (regra de views específica do app).

Atualização 2026-08-19 — bump de manutenção 0.4.0 → 0.5.0

Acompanhamento do latest do registro. Source-compatível: ProblemDetail, VersaoInfo, HealthController e SentryInitializer seguem com as mesmas assinaturas usadas aqui — zero adaptação, gate da stack verde. Corpo de erro e /health inalterados.

Atualização 2026-09-11 — 0.9.0 e 0.9.1

  • 0.9.0: a env do commit passou a ser XADM_COMMIT. O Coolify sobrescreve a SOURCE_COMMIT com HEAD em recurso pull-only; o rename entrou nos dois Dockerfiles, nos build-args do pipeline.yml e na decisão 0014.
  • 0.9.1: a lib embarca o reflect-config.json do SentryAppender (três entradas, com métodos) e o arquivo local saiu (ver 0011). O 404 de negócio, devolvido por uma rota que casou, passa a ir a DEBUG; só o 404 de rota não casada em requisição autenticada vai a ERROR. O contrato de wire não muda.