📋 Documentação da API - Leads Unificados RSC
Endpoint
GET /bifrost/leads-unificados/rsc/
Descrição
Retorna uma lista unificada e otimizada de leads de vendas, com suporte a filtros avançados, paginação, agrupamento de leads repetidos e controle de permissões de usuário. Esta é a versão refatorada e otimizada com circuit breaker e processamento paralelo.
🔐 Autenticação
Esta rota requer autenticação via token API Key.
Headers obrigatórios:
api-key: <sua-api-key>
🌐 Hostnames
DEV:
- VPN:
100.113.139.94:3001 - PUBLIC:
136.116.58.209:3001
URL Completa de Exemplo (DEV):
http://136.116.58.209:3001/bifrost/leads-unificados/rsc/
📥 Parâmetros de Query
| Parâmetro | Tipo | Obrigatório | Descrição | Exemplo |
|---|---|---|---|---|
startDate | string | Não | Data inicial para filtro (formato: YYYY-MM-DD) | 2026-01-01 |
endDate | string | Não | Data final para filtro (formato: YYYY-MM-DD) | 2026-02-06 |
userId | number | Não | ID do usuário para filtrar leads específicos | 123 |
usePermissions | string/number/boolean | Não | Aplicar permissões do usuário (1 ou '0') | 1 |
cached | string/number | Não | Tempo de cache (0=sem cache, 1=15min, padrão=5min) | 1 |
fetchAll | string/number/boolean | Não | Buscar todos os registros sem paginação | true |
📤 Resposta de Sucesso
Status Code: 200 OK
Estrutura da Resposta
{
"data": [{...}],
"total": 0,
"page": 1,
"limit": 100,
"totalPages": 0,
"hasNextPage": false,
"hasPreviousPage": false,
"repeatedTotal": 0,
"cached": false,
"responseTime": 1234
}
Campos da Resposta
| Campo | Tipo | Descrição |
|---|---|---|
data | array | Array de objetos contendo os leads unificados |
total | number | Quantidade total de leads encontrados |
page | number | Página atual |
limit | number | Limite de registros por página |
totalPages | number | Total de páginas disponíveis |
hasNextPage | boolean | Indica se existe próxima página |
hasPreviousPage | boolean | Indica se existe página anterior |
repeatedTotal | number | Quantidade total de leads repetidos (filhos) |
cached | boolean | Indica se o resultado veio do cache (sempre false na vers ão atual) |
responseTime | number | Tempo de resposta em milissegundos |
Estrutura de um Lead no Array data
{
"id": 20626,
"source": "custom-funil",
"customSourceId": 30,
"customSourceName": "Instagram",
"customSourceSlug": "Instagram",
"originConsolidated": "Instagram",
"blocked": "0",
"name": "Nádia Caroline Charaf Edine",
"mail": "[email protected]",
"phone": "8781464575",
"pfOrPj": "PJ",
"long_id": "29062119-f318-11f0-a29c-02420a4d0002",
"shortLongId": "29062119",
"sprintId": null,
"sprintName": null,
"cpf": "-",
"cnpj": "-",
"etapa_kanban": "5",
"gestor_user_Id": 19,
"corretor_nome": "Paloma Soares de Souza",
"balcaoId": null,
"nome_balcao": null,
"date_created": "2026-01-16T23:15:54.000Z",
"date": "2026-01-28T17:29:47.000Z",
"time": "",
"files": "-",
"attributedToPersonIn": false,
"campaignName": "Forms Vendas PJ - UNC 0061 25 VIRADA DE TABELA",
"motiveCancelling": null,
"novu_hash": "ddc12c5e9050c3df5031d966511a222dbda4092e",
"isFollowUp": false,
"timeContact": "-",
"prefContact": "whatsapp",
"interestPlan": "-",
"proposeNumber": null,
"proposalCreatedBy": null,
"temperature": 3,
"temperatureLabel": "Morno",
"temperatureScore": 52,
"saledLifes": 0,
"saledPlan": null,
"qttPersons": "1",
"size": "-",
"ans_plano_unimed": "-",
"email_valido": "1",
"cliente_unimed": "0",
"isOrganic": false,
"origem_personalizada": null,
"isParent": true,
"clusterSize": 2,
"childrenCount": 1,
"repeated": 1,
"tipo_lead": "Lead com reincidência",
"cluster": {
"totalRegistros": 2,
"primeiroRegistro": "2025-10-30T02:10:11.000Z",
"ultimoRegistro": "2026-01-16T23:15:54.000Z",
"idsGrupo": [
"19590",
"20626"
]
}
}
Campos Detalhados do Lead
| Campo | Tipo | Descrição |
|---|---|---|
id | number | ID único do lead |
source | string | Tipo de origem do lead (ex: "custom-funil") |
customSourceId | number | ID da origem personalizada |
customSourceName | string | Nome da origem personalizada |
customSourceSlug | string | Slug da origem personalizada |
originConsolidated | string | Nome consolidado da origem |
blocked | string | Status de bloqueio ("0" = não bloqueado, "1" = bloqueado) |
name | string | Nome completo do lead |
mail | string | E-mail do lead |
phone | string | Telefone do lead (apenas números) |
pfOrPj | string | Tipo de pessoa ("PF" = Pessoa Física, "PJ" = Pessoa Jurídica) |
long_id | string | Identificador longo único do lead (UUID) |
shortLongId | string | Versão curta do long_id (8 primeiros caracteres) |
sprintId | number | null | ID da sprint associada |
sprintName | string | null | Nome da sprint associada |
cpf | string | CPF do lead ("-" se não informado) |
cnpj | string | CNPJ do lead ("-" se não informado) |
etapa_kanban | string | ID da etapa atual no kanban |
gestor_user_Id | number | ID do usuário gestor/corretor responsável |
corretor_nome | string | Nome do corretor responsável |
balcaoId | number | null | ID do balcão (se aplicável) |
nome_balcao | string | null | Nome do balcão (se aplicável) |
date_created | string (ISO 8601) | Data/hora de criação do lead |
date | string (ISO 8601) | Data/hora da última atualização |
time | string | Horário adicional (pode estar vazio) |
files | string | Arquivos anexados ("-" se nenhum) |
attributedToPersonIn | boolean | Indica se foi atribuído a uma pessoa |
campaignName | string | Nome da campanha de origem |
motiveCancelling | string | null | Motivo de cancelamento se aplicável |
novu_hash | string | Hash de identificação do Novu (notificações) |
isFollowUp | boolean | Indica se está em follow-up |
timeContact | string | Horário preferido de contato |
prefContact | string | Preferência de contato (ex: "whatsapp") |
interestPlan | string | Plano de interesse ("-" se não especificado) |
proposeNumber | string | null | Número da proposta associada |
proposalCreatedBy | number | null | ID do usuário que criou a proposta |
temperature | number | Temperatura do lead (1-5) |
temperatureLabel | string | Label da temperatura ("Frio", "Morno", "Quente") |
temperatureScore | number | Score de temperatura (0-100) |
saledLifes | number | Quantidade de vidas vendidas |
saledPlan | string | null | Plano vendido |
qttPersons | string | Quantidade de pessoas no lead |
size | string | Tamanho/categoria ("-" se não aplicável) |
ans_plano_unimed | string | Código ANS do plano Unimed |
email_valido | string | Validação de e-mail ("0" = inválido, "1" = válido) |
cliente_unimed | string | Cliente Unimed ("0" = não, "1" = sim) |
isOrganic | boolean | Indica se é lead orgânico |
repeated | number | Número de reincidências |
❌ Respostas de Erro
503 - Service Unavailable
Retornado quando o circuit breaker está aberto devido a falhas consecutivas.
{
"error": "Service temporarily unavailable",
"message": "O sistema está temporariamente indisponível. Tente novamente em alguns instantes.",
"requestId": "abc-123-def-456",
"responseTime": 500
}
500 - Internal Server Error
Retornado em caso de erro interno não tratado.
{
"error": "Internal server error",
"message": "Descrição do erro",
"requestId": "abc-123-def-456",
"responseTime": 1500
}
📊 Exemplos de Uso
Exemplo 1: Buscar leads por período com permissões de usuário
curl -X GET "https://api.exemplo.com/bifrost/leads-unificados/rsc/?startDate=2026-01-01&endDate=2026-02-06&userId=123&usePermissions=1" \
-H "Authorization: Bearer seu-token-jwt" \
-H "api-key: sua-api-key"
Exemplo 2: Buscar todos os leads (puro)
curl -X GET "https://api.exemplo.com/bifrost/leads-unificados/rsc/?fetchAll=true" \
-H "Authorization: Bearer seu-token-jwt" \
-H "api-key: sua-api-key"
Sistema de Permissões
Quando usePermissions=1 e userId é fornecido:
- O sistema busca as permissões do usuário no banco de dados
- Filtra os leads retornados baseado nas permissões
- Respeita departamentos e sprints autorizados
⚡ Performance e Otimizações
Circuit Breaker
A rota utiliza circuit breakers para:
- Chamadas ao banco de dados
- Requisições HTTP externas (API do Gestor)
- Proteção contra falhas em cascata
Rate Limiting
Aplicado através do middleware limiterHeavyEndpoints para prevenir sobrecarga.
Cache (Atualmente Desabilitado)
Nota: O cache está desabilitado na versão atual (cached: false). Todas as requisições buscam dados diretamente do banco de dados para garantir consistência.
📝 Notas Importantes
- Multi-tenant: A rota é multi-tenant, identifica o tenant através da configuração da requisição (primeiro path após o host)
🔧 Middlewares Aplicados
- verificaToken: Validação de token JWT
- limiterHeavyEndpoints: Rate limiting para endpoints pesados
📌 Versão
- Versão da API: Refatorada (v2)
- Controller:
funil.controller.refactored.js - Última atualização: Fevereiro 2026
🤝 Suporte
Para dúvidas ou problemas com esta API, entre em contato com a equipe de desenvolvimento.