@77sol-ui/form-schemas
v1.0.0
Published
Fonte central de schemas Zod da 77 (source-only). Financiamento (PF) é o primeiro domínio; consumido direto do código-fonte pelo backend e frontend.
Maintainers
Keywords
Readme
@77sol/form-schemas
Repositório central de schemas (Zod) da 77. Cada domínio de formulário mora em sua própria camada; o primeiro domínio é o de financiamento, e a camada shared/ reúne primitivos reutilizáveis (regex/validadores de formato, primitivos de campo Zod e enums comuns) — agnósticos a domínio.
O domínio de financiamento define, por banco, uma ficha PF (pessoa física) e uma ficha PJ (pessoa jurídica). Cada banco são dois arquivos próprios em schemas/: <Banco>PFSchema.ts (ficha PF) e <Banco>PJSchema.ts (ficha PJ), ambos com o shape declarado explicitamente (z.object({...}).strict()) — você abre o arquivo e lê os campos do banco direto, sem build dinâmico nem catálogo. Consumido tanto pelo backend (api-v3, validação no submit) quanto pelo frontend (validação on blur) — sem endpoint intermediário.
Contexto: USI-4045.
Import (subpath por banco)
Cada banco é self-contained: os arquivos <Banco>PFSchema.ts/<Banco>PJSchema.ts
ficam disponíveis individualmente via o subpath export com wildcard
./financing/formalization/schemas/*. Não há mais registry agregado nem mapas
centrais — você importa diretamente o arquivo do banco:
import { bvPfSchema } from '@77sol/form-schemas/financing/formalization/schemas/BvPFSchema'
import { bvPjSchema } from '@77sol/form-schemas/financing/formalization/schemas/BvPJSchema'
import { santanderPjSchema } from '@77sol/form-schemas/financing/formalization/schemas/SantanderPJSchema'
import { credito77PfSchema } from '@77sol/form-schemas/financing/formalization/schemas/Credito77PFSchema'O nome do arquivo é PascalCase do slug (bv→Bv, banco-do-brasil→BancoDoBrasil,
cash-me→CashMe, credito77→Credito77, hdt-energy→HdtEnergy, sol-agora→SolAgora);
o nome do export continua camelCase (bvPfSchema, bancoDoBrasilPjSchema, …).
Uso
A validação roda igual no front (on blur/submit) e no back (no submit), a partir do
mesmo schema. Importe o arquivo do banco e use .parse()/.safeParse():
import { bvPfSchema } from '@77sol/form-schemas/financing/formalization/schemas/BvPFSchema'
import { santanderPjSchema } from '@77sol/form-schemas/financing/formalization/schemas/SantanderPJSchema'
const result = bvPfSchema.safeParse(payloadPf)
if (!result.success) {
console.log(result.error.issues) // → 400 no back / feedback no front
}
santanderPjSchema.parse(payloadPj) // empresa + avalista[]Cada arquivo também exporta o tipo inferido correspondente (BvPfFicha,
SantanderPjFicha, …). Como o shape é declarado explicitamente, z.infer produz
tipos precisos por campo.
Como não há mais um mapa central, quem precisa escolher o schema dinamicamente pelo slug monta o próprio mapa local importando só os bancos que usa.
Bancos disponíveis (slug): credito77, losango, santander, btg, bv,
banco-do-brasil, caixa-economica-federal, alfa, safra, cash_me_,
hdt_energy, solfacil, sol_agora, eos.
Estrutura
src/
shared/ # infra interna agnóstica a domínio (não exportada)
regex/ # patterns + validators (CPF/CNPJ/cpfCnpj, datas) + field schemas de formato
fields/ # primitivos de campo Zod (textField, numberField, integerField, fileUploadField…)
enums/ # enums reutilizáveis (tipo_documento, sexo, nacionalidade)
domains/
financing/
enums/ # bancos (BANK_SLUGS/BankEnum) + ocupações
formalization/
extras.ts # campos da formalização comuns (uploads, vínculo, seguro RD/RE)
refinements.ts # applyPfRefinements / applyPjRefinements (RN-011/012 + nacionalidade→RNE)
schemas/ # DOIS ARQUIVOS ACHATADOS POR BANCO, shape explícito — sem index/barril
BvPFSchema.ts # ficha PF do BV (bvPfSchema)
BvPJSchema.ts # ficha PJ do BV (bvPjSchema)
SantanderPFSchema.ts # … um par PF/PJ por banco
… # (14 bancos = 28 arquivos achatados)
index.ts # barrel do escopo (só BANK_SLUGS/BankEnum/tipos — NÃO os schemas)
index.ts
index.ts # API pública rootCada arquivo de banco é independente: <Banco>PFSchema.ts e <Banco>PJSchema.ts
importam os primitivos de shared/, os campos comuns de extras.ts e os refinements de
refinements.ts, e declaram o z.object({...}) de PF e de PJ. Sem gerador, sem catálogo
de dados, sem builder e sem registry agregado: cada arquivo é exposto direto pelo
subpath export ./financing/formalization/schemas/*.
Manutenção
A manutenção é manual e local aos arquivos do banco — edite o shape direto em
schemas/<Banco>PFSchema.ts (PF) ou schemas/<Banco>PJSchema.ts (PJ).
- Mudar campos de um banco: abra
schemas/<Banco>PFSchema.tsouschemas/<Banco>PJSchema.tse edite oz.object({...})(adicione/remova chaves, troque o schema de formato, marque.optional()). - Regra de formato/primitivo:
shared/regex(CPF/CNPJ/datas…) oushared/fields/primitives(textField,numberField,integerField). - Campos comuns da formalização (uploads, vínculo, seguro):
extras.ts. - Regra cross-field (RN):
refinements.ts.
Adicionar um banco
Regra do pacote: cada banco são dois arquivos de schema próprios (achatados em schemas/). O passo a passo
está na skill adicionar-banco-financing (.claude/skills/). Em resumo:
- Crie
schemas/<Banco>PFSchema.tseschemas/<Banco>PJSchema.ts(shape explícito). - (Opcional) adicione o
slugemBANK_SLUGS(enums/banks.ts) só se quiser o banco listado no enum — os schemas não dependem mais dele. yarn check:fix && yarn typecheck.
Teste de schema é dispensado por enquanto — não crie
.spec.tspor banco.
Não há registry para registrar: os arquivos ficam disponíveis automaticamente via o subpath export
./financing/formalization/schemas/*, sem fiação central.
Regras de negócio materializadas
Aplicadas via .superRefine(...) em cada banco; os campos usam os nomes definidos no schema.
| RN | Onde |
| -- | -- |
| RN-011 (RG ≤ 10 anos) | refinements.ts (type_doc='rg' + doc_issue_date) · CNH "não vencida" → TODO (dado ausente) |
| RN-012 (CNPJ por ocupação) | refinements.ts (nature_of_occupation + cnpj_proprietary; presentes só onde o banco os declara, ex. BV) |
| RN-014 (Seguro RD/RE default ON) | extras.ts (rd_re_insurance_toggle: z.boolean().default(true)) |
| Nacionalidade → RNE | refinements.ts (nationality ≠ Brasil força type_doc='rne') |
| Vínculo de terceiro | refinements.ts (account_third_party ≠ nao_se_aplica exige bond_document_upload) |
| .strict() | cada ficha rejeita qualquer campo fora do shape declarado do banco |
Campos dropdown/autocomplete
Campos de seleção são string validada (textField), exceto type_doc
(DocumentTypeEnum) e sex (SexEnum). Para restringir um deles, troque no
<Banco>PFSchema.ts/<Banco>PJSchema.ts do banco por um z.enum([...]) — está tudo explícito no shape.
Distribuição (source-only)
Este repositório armazena apenas os schemas em TypeScript — não faz build. Os exports apontam direto para o source (src/*.ts); quem consome transpila.
"exports": {
".": "./src/index.ts",
"./financing/formalization": "./src/domains/financing/formalization/index.ts",
// wildcard: cada arquivo de banco é importável direto, sem registry central
"./financing/formalization/schemas/*": "./src/domains/financing/formalization/schemas/*.ts"
}- Next.js / frontend: adicione
@77sol/form-schemasemtranspilePackages. - api-v3 / backend (Node + TS): garanta que o pacote seja transpilado.
zodépeerDependency.
Agnóstico a framework
Depende apenas de zod (peer) — zero React/Next/Vue/DOM. Entrega schemas Zod, não
componentes: valide com .parse()/.safeParse() e, para renderizar, derive os campos
do schema (.shape). Um guardrail do Biome (noRestrictedImports) barra imports de UI.
Scripts
yarn typecheck # tsc --noEmit
yarn test # vitest
yarn lint # biome lint
yarn run check # biome check (lint + formatação)
yarn check:fix # biome check --writeVersionamento
Conventional Commits + changelog automático via semantic-release (ver .releaserc.json).
