Skip to main content

Módulo 06: Leads & Clientes — API

Status: Rascunho Inicial Regras de negócio: ver regras-negocio/06_leads_clientes.md Domínio: ver dominio/lead.md · dominio/cliente.md


1. Contratos de API (RESTful)

1.1 Leads

POST /api/leads
Auth: Consultor | Gestor | Admin
Body: { tipo_pessoa, nome, telefone?, email?, cpf_cnpj?, origem, anotacoes? }
Return: { id, status: "NOVO" }

GET /api/leads
Auth: Consultor | Gestor | Gerente | Admin
Query: ?status=NOVO&consultor_id=uuid&dias_inatividade=X&temperatura=QUENTE
Return: [{ id, nome, tipo_pessoa, status, temperatura, ultimo_contato_at, consultor: { id, nome } }]

GET /api/leads/{id}
Auth: Consultor (própria carteira) | Gestor (subordinados) | Admin
Return: { ...atributos, interacoes[], tarefas_pendentes[], timeline[] }

PATCH /api/leads/{id}/status
Auth: Consultor | Gestor
Body: { status: "EM_ANDAMENTO | QUALIFICADO | PERDIDO", motivo_descarte? }
Return: 200 OK

POST /api/leads/{id}/interacao
Auth: Consultor | Gestor
Body: { tipo: "LIGACAO | WHATSAPP | EMAIL | REUNIAO", descricao, data_interacao }
Return: { id, lead_status_atualizado: bool }

POST /api/leads/{id}/converter
Auth: Consultor | Gestor
Body: { cpf_cnpj, endereco: { cep, logradouro, numero, complemento?, bairro, cidade, uf } }
Return: { cliente_id }
Errors:
422 — CPF/CNPJ inválido algoritmicamente
409 — CPF/CNPJ já existe para outro cliente no tenant

1.2 Clientes

GET /api/clientes
Auth: Consultor | Gestor | Gerente | Admin
Query: ?busca=nome_ou_cpf&consultor_id=uuid
Return: [{ id, nome, cpf_cnpj, tipo_pessoa, total_veiculos, status }]

GET /api/clientes/{id}
Auth: Consultor (própria carteira) | Gestor (subordinados) | Admin
Return: { ...atributos, veiculos[], propostas[], contratos[], timeline[] }

PUT /api/clientes/{id}
Auth: Consultor | Gestor
Body: { nome, email, telefone, endereco: { cep, logradouro, numero, complemento?, bairro, cidade, uf } }
Return: 200 OK
Nota: cpf_cnpj e tipo_pessoa são imutáveis — não aceitos no body.

1.3 Gestão de Carteira

POST /api/leads/redistribuir
Auth: Gestor | Gerente | Admin
Body: { lead_ids: [uuid], novo_consultor_id: uuid }
Return: { total_transferidos: int }
Nota: O novo_consultor_id deve pertencer ao mesmo tenant e ser subordinado ao gestor solicitante.

2. Schemas de Dados

Lead

{
"id": "uuid",
"tenant_id": "uuid",
"consultor_id": "uuid",
"tipo_pessoa": "PESSOA_FISICA | PESSOA_JURIDICA",
"nome": "string",
"razao_social": "string | null",
"telefone": "string (E.164) | null",
"email": "string | null",
"cpf_cnpj": "string | null",
"origem": "MANUAL | IMPORTACAO | FORMULARIO_WEB | INDICACAO | AUTOMACAO",
"status": "NOVO | EM_ANDAMENTO | QUALIFICADO | CONVERTIDO | PERDIDO | EXPIRADO",
"temperatura": "FRIO | MORNO | QUENTE | null",
"anotacoes": "text | null",
"motivo_descarte": "string | null",
"ultimo_contato_at": "datetime | null",
"expiracao_at": "datetime | null",
"created_at": "datetime",
"updated_at": "datetime"
}

Interação (Evento de Timeline)

{
"id": "uuid",
"lead_id": "uuid",
"cliente_id": "uuid | null",
"consultor_id": "uuid",
"tipo": "LIGACAO | WHATSAPP | EMAIL | REUNIAO | SISTEMA",
"descricao": "text",
"data_interacao": "datetime",
"created_at": "datetime"
}

Cliente

{
"id": "uuid",
"tenant_id": "uuid",
"lead_id": "uuid",
"consultor_id": "uuid",
"tipo_pessoa": "PESSOA_FISICA | PESSOA_JURIDICA",
"nome": "string",
"razao_social": "string | null",
"cpf_cnpj": "string",
"telefone": "string (E.164)",
"email": "string",
"endereco": {
"cep": "string",
"logradouro": "string",
"numero": "string",
"complemento": "string | null",
"bairro": "string",
"cidade": "string",
"uf": "string (2 chars)"
},
"status": "ATIVO | INATIVO | BLOQUEADO",
"sincronizado_erp": "boolean",
"created_at": "datetime",
"updated_at": "datetime"
}

3. Segurança e Boas Práticas

RegraImplementação
Silo de dadosConsultor só acessa leads/clientes da própria carteira. Gestor acessa os de seus subordinados. tenant_id validado em toda query.
ConversãoO endpoint POST /api/leads/{id}/converter valida CPF/CNPJ algoritmicamente antes de criar o Cliente. Em caso de inválido, retorna 422 com mensagem descritiva.
Imutabilidadecpf_cnpj e tipo_pessoa do Cliente não são atualizáveis via API. O body de PUT /api/clientes/{id} deve ignorar (ou rejeitar com 400) esses campos se enviados.
AuditoriaToda mudança de status do lead e toda redistribuição de carteira geram um evento do tipo SISTEMA na timeline do lead, com consultor_id do autor da ação.