Skip to content

[tests] 44 fixtures declaram agência com DV que não fecha o módulo 11 — a suíte descreve cadastro que o banco recusa #1007

Description

@GabrielAderaldo

🎯 Problema (uma frase, sem ambiguidade)

44 ocorrências em 35 arquivos declaram agência no formato NNNN-D cujo dígito não fecha o módulo 11 do
banco, de modo que a suíte descreve, como cadastro válido, um cadastro que o banco recusaria — e só não falha
porque quase todas usam bancos cujo algoritmo não está no acervo.

📍 Localização

Medido por varredura sobre git grep -nE "agency: *.[0-9]{1,5}-[0-9Pp]", com o DV recalculado pelo algoritmo do
manual (p. 30). Distribuição:

Agência declarada DV correto Ocorrências Banco predominante
0001-2 9 30 001
1234-5 3 11 341 / sem banco
1234-1 3 2 —
01234-5 3 1 cedente

Concentração: tests/modules/partners/** (24 arquivos, todas 0001-2 com banco 001),
tests/modules/contracts/adapters/http/** (2), tests/modules/financial/** (o restante),
tests/etl/financial/mapper.test.ts:73.

⚠️ Uma das 44 é deliberadamente inválida e deve permanecer: o caso de check-digit-mismatch em
tests/modules/financial/domain/payout/payout-readiness.test.ts, cuja matéria É o dígito não fechar. Ela tem
comentário dizendo isso. Quem for corrigir em massa precisa distinguir — ver o último item da DoD.

🔍 Atual vs. Esperado

Descrição
Hoje (atual) O dígito da fixture é decorativo. Verde não significa "este cadastro seria aceito" — significa "o banco desta fixture não é conferível".
Esperado Fixture que se declara um cadastro completo carrega dígito aritmeticamente correto, como já vale para a conta desde a #734.

🧠 Por quê (causa-raiz + impacto)

  • Causa-raiz: até a [financial] 🏦 O campo DV pode guardar o dígito da agência em vez do da conta — indício estatístico em 44 de 86 cadastros #734 nada calculava dígito, então qualquer valor servia; a [financial] 🏦 O campo DV pode guardar o dígito da agência em vez do da conta — indício estatístico em 44 de 86 cadastros #734 corrigiu as fixtures da
    conta e não tocou nas da agência, porque a agência ainda não era conferida. É o padrão "a régua certa
    não se propaga sozinha": existe num campo e falta no irmão.
  • Evidência de que o risco é real, não hipotético: ao ligar a verificação da agência do favorecido
    (fix/dv-agencia-favorecido), quatro fixtures de banco 237 quebraram de uma vez, em quatro arquivos —
    payout-readiness, payee-account-properties, bank-code-extraction e preview-remittance (corrigidas naquele
    PR). As restantes sobreviveram só porque seus bancos devolvem not-verifiable. O comentário de
    tests/modules/financial/domain/payout/bank-code-extraction.test.ts:30-31 já previa exatamente esse modo de
    falha — para a conta.
  • Impacto: duplo, e nenhum dos dois é urgente. (a) No dia em que o acervo ganhar o algoritmo de outro
    banco — 001 é o candidato óbvio, é o mais usado nas fixtures —, dezenas de testes ficam vermelhos de uma vez,
    por um motivo que não é o deles, e o vermelho aparece longe da mudança. (b) Enquanto isso, a suíte documenta
    como "cadastro bancário completo" uma forma que o Bradesco recusa, o que ensina o padrão errado a quem copia a
    fixture para um teste novo.
  • Regra/princípio violado: nenhuma regra escrita. É débito de fixture, e o critério é o do próprio
    repositório: fixture com DV inventado descreve um cadastro que o banco recusa
    (payout-readiness.test.ts:45-48, comentário já existente sobre a conta).

🔁 Reprodução / evidência

git grep -nE "agency: *.[0-9]{1,5}-[0-9Pp]" -- 'tests/**' 'src/**' 'scripts/**' \
  | node -e 'let s="";process.stdin.on("data",d=>s+=d).on("end",()=>{
      const dv=a=>{let t=0;for(let i=0;i<a.length;i++)t+=+a[i]*(2+((a.length-1-i)%6));
        const r=t%11;return r===0?["0"]:r===1?["0","P"]:[String(11-r)];};
      for(const l of s.split("\n")){const m=/agency: *.([0-9]{1,5})-([0-9Pp])/.exec(l);
        if(m&&!dv(m[1]).includes(m[2].toUpperCase()))console.log(l.trim(),"-> esperado",dv(m[1]).join("|"));}});'

Hoje devolve 44 linhas. O critério de pronto é ele devolver só a linha deliberada — e o teste do CA2 abaixo é
o que impede a lista de voltar a crescer.

✅ Critérios de aceite (testáveis)

  • CA1 — Dado a varredura acima, Quando rodada sobre tests/, src/ e scripts/, Então devolve
    zero linhas. Cada fixture passa a declarar o DV que o algoritmo produz para a base
    (0001 → 9, 1234 → 3).
  • CA2 — Dado uma fixture nova com agência NNNN-D cujo dígito não fecha, Quando o gate roda, Então
    um teste de tests/cleanup/ a acusa por propriedade — nunca por contagem, que envelheceria a cada
    fixture nova. O teste precisa da guarda contra verde por vacuidade: provar que a varredura enxerga ao menos
    uma agência: o grep que decide é o que volta vazio sobre um universo não-vazio.
  • CA3 — Dado o CA2 em vigor, Quando alguém escreve uma fixture com DV correto num banco fora do
    acervo, Então é aceita — o gate confere aritmética onde ela é conhecida, e não inventa algoritmo para
    banco que não tem um.
  • CA4 — nenhum valor de agência ou conta vem de cadastro real. Todos sintéticos, com o dígito calculado
    (CLAUDE.md, anti-padrão 9 — os três repositórios são públicos).

🧪 Definition of Done

  • Gate verde: pnpm run typecheck + pnpm run format:check + pnpm run lint + pnpm test.
  • Sem regressão — contagem de testes ≥ baseline; nenhum teste afrouxado para acomodar a mudança de fixture.
  • ⚠️ Trocar o dígito de uma fixture não pode alterar o que o teste mede. Onde a fixture existe justamente
    para ser inválida (ex.: o caso de check-digit-mismatch), o valor permanece — e ganha comentário
    dizendo que a invalidez é deliberada, para que o CA2 não o "conserte" depois.

🏷️ Classificação

  • Tipo: debito-tecnico
  • Severidade: baixa — nada quebra hoje; o custo é um vermelho em massa no futuro e um padrão errado sendo
    copiado enquanto isso.
  • Tamanho estimado: M (mecânico, mas espalhado por ~35 arquivos e 3 módulos)
  • dedup-key: tests:fixtures:agency-check-digit-invalid

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions