# CLAUDE.md — Cacalutia Leads

Consolidado a partir de `claude/PLANEJAMENTO-CACALUTIA-LEADS.md` (v2.1) e
`claude/referencia-visual.html` em 2026-09-11. O planejamento é o documento completo; este
arquivo é o resumo operacional pra sessões futuras de código. Em caso de dúvida, o planejamento
original manda.

## O que é

Serviço de geração de leads B2B com garantia de entrega. A Cacalutia investe a própria mídia
(Meta Ads e Google Ads), capta os leads, enriquece dados, qualifica cada lead com agente de IA
via WhatsApp e entrega ao vendedor do cliente só os leads que cumprem critérios objetivos. O
cliente compra um pacote mensal com quantidade mínima garantida. Nicho inicial: terceirização de
cosméticos (private label). Cacalutia nunca vende para o cliente final — o vendedor do cliente
fecha.

Métrica central: **CPLQ** (custo por lead qualificado) = CPL bruto / taxa de qualificação. Toda
a plataforma existe pra manter o CPLQ abaixo do teto do pacote e mostrar isso em tempo real
(fórmula completa na seção 2 do planejamento).

## Decisão de arquitetura: app separado, não módulo do One

Pasta própria, banco próprio, processo PM2 próprio. Motivos: produto diferente, receita crítica
(lead perdido = prejuízo por causa da garantia), dados pessoais sob LGPD, risco de uma mudança
aqui quebrar o `one.cacalutia.com` em produção. Ver `REAPROVEITAMENTO.md` pro que dá pra
reaproveitar do One (auditoria file-by-file) — nunca importar direto do One, sempre copiar e
adaptar, ou extrair pra pacote compartilhado se isso for decidido depois.

Stack: Node.js + Express + React + MySQL + PM2, igual ao One (maximiza reaproveitamento e
familiaridade). Interface 100% em português. Código, banco, status internos, logs, testes e
documentação técnica em inglês. Manual da gerente em português.

## Regras de arquitetura que nunca podem ser violadas (seção 10 do planejamento)

1. Uma única definição de cada status e estado (lead, conversa, dono), em um único service.
2. Custos, lucro, margem e CPLQ calculados em um único service, a partir de `cost_ledger` e
   `ai_calls`. Nunca duplicar essa conta em telas ou relatórios.
3. **Nenhum lead pode se perder**: gravar cru em `inbound_events` primeiro, processar em job
   durável (retry + backoff + dead-letter + alerta). A captação NUNCA é pausada — pausa de
   agente, orçamento estourado ou circuit breaker só mudam pra onde o lead vai (fila humana).
4. Toda mensagem passa pelo mesmo service de envio e pela guarda da seção 5.2 (7 checagens, ver
   abaixo). Não existe envio por fora dele.
5. Só o `owner` da conversa (`agent` | `human` | `none`) envia. Troca de dono é transação atômica
   gravada em `audit_log`.
6. `do_not_contact` é checado antes de qualquer envio, em qualquer módulo — inclusive no
   copiloto de prospecção interno.
7. O agente só afirma o que está em `client_claims` com status `verified`. Nunca inventa preço,
   desconto, prazo, condição de pagamento, garantia de resultado ou superlativo.
8. A IA coleta e interpreta (JSON estruturado); a **decisão de qualificação é regra determinística
   versionada em código**, aplicada sobre esse JSON. A IA nunca decide sozinha se o lead conta
   na garantia.
9. Mudança de roteiro, ICP ou afirmações cria nova versão; leads antigos mantêm a versão com que
   foram avaliados (nunca reavaliar retroativamente com regra nova).
10. Toda query filtra por `client_id`. Regra de negócio só em `services/`, nunca em `routes/`.
11. Toda ação de agente e de humano vai para `audit_log`.
12. Dados pessoais: consentimento registrado, acesso por papel, tokens de clientes criptografados
    no banco (nunca em texto puro), política de retenção definida.
13. Segredos só no `.env` do servidor. Nunca em `.md`, commits, logs ou prints. Logs estruturados
    sem token.
14. Nenhum bloqueio (API, janela, orçamento, breaker) é contornado por caminho alternativo.
    Bloqueou → registra e escala. Nunca criar um "jeitinho" pra passar por cima.
15. Código escrito não é sucesso. Testar de verdade e mostrar evidência antes de reportar algo
    como pronto ou corrigido.

## Glossário de estados (fonte única — nunca reimplementar em tela/relatório)

**Status do lead (funil)**: `received` → `duplicate` | `qualifying` → `qualified_a` (conta na
garantia) | `qualified_b` (bônus, não conta) | `discarded` → `delivered` → `disputed` |
`accepted` (aceito após 48h sem contestação = o que conta na garantia de verdade).

**Estado da conversa (canal, campo separado do status do lead)**: `pending_first_contact` →
`waiting_reply` | `window_open` (24h, ou 72h se veio de Click-to-WhatsApp) | `window_closed` →
`paused` | `do_not_contact` (terminal) | `completed`.

**Propriedade da conversa**: `owner` ∈ `agent` | `human` | `none`. Gerente assume → agente
bloqueado de enviar (inclusive follow-ups agendados, cancelados na mesma transação). Devolver →
agente recebe resumo do que a gerente conversou.

**Intenções classificadas a cada mensagem do lead** (seção 6.3): `interested`, `asked_info`,
`asked_pricing`, `wants_salesperson`, `not_decision_maker`, `will_forward`, `objection`,
`out_of_scope`, `not_interested`, `opt_out` (fluxo 5.3, imediato), `ambiguous`, `needs_human`
(handoff imediato).

**Níveis de ativação por cliente** (`clients.activation_level`): `simulation` (webhooks/WhatsApp
simulados, nenhum lead real) → `dry_run` (leads reais entram, agente sugere, gerente aprova cada
envio) → `pilot` (agente envia sozinho, teto diário, só após autorização explícita registrada) →
`autonomous` (operação normal). Subir de nível é ação manual registrada. Qualquer circuit
breaker pode rebaixar o cliente pra `dry_run` automaticamente.

## Guarda de envio (seção 5.2 — as 7 checagens, nesta ordem, sempre)

1. Lead não está em `do_not_contact`.
2. Quem envia é o `owner` atual da conversa.
3. Cliente, conversa e agente não estão pausados (manual, breaker ou orçamento).
4. Janela do WhatsApp permite mensagem livre, ou é template aprovado.
5. Sem envio idêntico pro mesmo lead nos últimos minutos (trava de duplicidade).
6. Mensagens do agente: validação de afirmações aprovada (duas camadas — regra determinística +
   modelo rápido, seção 5.4).
7. Nível de ativação do cliente permite envio real (`dry_run` grava como sugestão, não envia).

Falhou qualquer item → não envia, grava motivo, vai pra fila de exceções. Nunca existe caminho
alternativo.

## Proteções operacionais (seção 8)

- **Jobs duráveis**: tabela `jobs` no MySQL (sem Redis, salvo se já existir no servidor). Worker
  em processo PM2 separado do servidor web. Retry com limite e backoff; esgotou → `dead`, aparece
  na fila de exceções. Idempotência por chave única em webhooks, jobs e envios. Reinício não
  perde nem duplica (jobs `running` com lock expirado voltam pra `pending`).
- **Orçamento de IA**: toda chamada grava em `ai_calls` (custo estimado em BRL). Teto mensal
  global (`AI_MONTHLY_BUDGET_BRL`) e teto por cliente (contrato). Atingiu → pausa agente naquele
  escopo, leads vão pra fila da gerente, alerta disparado. Captação nunca para.
- **Circuit breaker**: 8 gatilhos (seção 8.3 do planejamento — opt-out alto, queda de qualidade
  do número, bloqueios/denúncias, erro anormal de webhook/API, campanha gastando sem lead há X
  horas, envio duplicado, reprovação de afirmação acima do limite, divergência de dados). Disparo
  → pausa o escopo afetado, alerta Bruno + gerente. Retomada só manual, registrada.

## Modelo de negócio (seção 2 e 6.7 — cockpit financeiro, só admin)

```
disponivel = preco_pacote × (1 − imposto_faturamento − margem_alvo) − custos_fixos_cliente
teto_cplq = (disponivel / leads_garantidos − custo_ia_por_lead_bruto / taxa_qualificacao)
            / (1 + parcela_verba_meta × 0,1215)
```

Meta cobra 12,15% de imposto sobre mídia desde jan/2026 (Ads Manager mostra sem imposto, fatura
vem com). Google absorve. Cacalutia compra a mídia → o valor total do pacote é faturamento da
Cacalutia. Pacotes iniciais de cosméticos: Essencial (30 leads/R$15.000), Crescimento (50/R$23.500),
Escala (80/R$36.000, só após 60 dias de dados) — valores a validar com piloto.

## Design (seção 16 do planejamento)

