Skip to content

chore(release): integra a dev na main — DV da agência do favorecido (#1008) - #1009

Merged
GabrielAderaldo merged 4 commits into
mainfrom
dev
Sep 8, 2026
Merged

GabrielAderaldo merged 4 commits into
mainfrom
dev

Conversation

@GabrielAderaldo

Copy link
Copy Markdown
Contributor

O que entra

Integração da dev na main. São 3 commits, todos da frente do dígito verificador da agência do favorecido (PR #1008, já mergeada na dev):

Superfície tocada

Arquivo Natureza
src/modules/financial/domain/payout/account-check-digit.ts novo — cálculo do DV
src/modules/financial/domain/payout/payee-account.ts validação passa a usar o cálculo
tests/.../account-check-digit.test.ts novo
tests/.../payout-readiness.test.ts, payee-account-properties.test.ts, bank-code-extraction.test.ts, preview-remittance.test.ts ajuste ao novo contrato

324 inserções, 40 remoções, 7 arquivos — domínio e testes apenas. Sem migration, sem mudança de env, sem infra.

Observação sobre a topologia

git merge-base --is-ancestor origin/main origin/dev acusa divergência, mas os 4 commits que a main tem a mais são os merge commits das PRs dev→main anteriores (#1005, #1002, #978, #886) — conteúdo já presente na dev. Não há diff de conteúdo na direção main → dev.

GabrielAderaldo and others added 3 commits September 8, 2026 12:53
…or cálculo

O Validador Universal recusou a remessa de 08/09/2026 apontando as colunas
024-028 do segmento A — a agência —, e nunca a posição do DV, que estava em
branco. O pré-voo aprovava porque conferia a agência só por FORMA: cinco
dígitos cabem em cinco posições, e era tudo o que se perguntava.

O manual 4008-523-0096 v16 (p. 30) abre a seção do cálculo com "Agência
Bradesco: Módulo 11 Universal, com pesos 2 a 7" e exemplifica com a AGÊNCIA;
só depois estende o critério à conta. O algoritmo sempre foi dos dois campos —
a #734 implementou o consumidor da conta, e o nome da função ficou por ela.

`verifyAgencyCheckDigit` delega ao mesmo núcleo em vez de copiá-lo, e
`agencyHasEmbeddedCheckDigit` prova por aritmética o campo que traz o dígito
colado no número. Nenhuma das duas decompõe: saber que `12343` é `1234-3` não
autoriza escrever a agência derivada na posição 024-028 — um dígito errado ali
não falha o arquivo, paga a conta de outra pessoa. O que elas produzem é lacuna
nomeada, e a decisão volta a quem tem a informação.

O DV AUSENTE segue aceito. G009 o declara "Campo Não Obrigatório – Informação
Opcional", e o laudo confirma pelo silêncio: nunca apontou a posição do DV.

Quatro fixtures traziam `1234-5`, e o `5` nunca foi o dígito de `1234` — a mesma
classe de defeito que chegou ao banco, morando na suíte. O comentário de
`bank-code-extraction.test.ts` já previa isto para a conta; faltava a agência
entrar na régua.

Escopo deliberado: só o favorecido. O DV do cedente é a #816, que a #819 pede
para não entregar sozinha — juntas elas encalham o operador entre uma remessa
recusada e um cadastro travado por histórico.

Refs #816
Refs #820

Assisted-by: claude-code:claude-opus-5
…hida com zeros

Achado do code-review, e o defeito era pior que o que a mudança corrigia.

`readAgency` passava `agency` — o valor já com `padStart(5, '0')` — ao
`agencyHasEmbeddedCheckDigit`. Como o argumento chegava sempre com cinco
caracteres, a guarda de largura do detector nunca disparava pelo caminho de
produção, e uma agência legítima de quatro dígitos `abcd` era lida como
`0abc` + `d`. Sempre que `DV('0abc') === d`, era recusada: 900 das 9000
agências de quatro dígitos, uma em cada dez, com `1007` e `1236` entre elas.

E a recusa era a pior possível. A correção que a lacuna sugere ao operador é
separar `1236` em `123-6` — que escreveria `00123` nas posições 024-028. Ou
seja: o gate recusava cadastro correto e ensinava a corromper o destino do
pagamento, que é exatamente o modo de falha descrito no cabeçalho deste
arquivo como a razão de nada aqui decompor por conta própria.

A suíte ficou verde sobre o defeito porque as duas guardas que o pegariam eram
exercitadas de formas incompatíveis: o teste unitário chamava o detector SEM
padding, caminho que a produção nunca toma, e os três valores do loop de
regressão (`1234`, `0920`, `12345`) não pertencem à classe do falso positivo.
Ambos agora carregam `1236` e `1007`, e há um caso que entra pela régua real
para provar que a guarda de largura está viva em produção — não só na chamada
direta. Prova invertida: com o argumento errado de volta, os dois reprovam.

Corrigido também o comentário que afirmava que "os dois defeitos que a recusa
de 08/09/2026 expôs passam a ser vistos antes do banco". Só os do favorecido
são. A agência do cedente, apontada no mesmo laudo nas colunas 053-057 dos três
headers, segue validada apenas por forma — é a #1006, fora deste diff por causa
da #819. Registro que afirma mais do que o código faz é o defeito que o
CLAUDE.md nomeia, e estava sendo introduzido aqui.

Refs #816
Refs #1006

Assisted-by: claude-code:claude-opus-5
fix(financial): o DV da agência do favorecido passa a ser conferido por cálculo
Copilot AI lite review requested due to automatic review settings September 8, 2026 16:33

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@GabrielAderaldo
GabrielAderaldo merged commit e5faba7 into main Sep 8, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants