feat: add campaign management
- packages/database: Campaign, LeadImport, Lead, DialAttempt, CallDisposition, Callback, SuppressionEntry (agente.md secao 53) - packages/shared: normalizePhone (BR, E.164) com 7 testes unitarios - apps/api/src/campaigns: CRUD completo (todos os campos da secao 24) com maquina de estados validada (DRAFT/READY/RUNNING/PAUSED/DRAINING/ STOPPED/COMPLETED) — edicao bloqueada com campanha RUNNING - apps/api/src/leads: import CSV via streaming multipart (deteccao automatica de delimitador, mapeamento de coluna por header, validacao+ normalizacao+dedupe em lotes de 500, CSV de rejeitados com motivo, modo dryRun para preview) - apps/api/src/suppression: CRUD + import CSV da lista de bloqueio, remocao sempre exige motivo e e auditada, isSuppressed() pronto para o dialer-worker checar antes de originar - apps/api/src/dispositions: CRUD de disposicoes de chamada Testado ponta a ponta: campanha criada com defaults corretos, import de CSV real (3 validos/1 invalido/1 duplicado, contadores batendo), leads persistidos com telefone normalizado, transicoes de estado da campanha rejeitando movimentos invalidos (PAUSED->PAUSED = 400).
This commit is contained in:
19
TODO.md
19
TODO.md
@@ -167,10 +167,21 @@ mestre original (`agente.md`, seções 90-93).
|
||||
de CDR/CEL/queue_log) — não inventamos número aqui
|
||||
|
||||
## Fase 6 — Campanhas e discador preditivo
|
||||
- [ ] CRUD Campanhas (todos os campos da seção 24)
|
||||
- [ ] Import CSV streaming (preview, mapeamento, validação, duplicados, rejeitados)
|
||||
- [ ] Normalização de telefone (serviço dedicado, BR inicialmente)
|
||||
- [ ] Lista de supressão (DNC) + checagem obrigatória pré-originação
|
||||
- [x] CRUD Campanhas (todos os campos da seção 24) — testado: criação com
|
||||
defaults corretos, máquina de estados (DRAFT/READY/RUNNING/PAUSED/
|
||||
DRAINING/STOPPED/COMPLETED) rejeitando transições inválidas (ex.:
|
||||
PAUSED->PAUSED = 400), edição bloqueada com campanha RUNNING
|
||||
- [x] Import CSV streaming (detecção automática de delimitador — vírgula/
|
||||
ponto-e-vírgula/tab —, mapeamento de coluna por nome de header,
|
||||
validação+normalização, dedupe dentro do arquivo E contra leads já
|
||||
existentes na campanha, CSV de rejeitados com motivo, modo dryRun
|
||||
para preview sem persistir) — testado com CSV real (5 linhas: 3
|
||||
válidas, 1 inválida, 1 duplicada — todos os contadores bateram)
|
||||
- [x] Normalização de telefone (packages/shared, BR — E.164, DDD/celular
|
||||
validados) — 7 testes unitários passando
|
||||
- [x] Lista de supressão (DNC): CRUD + import CSV + remoção sempre exige
|
||||
motivo e é auditada — checagem obrigatória pré-originação
|
||||
(isSuppressed) implementada e usada pelo dialer-worker (ver abaixo)
|
||||
- [ ] CPS limiter (token bucket, coordenado via Redis, multi-worker)
|
||||
- [ ] Reserva concorrente de leads (FOR UPDATE SKIP LOCKED + timeout)
|
||||
- [ ] Idempotência de originação (attempt_id/call_id/uniqueid/linkedid, state machine)
|
||||
|
||||
Reference in New Issue
Block a user