Direção: evolução do visual do One, mais futurista, sala de controle ao vivo. **Atenção**: o
planejamento assume que o One tem tema escuro (`#0D0F12`) e fontes DM Sans/DM Mono como base —
isso está **desatualizado**. Ver `REAPROVEITAMENTO.md` seção de design pros tokens reais
auditados em 2026-09-11 (tema claro, fonte Inter, cor de marca única `lime #CFFF06`). Antes de
montar o design system daqui, ler os tokens reais do One de novo (podem ter mudado de novo) e
decidir com o usuário se este app usa a mesma base clara+lime do One (reconhecimento de marca) ou
a direção escura+ciano/violeta/lime do `referencia-visual.html` (identidade própria, "sala de
controle" mais justificável pro tom "ao vivo" deste produto). Isso é uma decisão de design a
apresentar, não a assumir.

Regras que sobrevivem independente da paleta escolhida: DM Mono/tabular-nums pra todo número;
lima reservado pro elemento mais importante de cada tela (aqui, o anel da garantia); área de
mensagens da central de conversas sempre calma, sem gradiente, alto contraste (a gerente passa o
dia lá); dois modos de densidade (cockpit vs. operação); uma única sequência de entrada animada
por tela; `prefers-reduced-motion` respeitado.

## Modelo de dados (seção 9 — proposta inicial, revisar após auditoria)

Ver planejamento completo pra lista de campos. Tabelas-chave: `clients`, `contracts`, `cycles`,
`icp_criteria`, `agent_scripts`, `client_claims`, `inbound_events`, `leads`, `do_not_contact`,
`lead_enrichment`, `conversations`, `messages`, `intent_classifications`,
`qualification_answers`, `claim_checks`, `lead_scores`, `handoffs`, `deliveries`, `disputes`,
`sales_feedback`, `offline_conversions`, `experiments` (+variants+assignments), `ai_calls`,
`cost_ledger`, `jobs`, `breaker_events`, `prospects` (+contacts+activities, copiloto interno),
`audit_log`.

## Roadmap (seção 14)

**Fase 0** (sem código): histórico de CPL/qualificação/fechamento das fábricas já atendidas, ICP
padrão de cosméticos, fechar 1-2 clientes piloto por venda manual.

**Fase 1 (MVP)**: captação (Meta Lead Ads + landing page + Click-to-WhatsApp) → jobs duráveis →
agente WhatsApp com roteiro/intenções/afirmações verificadas → guarda de envio → lista de não
contato → trava de dono → central da gerente (inbox, assumir, pausa geral, fila de exceções) →
níveis `simulation`/`dry_run`/`pilot` → orçamento de IA + breaker básico → entrega por WhatsApp →
contador de garantia → cockpit com mídia/custos/CPLQ. 13 critérios de aceite com evidência na
seção 14 do planejamento — não declarar Fase 1 pronta sem rodar todos.

**Fase 2**: enriquecimento CNPJ, score versionado, portal do cliente, conversões offline,
pacing com alertas, Google Ads como fonte, experimentos, breaker completo, copiloto de
prospecção (pode antecipar — independente, ajuda a vender os primeiros pacotes).

**Fase 3**: CRMs, editor de roteiros sem código, novos nichos, relatórios de ROI automáticos.

## Decisões em aberto (seção 15 — travam a Fase 1: itens 1, 3 e 7)

1. Captação na marca do cliente ou portal com marca própria distribuindo por aderência.
2. Limite de clientes por nicho/região (não competir no mesmo leilão).
3. **Número de WhatsApp**: WABA do cliente ou da Cacalutia — trava o modelo de dados.
4. Contas de anúncio: BM da Cacalutia por cliente, ou BM do cliente com pagamento da Cacalutia.
5. Regime tributário / faturamento (contador).
6. Cláusula de garantia + contrato de tratamento de dados (advogado).
7. **Servidor**: dedicado ou VPS atual (compartilhada, 8GB RAM, já com histórico de sobrecarga
   documentado no CLAUDE.md do One) — trava o deploy.
8. Fornecedor de dados de CNPJ com busca por CNAE pro copiloto.
9. Limiares iniciais do circuit breaker e teto diário do `pilot`.

## Infraestrutura

Subdomínio `leads.cacalutia.com` já provisionado no cPanel da conta `ccltglobal1` (confirmado em
2026-09-11 — pasta já tinha `cgi-bin`/`.well-known` de criação automática do cPanel). Arquivos de
planejamento em `claude/` dentro desta pasta. Seguir o mesmo padrão de deploy do One: banco MySQL
próprio (nome a definir, convenção `ccltglobal1_<algo>`), `.env` próprio, PM2 com processo(s)
próprio(s) — pelo menos dois: servidor web + worker de jobs (arquitetura pede processo separado
pro worker, seção 8.1).

## Mensagem original de kickoff (seção 17 do planejamento)

Preservada porque define a ordem de trabalho esperada: ler o planejamento inteiro + a referência
visual → escrever este CLAUDE.md → auditar o One só-leitura e gerar `REAPROVEITAMENTO.md` →
apresentar pro usuário (reaproveitamento, app separado vs. módulo, jobs duráveis/guarda de
envio/trava de dono neste servidor, mudanças no modelo de dados, design system, plano de
construção da Fase 1) → **só então** escrever código.
