# Revisão 100% do PIX admin e relatório de entrega (2026-07-03)

Mandato do dono: revisar todas as páginas, telas, abas, botões e funcionalidades do
PIX admin (`pixadmin-h.monetarie.internal`), deixar tudo funcionando, sem vazar a
palavra "homologação" ao piloto, e entregar este relatório com as evidências dos
erros encontrados (tela branca, console do navegador) e de todas as correções.
Contexto: no período da tarde o ambiente de produção será preparado.

Estado de entrega: `origin/main` na altura `0f007bfe`; serviço `pix-admin-ui` na
task definition `:17` (imagem `homolog-0f007bfe-20260703`); `pix-api` na `:98`
(imagem `homolog-b3d25d27-20260703`). Todas as mensagens de erro internas de rede,
segredos e detalhes técnicos ficam fora das telas do piloto.

## 1. Como a revisão foi feita

A revisão foi feita ao vivo, tela a tela, com um navegador real logado como
`admin@monetarie.com.br`, percorrendo o menu inteiro do admin. Foram cobertas 96
telas. Cada tela foi aberta, cada chamada de API observada, e cada erro de tela
branca ou de console foi capturado antes de qualquer correção.

Resultado da auditoria inicial: 84 telas já funcionais e 41 itens com problema (1
crítico de tela branca, 9 de prioridade alta, 31 de prioridade média). A maioria
dos defeitos era de frontend (render, tradução, escala de número, tema), não de
rede: quase todas as APIs já respondiam 200. Não havia crash generalizado nem
vazamento de credencial.

Evidências "antes": `docs/reports/screenshots/2026-07-03-pixadmin-audit/`.

## 2. O defeito crítico (tela branca) e sua causa raiz

Telas afetadas: detalhe de participante indireto (`/reda/:id`), parâmetros de saldo
(`/balance/parameters`) e os placeholders das telas MED que usam a chave PIX de
exemplo.

Sintoma no navegador: a tela não renderizava o conteúdo e o console mostrava
`SyntaxError: 10` vindo do compilador de mensagens do vue-i18n (funções
`nextToken`/`parse` do tokenizador), capturado pelo `RouteErrorBoundary`.

Causa raiz provada: no pacote de produção, o vue-i18n remove os textos de erro e
lança apenas o código. O código 10 é `INVALID_LINKED_FORMAT`. As mensagens de
tradução abaixo continham um `@` literal (endereços de email de exemplo). O
vue-i18n interpreta `@` como início de uma mensagem vinculada (`@:chave`) e, ao não
encontrar uma chave válida, aborta a compilação da mensagem no momento do render:

- `balance.parameters.emailPlaceholder = "email@exemplo.com"`
- `reda.form.placeholder.directorEmail = "diretor@empresa.com.br"`
- `reda.form.placeholder.contactEmail = "contato@empresa.com.br"`
- `med.placeholders.pixKey = "CPF / CNPJ / +5511... / email@..."` (aqui o `@.` era
  lido como modificador vinculado vazio)

Correção: escapar o `@` com a interpolação literal do vue-i18n, `{'@'}`, que
renderiza o `@` sem tentar interpretá-lo. Aplicado nos cinco idiomas
(`pt-BR`, `en-US`, `es-ES`, `fr`, `zh-HK`).

Prova objetiva: um teste que compila TODAS as mensagens de tradução com o próprio
vue-i18n foi rodado antes e depois. Antes: 4 mensagens quebravam. Depois: 0
quebras em todos os cinco idiomas. Isso garante que nenhuma outra tela vai cair por
este motivo, em nenhuma língua.

## 3. Correções por onda

### Onda 1 — núcleo funcional (commits `35e20381` front, `d18d426d` backend)

- Blindagem de render: `RouteErrorBoundary` envolvendo o conteúdo das rotas, para
  que uma exceção de uma tela nunca mais deixe a área principal em branco; mostra
  um estado de erro amigável com botões de recarregar e voltar.
- Marcadores de fraude (`/med/fraud-markers`): a API respondia 502; passou a
  responder 200 com estado vazio honesto.
- Simulador (`/simulator`): a API de status respondia 500 quando o simulador estava
  desligado; passou a responder 200 com o estado "desativado".
- Monitor de operações: a taxa de erro de 22% era dominada por chamadas de
  devolução com 400 sistemático; o cliente DICT passou a preencher o participante,
  encerrando o 400.
- Logs de auditoria: as traduções cruas (`audit.eventTypes.*`) e a coluna
  "Resultado" invertida (mostrava "Erro" para tudo) foram corrigidas; o total
  passou a refletir os registros.
- Central de mensagens / Construir Mensagem: o envio dava 403 para todos; corrigido
  com bypass de administrador e mensagens de validação amigáveis (já validado ao
  vivo com HTTP 201 no mandato anterior).
- Monitoramento em tempo real: a página estava em inglês; traduzida.
- Telas de detalhe (reivindicações, infrações) com 404 cru passaram a mostrar
  estado vazio; grupos de segurança ganharam ações de CRUD; mascaramento de PII no
  detalhe de mensagem.
- Backend: métricas do DICT passaram a agregar dados reais; escala do camt.060
  corrigida; saúde de certificados escopada por ISPB.

### Onda 2 — qualidade, tema e 4 telas reais (commit `f0dab9cd`)

- Quatro telas que antes exibiam banner de indisponibilidade foram implementadas de
  verdade, ligadas a endpoints reais: parâmetros legados, estatísticas de mensagens,
  monitor RCO e relatório de tempo de resposta.
- Tema claro/escuro: foi criado o conjunto completo de tokens escuros coerente com
  a marca Monetarie e as duas stores de tema duplicadas foram reconciliadas numa
  única fonte persistente, aplicada no boot. O idioma e o tema agora aplicam e
  persistem entre navegações.
- Cores fixas no código migradas para os tokens de design.

### Onda 3 — legibilidade e acabamento (commits `1e1c070b`, `0f007bfe`)

- Login legível: os campos de login e senha não tinham cor de texto definida e o
  que era digitado ficava quase invisível; adicionada cor de texto e de placeholder.
- Contraste do modo escuro: aproximadamente 4000 utilitários de cor fixos do
  Tailwind (`text-gray-*`, `bg-white`, etc.) ignoravam o tema e produziam texto
  escuro sobre fundo escuro; um shim de compatibilidade remapeia esses utilitários
  para os tokens quando o tema escuro está ativo.
- Saldo da Conta PI no painel: mostrava valor 100 vezes menor porque dividia por
  100 um número que já vinha em reais (posição da camt.053 SADP, que é a verdade do
  BACEN); a divisão foi removida e o valor passou a bater com a tela de CAMT.060.
- Badges coloridos no escuro: os chips verde/amarelo/vermelho/azul apareciam como
  caixa clara sobre card escuro; re-tingidos translúcidos com texto claro.
- Simulador desligado: os cartões mostravam "NaN%" e "NaN Max Trocas/Hora"; os
  formatadores de número e percentual ficaram à prova de valor nulo.

## 4. Decisões do dono aplicadas

- Não mexer em dado de teste: os dados de homologação (chaves de exemplo, registros
  de seed, notas internas nos eventos) permanecem no ambiente de homologação e
  somem quando a produção for semeada do zero. Só o código foi corrigido.
- Implementar de verdade as telas placeholder, em vez de escondê-las.

## 5. Validação ao vivo (regra 11)

Após a estabilização do deploy `:17` (rollout `COMPLETED`, serviço 1/1), cada
correção foi conferida ao vivo no navegador logado, verificando o console do
navegador (0 erros) e o render da tela. O navegador foi forçado a carregar o pacote
novo (`index-GrF8HtdE.js`) após limpar o cache.

| Tela / item | Antes | Depois (validado ao vivo) | Console | Evidência "depois" |
|---|---|---|---|---|
| `/reda/:id` detalhe | Tela branca (error boundary), `SyntaxError: 10` | Renderiza dados, responsáveis e histórico; placeholder `diretor@empresa.com.br` correto | 0 erros | `06-reda-detalhe-DEPOIS.png` |
| `/balance/parameters` | Tela branca, mesma causa | Renderiza os cartões de parâmetros | 0 erros | `07-balance-parameters-DEPOIS.png` |
| `/med/fraud-markers` (Novo marcador) | 502 na lista; formulário derrubava a tela pelo placeholder | Lista com estado vazio honesto; formulário abre com placeholder `email@...` correto | 0 erros | `08-med-novo-marcador-DEPOIS.png` |
| `/simulator` (inativo) | "NaN%" e "NaN Max Trocas/Hora" | "Taxa de Aceitação: —" e "Max Trocas/Hora: 0" | 0 erros | `09-simulador-sem-NaN-DEPOIS.png` |
| Toggle de tema (Configurações) | Alternar não mudava a cor | Botão Escuro aplica a classe `dark` e persiste `theme: dark` em `user-settings` | 0 erros | (persistência conferida por script) |
| Modo escuro `/transactions` | Badge "Envio" como caixa creme sobre card escuro | Pílula violeta translúcida; status vermelho/azul/verde translúcidos, tudo legível | 0 erros | `10-dark-transactions-badge-DEPOIS.png` |

Evidência do defeito crítico antes da correção (tela branca + console):
`docs/reports/screenshots/2026-07-03-pixadmin-audit/reda-1-ERRO-antes.png`.

Prova de que o toggle persiste: após clicar em Escuro, o `localStorage`
`user-settings` guardou `"theme":"dark"` e o `documentElement` recebeu a classe
`dark`; ao navegar entre telas a preferência se mantém.

Login legível, contraste do modo escuro e saldo do painel batendo com o CAMT.060
já haviam sido validados ao vivo no deploy anterior (`:16`), com evidências em
`01-login-texto-legivel.png`, `02-dark-dashboard.png`, `03b-dark-transactions.png`,
`04-dashboard-saldo.png` e `05-camt060-saldo.png`.

## 6. Itens sem impacto no piloto e acompanhamento

- Os textos de exemplo de valor com barra vertical (`|`) em alguns hints renderizam
  corretamente na versão atual do vue-i18n (verificado ao vivo no rodapé); sem ação.
- Vazamentos residuais da palavra "homologação" em dados de teste desaparecem no
  seed de produção (decisão do dono de não mexer em dado).
