Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
a609848
fix(financial): o Pix por chave para de exigir conta, e o ISPB vira z…
lekadecastro Sep 5, 2026
99391c3
fix(financial): o pré-voo do Pix passa a checar as duas condições da …
lekadecastro Sep 5, 2026
f868289
Merge pull request #981 from ERP-Bem-Comum/fix/pix-ispb-zeros-e-bloco…
lekadecastro Sep 6, 2026
d443743
Merge branch 'dev' into fix/preflight-pix-key-limits-948
lekadecastro Sep 6, 2026
b1e75db
Merge pull request #982 from ERP-Bem-Comum/fix/preflight-pix-key-limi…
lekadecastro Sep 6, 2026
198aeb8
fix(financial): os campos do cedente no header ganham fonte, e a agên…
lekadecastro Sep 6, 2026
cfc8d47
fix(financial): o DV da agência sobrevive ao UPDATE, e para de ser tr…
lekadecastro Sep 6, 2026
87a1816
Merge pull request #994 from ERP-Bem-Comum/fix/cedente-header-fields-856
lekadecastro Sep 6, 2026
e09d5df
fix(financial): a sequência de NSA passa a ser do convênio, e a conta…
lekadecastro Sep 6, 2026
d8c9a42
fix(financial): o CA3 acha um deadlock na alocação por convênio, e el…
lekadecastro Sep 6, 2026
0063564
test(financial): o backfill da 0057 passa a ser exercitado com dados,…
lekadecastro Sep 6, 2026
a94611e
Merge pull request #997 from ERP-Bem-Comum/fix/nsa-por-convenio-943
lekadecastro Sep 6, 2026
c3d2431
fix(financial): o convênio volta a ser editável na conta encerrada (#…
lekadecastro Sep 6, 2026
c9dc20e
fix(financial): o convênio VAZIO desativa a numeração da conta encerr…
lekadecastro Sep 6, 2026
d35de7e
feat(financial): reabrir e excluir conta-cedente — o encerramento dei…
lekadecastro Sep 6, 2026
dafd2da
Merge pull request #998 from ERP-Bem-Comum/fix/convenio-editavel-cont…
lekadecastro Sep 6, 2026
9694ed1
feat(financial): o saldo de abertura passa a ser editável — o caminho…
lekadecastro Sep 6, 2026
15a1204
Merge pull request #999 from ERP-Bem-Comum/fix/saldo-editavel-995
lekadecastro Sep 6, 2026
3f86864
fix(financial): a chave natural da conta-cedente ganha forma canônica…
lekadecastro Sep 6, 2026
1dd4d45
Merge remote-tracking branch 'origin/dev' into fix/chave-natural-cano…
lekadecastro Sep 6, 2026
2ec3400
fix(financial): quatro achados da revisão do bloco A, e um deles era …
lekadecastro Sep 6, 2026
1a5dede
Merge pull request #1001 from ERP-Bem-Comum/fix/chave-natural-canonic…
lekadecastro Sep 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@
"docs:links": "node --experimental-strip-types --enable-source-maps --no-warnings scripts/handbook/link-scan.ts",
"wiki:sync": "node --experimental-strip-types --enable-source-maps --no-warnings scripts/handbook/wiki-sync.ts",
"cnab:index": "node --experimental-strip-types --enable-source-maps --no-warnings scripts/financial/cnab-manual-index.ts",
"cnab:ispb": "node --experimental-strip-types --enable-source-maps --no-warnings scripts/financial/build-ispb-map.ts",
"logbook": "node --experimental-strip-types --enable-source-maps --no-warnings scripts/claude/logbook.ts",
"release:notes": "node --experimental-strip-types --enable-source-maps --no-warnings scripts/ci/release-notes.ts",
"audit": "pnpm audit --prod --audit-level=high",
Expand Down
5 changes: 5 additions & 0 deletions scripts/ci/test-integration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,11 @@ const SUITES: Readonly<Record<string, Suite>> = {
// Alocação de NSA sob concorrência real: prova que o SELECT ... FOR UPDATE serializa e que dois
// pedidos simultâneos nunca recebem o mesmo número. NSA repetido = retransmissão para o banco.
'tests/modules/financial/adapters/persistence/nsa-allocation.drizzle-mysql.test.ts',
// Backfill da migration 0057 (#943, CA4): a sequência de cada convênio nasce em MAX(next_nsa).
// ⚠️ Existe porque as migrations rodam contra banco VAZIO no `before` de cada arquivo — um
// `INSERT … SELECT` sobre tabela vazia passa sem inserir nada. Em produção ela roda sobre contas
// reais, no job de migration, ANTES de o app subir: falhar ali derruba o deploy.
'tests/modules/financial/adapters/persistence/convenio-nsa-backfill.drizzle-mysql.test.ts',
// Remessa (migration 0044): cabeçalho + vínculos na mesma transação, anti-join de documento
// preso no BANCO, e os UNIQUEs de NSA-por-conta e nome de arquivo.
'tests/modules/financial/adapters/persistence/remittance-repository.drizzle-mysql.test.ts',
Expand Down
26 changes: 23 additions & 3 deletions scripts/etl/financial/mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

import { type Result, ok, err } from '#src/shared/primitives/result.ts';
import type { DocumentType, PaymentMethod } from '#src/modules/financial/domain/document/types.ts';
import { splitCheckDigit } from '#src/modules/financial/domain/payout/payee-account.ts';
import type { LegacyAccountRow, LegacyPayableRow } from '../legacy/rows.ts';
import type { QuarantineReason } from '../quarantine/reason.ts';
import { EXCLUDED_PAYABLE_LEGACY_IDS } from './exclusions.ts';
Expand All @@ -28,6 +29,8 @@ export type CedenteAccountPlan = Readonly<{
input: Readonly<{
bankCode: string;
agency: string;
// #856 — o DV da agência, separado do número. Ausente quando o legado não trazia separador.
agencyDigit?: string;
accountNumber: string;
accountDigit: string;
convenio: string;
Expand All @@ -54,15 +57,32 @@ export const mapLegacyAccountRow = (
errors.push({ tag: 'EnumUnknown', field: 'bank', attempted: row.bank });
}

// F7: a agência legada vem com o DV EMBUTIDO, no formato `NNNN-D`.
//
// ⚠️ ELA ERA GRAVADA INTEIRA, e isso corrompia toda remessa daquela conta em silêncio (#856). O
// emissor escreve `digits(agency, 5)`, que faz `replace(/\D/g,'')` antes do pad: `1234-5` virava
// `12345` nas posições 053-057, onde o banco espera `01234`. Cinco dígitos, cabe no campo, nenhum
// gate acusa — e o arquivo vai ao banco apontando outra agência. O comentário anterior dizia que o
// dígito ia "no campo próprio"; não ia, porque campo próprio não existia. Agora existe.
//
// A decomposição é `splitCheckDigit`, do domínio — a MESMA que lê a conta do favorecido. Uma
// segunda gramática aqui divergiria da de lá no dia em que uma das duas mudasse.
// ⚠️ O QUE NÃO DECOMPÕE NÃO VAI PARA QUARENTENA, e a escolha é a lição da #879. A conta-cedente
// serve à CONCILIAÇÃO sem agência válida; barrar a migração por um campo que só a remessa exige
// repetiria o beco do `'LEGADO'` — conta ausente do sistema, sem via de correção pela tela. Segue
// como veio, e quem recusa é `checkCedenteAgency` na hora de gerar, com lacuna nomeada, mensagem
// PT-BR dizendo onde corrigir, e ANTES de queimar NSA.
const agencyParts = splitCheckDigit(row.agency.trim());

if (errors.length > 0 || bankCode === undefined) return err(errors);

return ok({
legacyId: row.id,
input: {
bankCode,
// F7: agência legada vem com DV embutido ('0288-7') E dv separado — preservamos
// a agência como veio (domínio só exige não-blank) e o dv no campo próprio.
agency: row.agency,
agency: agencyParts?.base ?? row.agency,
// `null` é "o legado não trouxe DV", e vira ausência — nunca `'0'`, que é um dígito afirmado.
...(agencyParts?.digit != null ? { agencyDigit: agencyParts.digit } : {}),
accountNumber: row.accountNumber,
accountDigit: row.dv,
// D6: o convênio real do Bradesco não existe no legado, e o correto é nascer VAZIO.
Expand Down
166 changes: 0 additions & 166 deletions scripts/financial/build-ispb-map.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,8 @@ const translateErrorFor = (error: RemittanceFileError): CnabTranslateError => {
// no campo — não "falhou a tradução" (#838).
case 'pix-key-unrepresentable':
return 'cnab-pix-key-unrepresentable';
// Os dois erros de TRADUÇÃO da rota Pix. Sobem nomeados pela mesma régua: um manda ao cadastro
// (ou à fonte do Bacen), o outro diz que o tipo da chave não existe no domínio do layout.
case 'payee-ispb-unknown':
return 'cnab-payee-ispb-unknown';
// O erro de TRADUÇÃO da rota Pix, que sobe nomeado: diz que o tipo da chave não existe no
// domínio do layout. Eram dois até a #923 — o `payee-ispb-unknown` saiu com a tabela de-para.
case 'remittance-pix-key-type-unsupported':
return 'cnab-pix-key-type-unsupported';
// `remittance-mixed-file-modalities` converge para o desfecho genérico, e é escolha, não
Expand Down
Loading
Loading