Etapa 08 — Modernização: Java 25 + Micronaut 5 e auth nativa¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-06-17
Delta de modernização sobre a base Java 21 / Micronaut 4.7.6. Nada de comportamento observável mudou: a suíte completa (incl. docker/Testcontainers e o E2E de auth) passou sem alterar asserções — prova de paridade.
1. Contexto¶
O projeto estava uma major atrás (Micronaut 4.7.6, Java 21) e acumulava "código caseiro" onde o framework já oferecia o primitivo. Esta etapa moderniza a stack e realinha o código, em passos verificados contra a suíte.
2. Stack: Java 25 + Gradle 9.5.1 + Micronaut 5.0.2¶
- Toolchain JDK 25 (GraalVM 25.0.3 via SDKMAN); o Gradle 9.5.1 roda em
Java 25 — exigência do plugin
io.micronaut.application5.Dockerfilee CI passam atemurin:25/setup-java 25. - Os breaking changes reais do salto e como foram resolvidos estão na
decisão 0019 (serde default,
jackson explícito,
ViewModelProcessor<T,R>, checksum S3 do Garage, Testcontainers), incluindo a consolidação Jackson 2 → 3 (tools.jackson.*, removendo as classes duplicadas do uber-jar).
A serialização HTTP migrou para o serde (build-time, allowlist @Serdeable) e o
TelegramService virou @Client declarativo — detalhe na
decisão 0020.
Limpeza menor junto: bindings descartados viraram unnamed variables
_(JEP 456) em 5 pontos (catches e lambdas).
3. status stringly-typed → enums¶
ProcessamentoXls.status e ResetarPowersync.status deixam de ser String com
literais repetidos e viram enums (ProcessamentoStatus, ResetStatus),
mapeados como name() na fronteira (contrato JSON inalterado). Ganha checagem em
compile-time e elimina o "X".equals(getStatus()) sempre-falso silencioso.
4. Config espalhada → @ConfigurationProperties records¶
Os ~27 @Value soltos viram records tipados por prefixo coeso: S3Config,
TelegramConfig, CoolifyConfig, PowersyncMongoConfig/PowersyncPostgresConfig/
PowersyncNukeConfig, AppConfig, ArmazenamentoConfig, LogsConfig. Paths de
config preservados (nenhum env/contrato quebrado, incl. powersync.nuke.*).
Injeção 100% por construtor; sobra só o app.api-token como @Value single-use.
5. Contrato de erro único + Bean Validation¶
Todo corpo de erro da API passa a sair como {code, message} num ponto único
(ErrorResponseProcessor), substituindo os três formatos que coexistiam (Hateoas
default, envelope ad-hoc do login, status-no-corpo). Detalhe e porquê na
decisão 0017. Bean Validation foi
ativado nos pontos limpos (@Positive/@Size); a trilha de segurança do login
ficou manual de propósito (ver 0017).
6. Auth das views: caseiro → micronaut-security nativo¶
O AuthFilter (@Filter paralelo ao SecurityFilter) foi substituído por
primitivos nativos, mantendo UX, cookies e envs idênticos. Porquê e estratégia
de paridade na decisão 0018.
flowchart TB
user[Usuário X-Adm] -->|login Google| fb[Firebase]
fb -->|ID token| login[LoginController]
login -->|cookie xadm_session| browser[Browser]
browser -->|cookie| fetcher[SessionAuthenticationFetcher]
fetcher -->|Authentication| rule[ViewSecurityRule]
rule -->|ALLOWED| views[Views /processamentos, /admin]
rule -.->|REJECTED| handler[ViewRejectionHandler]
handler -.-> nega[302 /login · 401 JSON · 503 fail-closed]
O SessionTokenService (JWT da sessão) e o CsrfTokens (CSRF determinístico)
seguem intactos nesta etapa — a migração deles para o micronaut-security-jwt
e micronaut-security-csrf é trabalho subsequente.
Estado atual (2026-08-04): o motor de auth (validador Firebase,
SessionTokenService,CsrfTokens,SessionAuthenticationFetcher, Bearer estático, configauth.*) não é mais caseiro — vem da lib compartilhadabr.com.xadm.comum.seguranca(xadm-seguranca, decisão 0023). Local ficou só a policy de view (ViewSecurityRule/ViewRejectionHandler), oGlobalViewModel, oLoginControllere a whitelist base (ViewWhitelist). Oissdoxadm_sessionvirou config (auth.issuer, defaultbi-transporte-xls).
7. Decisões¶
| Nº | Decisão |
|---|---|
| 0017 | Contrato de erro único {code, message} |
| 0018 | Auth das views no micronaut-security nativo |
| 0019 | Bump major Java 25 + Micronaut 5 |
| 0020 | Serde (build-time) + HTTP declarativo (@Client) |
| 0023 | Adotar a lib xadm-seguranca (motor compartilhado) |
8. Riscos¶
- As mudanças de CI/Docker para Java 25 só se confirmam num run real de CI —
validar no primeiro PR antes do merge em
master. - A migração de auth preserva comportamento, mas é fronteira de segurança: o
AuthIntegrationTesté a rede que prova paridade — não enfraquecê-lo.