Pular para conteúdo

0015 — Tela de login servida pela lib (adota a central 0032)

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

Contexto

O tradutor tinha src/main/jte/login.jte própria — uma das cinco cópias da frota. As cinco carregavam o mesmo mecanismo de auth (SDK do Firebase 10.13.2, signInWithPopup, POST /login/callback com CSRF double-submit) e divergiam só na moldura: bloco de marca em três delas, título em quatro formatos. Duplicado justamente o que carrega risco; divergente o que é cosmético. Um bug de auth custava cinco PRs.

Este repo mediu o custo na prática: a cópia daqui viera do bi-comercial-xls sem o CSS que a acompanhava — .xadm-login-logo e .xadm-login-tagline estavam definidas no app.css de lá e não existiam aqui, compensadas por style= inline no <img>. A tela "parecia ok"; o markup viajou, o contexto não.

A casa fixou o alvo na ADR central 0032 — Tela de login servida pela lib (constituição 1.4.0), entregue na xadm-seguranca 0.7.1.

Decisão

Adotar a central 0032, sem variação local. Adoção é migração no mesmo PR:

  • Apagada a src/main/jte/login.jte. A view agora vem do jar da lib, sob namespace (xadm/login.jte → …precompiled.xadm.JteloginGenerated); o XadmLoginController renderiza @View("xadm/login"). O namespace não é detalhe: na raiz, a view da lib geraria a mesma FQCN que a de um app, uma sombreando a outra sem erro nem aviso.
  • Cosméticos viram property (LoginViewSettings): xadm.views.login.marca: true e tagline: "Um ERP Completo para sua empresa" — a moldura que este app já usava, agora declarada em vez de escrita em markup. O título é derivado do xadm.views.app-nome ("Login — Webstorm"), que é o que mata os quatro formatos por construção.
  • Apagado o ViewGlobals local: a 0.7.1 faz o XadmViewModel injetar appVersao, com as duas armadilhas (ler a cada render, nunca em static final; tolerar model imutável) resolvidas na lib.
  • Bootstrap deixa de vir do CDN. O kit 1.4.0 vendoriza bootstrap.min.css + bootstrap.bundle.min.js (5.3.8, conferidos contra o hash SRI publicado pelo projeto) em templates/public/**; re-derivamos o kit e os dois arquivos. O SDK do Firebase segue no gstatic, de propósito — vendoriza-se apresentação, não o SDK do provedor de identidade.

Consequências

  • /js/** precisou virar anônimo. O layout passou a linkar /js/bootstrap.bundle.min.js, e as regras de rota deste app — que são dele, não do kit — liberavam /css/** e /images/** mas não /js/**: o bundle respondia 401, inclusive na tela de login, onde por definição não há sessão. Sintoma mudo: página estilizada, JS morto, nada no log. Corrigido nas duas fontes (intercept-url-map do application.yml e ViewWhitelist) e travado por EstaticosDoKitSaoAnonimosTest, que lê o layout.jte real e cobra cada estático linkado nas duas.
  • Acoplamento novo entre repos, sem gate. O markup vem do jar da lib; o CSS que o estiliza (.xadm-login-logo, .xadm-login-tagline) vem do custom-theme.css, template rastreado do central. Dois versionamentos, nada os amarra: tema velho + lib nova renderiza a marca sem estilo, e só o olho pega. Sintoma nomeado pela lib: marca sem estilo = tema desatualizado, re-derive o kit.
  • A tela não usa o kit/layout.jte (emenda da 0032): @template resolve em tempo de geração, então a view empacotada exigiria o kit dentro do build da lib. Ela traz o próprio documento — logo, nome e versão. Custo declarado lá: ~10 linhas de header duplicadas, que podem divergir visualmente do header logado com o tempo.
  • Some o botão "Entrar" redundante no header da tela de login: sem sessão não há chip nem menu, e a view autocontida não os renderiza.

Alternativas descartadas

  • Manter a view local — era o estado que produziu cinco cópias e o CSS órfão descrito acima.
  • Vendorizar o Bootstrap só aqui, editando o kit/layout.jte: o layout é template verbatim, e a edição local seria revertida no próximo re-derive, em silêncio. O caminho certo foi levar ao central, que vendorizou para a frota.