Files
Rafael MelgaçoandClaude Opus 5 3149c25238 refactor(automação): a frase de falha do canal mora em lib/channels, não na automação
`lint:channels` reprovou — e estava certo. O mapa de traduções
(`waha_error` → "Não conseguimos falar com o serviço de WhatsApp…") nasceu
dentro de `lib/automation/desfecho-do-envio.ts`, e as chaves CARREGAM NOME DE
TRANSPORTE, que a doutrina de restrição de canal proíbe fora de
`lib/channels/`. A regra não é burocracia: quem ramifica por transporte fora do
seam obriga o canal seguinte a editar N lugares espalhados.

Agora vive em `lib/channels/frases-de-falha.ts` — `fraseDaFalhaDeCanal(codigo)`,
pura, aceitando o código que o adapter publica em `adapter.codes`. Quem chama
nunca precisa saber de quem é o código.

Duas notas do percurso, porque as duas são armadilha:

  * o lint varre o TEXTO INTEIRO do arquivo, comentários inclusive — ele
    reprovou de novo por causa do comentário que EXPLICAVA a regra, citando os
    códigos como exemplo;
  * `motivoLegivel()` sobrou como repasse de uma linha, e o mesmo nome já existe
    em `lib/followup/retorno-crm.ts` com outro significado. Removido: os dois
    call sites chamam o seam direto.

`scripts/seed-e2e-numero-conectado.ts` passou a usar
`credenciaisSupabaseDeTeste()` + `anunciarDestino()`. O gate que cobrava isso
existe porque o modo de falha é silencioso: um seed que escreve na nuvem por
engano acha os mesmos dados de teste de sempre e termina dizendo "pronto".

E o skeleton das abas foi de 306px para 432px — a `TabsList` com QUATRO abas
mede 431,94px (`getBoundingClientRect` em 1440px). 306px era a medida de três
abas, e um skeleton estreito demais faz a página saltar no primeiro paint.

## Estado dos gates

  verify (typecheck+lint+lint:channels+test:unit)  477 arquivos, 5332 testes
                                                   1 arquivo falho, PRÉ-EXISTENTE
  invariants (test:db, Postgres real)              114 arquivos, 855 testes, 0 falhas
  test:shell (o kit self-host)                     verde
  e2e (as duas specs novas, pela tela)             4 passed

O arquivo falho é `lib/ai/dispatcher/rate-limit.test.ts`, e a atribuição foi
MEDIDA nos dois lados, isolado, com a máquina livre:

    referência e815b434 → 5 falhas de 5 (todas com timeout de 15s)
    esta branch e3fa07c0 → 3 falhas de 5

Meu diff não toca `lib/ai/dispatcher/` nem `lib/auth/rate-limit.ts`. A oscilação
(5 → 3 → 2 entre execuções) e os timeouts mostram dependência de temporização —
é um contador de janela fixa, e ele varia com a carga da máquina.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019Rar8AjvB5rzqm8QKWeLMx
2026-08-24 17:13:40 -03:00
..