# Plano de execução: Dark mode/cores, layout, i18n e fluxos ICOM ida/volta (PIX)

Data: 2026-07-03. Autor: sessão Claude (handoff). Estado: PLANEJADO, nada executado.
Fonte: 3 auditorias read-only aterradas em arquivo:linha (inventários no corpo deste plano).
Regras: BACEN é verdade, zero inferência, provar empiricamente; validar tela com screenshot (regra #11); pt-br sem travessão; deploy manual arm64.

## Contexto que trava/afeta a execução

- **HSM RTM caído desde ~2026-07-03 20:22** (504/timeout). Assinatura de saída (pacs.008 etc.) fica fail-closed. NÃO bloqueia trabalho de frontend/i18n nem escrita de código backend; **bloqueia validação viva de envio/retorno real**. Detalhe: memória `monetarie-pix-crypto-hsm-vs-mtls`.
- Deploy HML atual: pix-api task-def :112; pix-admin-ui :10 (conferir digest).

---

## Workstream A — Dark mode / cores hardcoded (frontend)

Base: auditor de cores/layout. O tema é por classe `.dark` (owner `stores/settings.ts:82-91`), com um "shim" de compatibilidade em `src/style.css:170-292` que remapeia com `!important` as famílias comuns. **O trabalho é quase todo CENTRAL no `style.css`, não nos 110 arquivos.** Não sair trocando classe a classe: fechar os GAPS do shim.

- **A0 [P0] — fechar gaps do shim em `src/style.css` (bloco análogo a 247-292):**
  - Remapear BORDAS coloridas `border-*-200/300` no `:root.dark` (~240 ocorrências): green/emerald/amber/yellow/red/rose/blue/sky/indigo/purple/teal/cyan/orange. É a raiz do "status quebrado" (anel claro em volta das badges).
  - Separar `orange` do bucket `purple` (`style.css:283-292`): hoje o chip "Envio" (OUTBOUND, `TransactionListView.vue:60-63` `text-orange-700/bg-orange-50`) vira ROXO no dark.
  - Adicionar as famílias `cyan`/`lime` (100% ausentes do shim; 7 locais: MessageTimeline:62, ParticipantDetailView:177, accounting/NettingCyclesView:151, participants/ParticipantOperationsView:137/140, sessions/SessionListView:126, med/FundsRecoveryListView:191).
  - Remapear texto colorido `text-*-400/-500` (~156; shim só faz 600/700/800): red-400/500(75), green-400/500(31), blue-400/500(19), amber-400/yellow-500(22).
  - **Aceite:** abrir Transações PIX no dark e conferir por screenshot que as badges de status e o chip de direção estão sem anel claro e com cor semântica correta (Envio ≠ roxo).
- **A1 [P1]** — texto claro não remapeado `text-gray-300`(88)/slate-300(9)/gray-200(3) → `--color-text-muted`; fundos `bg-*-200`(5) → `--color-bg-*`.
- **A2 [P2]** — decidir estratégia única. Hoje convivem 495 `dark:` manuais em ~20 arquivos (Button, StatusTabs, DictReportsView, SystemHealthView, SettingsView, accounting/*, participants/*) com o shim global; o `!important` do shim VENCE o `dark:` do autor. Documentar o padrão canônico (recomendado: tokens `[var(--color-*)]` + classes `.badge/.card`, já com 218 usos) e migrar os 20 arquivos aos poucos. Corrigir o comentário falso em `style.css:180-181`.
- **Não fazer:** trocar os milhares de `bg-white`/`text-gray-900` (já cobertos pelo shim, não quebram).

## Workstream B — Layout

- **B1 [P1]** `src/views/dict/DictReportsView.vue`: envolver as tabelas `:114/:143/:172` em `overflow-x-auto` (só `:91` tem) e alinhar `dark:divide-*` (inconsistente).
- **B2 [P2]** `TransactionListView.vue`: badge de status é `<span>` inline simples (`:386-391`); dar `inline-flex items-center whitespace-nowrap` como o chip de direção (`:377-383`).
- **B3** valida após A0 (os anéis claros das badges/cards de alerta somem centralmente).

## Workstream C — i18n

Base: auditor i18n. Setup: `main.ts:43-54`, merge de cada locale POR CIMA de pt-BR (`main.ts:18-40`) → locales secundários herdam tudo; chaves ausentes renderizam em PT (não quebram). `@` já 100% escapado (NÃO mexer).

- **C1 [P1] — extrair strings hardcoded pt-br para `t()`** (~180 em 28 arquivos; piso). Ordem por concentração: `security/SecuritySettingsView.vue`(44, só 1 t()), `security/UserListView.vue`(25), `security/UserFormView.vue`(21), depois monitors/TariffMonitor(10), ParticipantDetailView(8), dict/StatisticsView(8), monitors/FileMonitor(8), security/MfaSetup(8). security/* concentra ~53%. Para cada string: criar chave em `pt-BR.json` + espelhar nos 4 locales. **Aceite:** grep de texto pt-br visível fora de `t()` no arquivo = 0.
- **C2 [P2] — cobrir chaves faltantes** (en 2948, es/fr/zh 2976 de 4002, ~74%). 27 namespaces ausentes por inteiro nos 4: transactions(319), balance(298), keys(108), reda(91), camt060(62), qrcodes(62), statements(53), systemHealth(53), certificates(52), claims(46), sync(42), apiClients(33), automation(30), etc. Como o merge evita quebra, priorizar por tráfego: **transactions, balance, keys, reda, camt060, qrcodes** primeiro. Traduzir de verdade (não copiar PT). É esforço grande: fatiar por namespace e validar por tela.
- **Não fazer:** mexer em `@` (higiene já correta).

## Workstream D — Fluxos ICOM ida/volta

Base: auditor de fluxos. **Já wired (não mexer, só confirmar por teste):** pacs.008→pacs.002 (e2e, `inbound_processor.ex:1576/2554`), reda.014/022/031→reda.016 (OrgnlBizInstr/MsgId, `:1367/1444`), reda.*→admi.002 (RltdRef→bacen_outbound hop, `:1236/1264`), admi.002→original (RltdRef→`find_correlated_transaction:2554`→`status_updater.handle_rejection:254`).

- **D1 [P1] — pacs.004 de SAÍDA sem tracking/correlação.** A devolução que enviamos não cria linha em `monetarie_spi.messages` nem propaga `transaction_id` (`return_processor.ex:168-215`); a pacs.002 que a confirma casa pelo e2e do pagamento ORIGINAL, não da devolução. Conserto: criar/vincular registro da devolução (RtrId/e2e) em `queue_outbound_return/3` e tratar no `process_status_report/2`. Aterrar o comportamento esperado em `mwbank/LegadoPIX`.
- **D2 [P1] — camt.052 sem handler** (cai em `process_generic`, é volta possível da camt.060). Adicionar cláusula `"camt.052"` em `inbound_processor.ex:170-187` espelhando `process_eod_statement:1733`.
- **D3 [P1] — camt.060→camt.053/052 sem correlação req↔resp** (aplica só por ISPB, `:1713/1763`). Persistir um id de requisição na camt.060 (`camt060.ex`) e casar em `process_eod_statement`. Casa com a queixa antiga "camt.060 enviada sem camt.053 casada".
- **D4 [P3] — pibr.001→pibr.002 sem correlação** (`process_echo_response:2056` só audita). Baixa: echo real é HTTP síncrono (`spi_client.ex:522`).
- **D5 — duplo builder camt.060/pibr.001**: `message_builder.ex:702/997` vs envio real inline `spi_client.ex:449/522`. Risco de divergência de versão/namespace. Unificar ou documentar qual é canônico.
- **D6 — pacs.004 ENTRANTE não emite pacs.002 de volta** (assimetria vs pacs.008 entrante, `inbound_processor.ex:1036`). Confirmar contra LegadoPIX se o BACEN espera pacs.002 na devolução recebida.
- **Validação:** cada correção precisa de prova viva (enviar + ler retorno). Envio real depende do HSM de volta; enquanto isso, testar contra o simulador ou reter para pós-recuperação do HSM.

---

## Sequenciamento sugerido

1. **Onda F (frontend, independe do HSM):** A0 → B1/B2 → A1 → C1 (security/*) → validar por screenshot no dark → deploy pix-admin-ui.
2. **Onda B (backend flows):** D2 → D1 → D3 → D5/D6 → D4. Escrever com testes; validar vivo quando o HSM voltar (ou via simulador).
3. **Onda T (tradução):** C2 por namespace priorizado.
4. A cada mudança de UI: build arm64 → deploy → screenshot (regra #11). A cada mudança de fluxo: teste + prova viva.

## Dependências externas / fora de escopo

- **HSM RTM** precisa voltar (RTM) para validar envio/retorno real.
- **CPIC mTLS → HSM** (tirar chave privada do disco/Secrets via PKCS#11 da RTM ou `sign_fun` do OTP) é trilha de governança separada; memória `monetarie-pix-crypto-hsm-vs-mtls`.

## Critério de "pronto" (por item)

Nenhum item conta como entregue sem: (a) o conserto no código citado por arquivo:linha; (b) para UI, screenshot no dark E light sem erro do validador; (c) para fluxo, prova viva do par ida/volta (ou simulador se HSM caído), com o status correto no banco. Sem isso, fica "em andamento", nunca "entregue".
