Initial commit
This commit is contained in:
@@ -0,0 +1,43 @@
|
||||
# Etapa 04 — Normalizador e padronização de dados
|
||||
|
||||
## Objetivo
|
||||
Implementar o módulo `normalizer/` que transforma os `LeadBrutoDTO` extraídos na etapa 03 em dados padronizados prontos para persistência, conforme as regras definidas em `ARQUITETURA-SCHEMA.md` seção 5.
|
||||
|
||||
## Contexto
|
||||
Esta etapa não persiste nada ainda — produz um `LeadNormalizadoDTO` a partir do `LeadBrutoDTO`. A persistência com deduplicação é a etapa 06 (junto com a API).
|
||||
|
||||
## Tarefas
|
||||
|
||||
1. Criar `normalizer/NomeNormalizer`:
|
||||
- Trim + colapsar espaços múltiplos
|
||||
- Title Case, preservando em maiúsculo as siglas societárias: `LTDA`, `ME`, `EIRELI`, `S/A`, `S.A.`
|
||||
- Remover caracteres de controle/emoji
|
||||
2. Criar `normalizer/TelefoneNormalizer`:
|
||||
- Extrair apenas dígitos do texto bruto
|
||||
- Assumir DDI `+55` se ausente
|
||||
- Validar tamanho (DDD de 2 dígitos + número de 8 ou 9 dígitos); se inválido, retornar `null` no campo normalizado mas manter o bruto
|
||||
- Formatar em E.164 (`+5543999999999`)
|
||||
3. Criar `normalizer/CnpjValidator`:
|
||||
- Extrair apenas dígitos (14 posições)
|
||||
- Implementar validação de dígito verificador (algoritmo módulo 11)
|
||||
- Se inválido, descartar o CNPJ (gravar `null`) em vez de persistir um valor incorreto
|
||||
4. Criar `normalizer/RamoMapper`:
|
||||
- Buscar na tabela `ramos.aliases` (JSONB) se a categoria bruta já tem mapeamento conhecido
|
||||
- Se encontrar, retornar o `ramo_id` correspondente
|
||||
- Se não encontrar, retornar `ramo_id = null` e manter a categoria bruta em `categoria_bruta` para curadoria manual posterior
|
||||
5. Criar `normalizer/DedupHashCalculator`:
|
||||
- Calcular `hash_dedup = SHA-256(nomeNormalizado + "|" + telefoneE164)`
|
||||
6. Criar `normalizer/LeadNormalizerService` que orquestra os passos acima e produz o `LeadNormalizadoDTO` completo a partir de um `LeadBrutoDTO`
|
||||
7. Escrever testes unitários para cada normalizador, cobrindo casos-limite:
|
||||
- Telefone sem DDD, com formatação variada (parênteses, traços, espaços)
|
||||
- CNPJ com dígito verificador inválido
|
||||
- Nome com sigla societária em posições diferentes
|
||||
- Categoria bruta sem mapeamento conhecido em `ramos`
|
||||
|
||||
## Critérios de aceite
|
||||
|
||||
- [ ] Todos os normalizadores implementados e cobertos por testes unitários com casos-limite
|
||||
- [ ] CNPJ inválido nunca é persistido como válido
|
||||
- [ ] Telefone sempre sai em E.164 quando válido, ou `null` quando não for possível normalizar
|
||||
- [ ] Ramo sem mapeamento conhecido não quebra o fluxo — apenas fica pendente de curadoria
|
||||
- [ ] `hash_dedup` calculado de forma determinística e reproduzível para o mesmo par nome+telefone
|
||||
Reference in New Issue
Block a user