Repository navigation
feat(partners): fornecedor pessoa física (CPF) — SupplierDocument, PF sem Razão Social/Nome Fantasia - #1025
Conversation
… sem razão social Fecha #1022. O cadastro de Fornecedor aceita pessoa física (CPF), pagos por RPA. - Domínio: `SupplierDocument` (CPF | CNPJ, no módulo, não no kernel) e identidade PF × PJ como union discriminada — na PF razão social e nome fantasia não existem no tipo. O tipo de pessoa é derivado do documento, nunca gravado. PF com os campos preenchidos é recusada (`supplier-*-not-allowed-for-pf`); branco conta como ausente. - Persistência: migration 0020 (`cnpj` → `document`, índice `par_suppliers_document_idx`, `corporate_name`/`fantasy_name` nullable com CHECK amarrado ao tamanho do documento). Ausência é NULL só na borda; sem valor sentinela (ADR-0070). - HTTP v1 aditivo: `document` + `personType`; `cnpj` segue como alias deprecated por um ciclo, na entrada e na resposta. Códigos `invalid-supplier-document` e `*-document-duplicate`. - Busca por CPF, CSV "CPF/CNPJ", leitura de nota resolve CPF (`findSupplierIdByDocument`), ETL aceita CPF na coluna legada. - Testes de favorecido CPF no CNAB (transferência, J-52, Pix); sem mudança de código lá. - ADR-0070 supersede parcialmente o ADR-0031. Assisted-by: Claude-Code:claude-opus-5-5
Os 20 comandos de hook do `.claude/settings.json` eram `${CLAUDE_PROJECT_DIR}/...` sem
aspas: num clone em "Área de trabalho" o `/bin/sh` partia o caminho no espaço e todo hook
falhava como "non-blocking" — Prettier pós-edição, bloqueios de Bash e o gate do Stop
deixavam de rodar em silêncio. Agora `"\"${CLAUDE_PROJECT_DIR}\"/..."`, a forma da doc.
Com os hooks de volta, apareceram mais três defeitos da mesma família:
- `pre-commit-typecheck.sh` guardava `pnpm --dir=${CORE_API_DIR}` numa string e a expandia
sem aspas: os quatro gates do pre-commit morriam com `ENOENT ... lstat '/home/.../Área'`.
Agora a chamada é direta, com `--dir` entre aspas.
- `stop-quality-gate.sh` reportava `pnpm: comando não encontrado` como QUATRO vermelhos.
Shell de hook não carrega o nvm; ausência do pnpm agora é diagnóstico próprio ("gate
não rodou"), que continua bloqueando, mas com a causa verdadeira.
- O fixture do `gate-blocker` montava `typecheck: <caminho do tsc> --noEmit` sem aspas no
package.json temporário; o cenário GREEN falhava por ambiente, não por gate.
Assisted-by: Claude-Code:claude-opus-5-5
- `rehydrate` aplica só a regra do CHECK (PF ⟺ nomes NULL). Exigir nome não-branco na LEITURA derrubava o `list()` inteiro por uma PJ gravada com razão social `''` por fora do domínio — o CHECK aceita, e essa linha sempre reidratou. - Borda: documento só alfanumérico. Só o tamanho deixava um CPF mascarado (14 caracteres) passar como CNPJ sem máscara, enquanto o CNPJ mascarado caía em 400. - ETL: CPF ambíguo (os 11 dígitos com zeros à esquerda também formam CNPJ válido — CNPJ legado que perdeu os zeros) vai para quarentena, não para PF; e documento inválido volta a juntar o erro de razão social na mesma quarentena. - `companyNamesOf` no domínio substitui o mesmo `switch` repetido em DTO, CSV, mapper e busca; tamanhos de CPF/CNPJ têm fonte única em `SupplierDocument`. - Reverte a edição da linha de status do ADR-0031: ADR aceito não se edita; a supersessão fica registrada no ADR-0070. ADR-0070 registra o risco aceito do OCR resolver CPF. - Diagnóstico de duplicatas e textos de teste apontam `par_suppliers.document`. Assisted-by: Claude-Code:claude-opus-5-5
Decisões tomadas e o motivo de cada umaRegistro do que foi decidido nesta entrega, inclusive o que se alinhou com a P.O. A versão normativa está no ADR-0070. 1. Ausência de razão social/nome fantasia: union no domínio e
|
|
Sobre os 4 checks vermelhos de Todo o resto passou: |
…-fisica # Conflicts: # .claude/hooks/stop-quality-gate.sh # handbook/architecture/adr/README.md
Fecha #1022.
O que muda
O cadastro de Fornecedor passa a aceitar pessoa física (CPF), paga por RPA. Na PF, razão social e nome fantasia não existem; na PJ seguem obrigatórios. O cálculo do RPA já existia no Contas a Pagar; esta entrega é só o cadastro.
SupplierDocument(CPF | CNPJ) no módulopartners, e identidade PF × PJ como union discriminada (individual×company). OCnpjdo kernel não muda: Financiador e Acordo continuam recusando CPF.0020renomeiacnpj→document(continuavarchar(14)), cria o índicepar_suppliers_document_idxe tornacorporate_name/fantasy_namenullable. Dois CHECKs amarram o NULL ao tamanho do documento. Sem backfill.document(11 ou 14 caracteres, sem máscara);cnpjaceito como alias deprecated por um ciclo;documentepersonType: 'PF' | 'PJ', com o aliascnpjmantido;corporateName/fantasyNamevêmnullna PF;invalid-supplier-document,*-document-duplicate,supplier-corporate-name-not-allowed-for-pfesupplier-fantasy-name-not-allowed-for-pf.supplier:edit-sensitive.findSupplierIdByDocument);Um commit separado conserta o harness: os hooks não rodavam em clone com espaço no caminho.
Como foi verificado
typecheck,format:check,lintetestverdes, com 11902 testes e 0 falhas.compose.yaml): suíte de integração dopartnerscom 50/50, passando em banco limpo, na repetição sem recriar e em ordem invertida.information_schema:document varchar(14) utf8mb4_bin, o índice novo e os dois CHECKs.3819; PF válida é aceita./code-reviewem nível high, com 7 achados corrigidos e 3 mantidos (ver o comentário de decisões), e/security-reviewsem achados.Pendências fora deste PR
handbook/guidelines/, fora do git) não está nesta máquina; alguém com o PDF deve abrir as p.25, 33, 40, 95, 101 e 108.web-appspec117-fornecedor-pessoa-fisica.