Pular para conteúdo

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.application 5. Dockerfile e CI passam a temurin: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, config auth.*) não é mais caseiro — vem da lib compartilhada br.com.xadm.comum.seguranca (xadm-seguranca, decisão 0023). Local ficou só a policy de view (ViewSecurityRule/ViewRejectionHandler), o GlobalViewModel, o LoginController e a whitelist base (ViewWhitelist). O iss do xadm_session virou config (auth.issuer, default bi-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.