# Análise profunda — Global Leads API × MVP LeadB2B

**Fontes:** [Swagger](https://leads.globals.tech/docs), [Developer](https://leads.globals.tech/developer), [OpenAPI](https://leads.globals.tech/openapi.json), [GET /api/v1/meta](https://leads.globals.tech/api/v1/meta) (jun/2026).

**Decisão de arquitetura:** o LeadB2B **não cria banco de dados**. Toda lógica de produto (funil, kanban, planos, anti-extração) vive na **Global API** sob `/api/v1/product/*`. O site Go é **SSR + BFF JWT** (cookie HttpOnly) e consome essa API via `internal/api/product.go`.

**Status LeadB2B (jun/2026):** refatorado — sem `APP_DB_*`; `/app/*` e `/api/v1/product/*` chamam a Global API diretamente.

---

## 1. Dois modos de auth (confirmado)

| Modo | Header | Uso no LeadB2B |
|------|--------|----------------|
| **API Key** `glk_live_…` | `Authorization: Bearer` ou `X-API-Key` | Site público SEO: `/busca`, `/empresa/*`, `/api/filtros/*` |
| **JWT usuário** | `Authorization: Bearer {access_token}` | App logado: `/app/*` → repassa token para `/product/*` e `/auth/me` |

Regras críticas ([meta](https://leads.globals.tech/api/v1/meta)):

- JWT: **1 sessão ativa** — novo login revoga a anterior (token antigo → **401**). Requisições mantêm bind de IP (`SESSION_BIND_IP`); troca de IP no mesmo dispositivo pode exigir novo login.
- API Key: sem IP lock; rate limit por portal (60 req/min padrão).
- Senha mínima: **10 chars**, letra + número.
- `GET /auth/me` retorna `product` com plano, limites e `can_use_app`.

---

## 2. O que a Global API **já entrega** para o MVP

### 2.1 Auth (completo para MVP)

| Endpoint | Status |
|----------|--------|
| `POST /api/v1/auth/register` | ✅ Trial automático; resposta pode incluir `access_token` |
| `POST /api/v1/auth/login` | ✅ |
| `POST /api/v1/auth/logout` | ✅ |
| `GET /api/v1/auth/me` | ✅ + bloco `product` (limits, subscription, access) |
| `PATCH /api/v1/auth/me` | ✅ Nome do perfil |
| `PATCH /api/v1/auth/me/password` | ✅ |
| `POST /api/v1/auth/forgot-password` | ✅ |
| `POST /api/v1/auth/reset-password` | ✅ |

`MeResponse.product` (schema OpenAPI):

- `subscription`: plan, plan_name, status, ends_at
- `limits`: max_active_leads, active_leads_count, slots_remaining, max_add_per_day, added_today, can_export, exports_today, max_export_per_day, **max_search_page_size**
- `access`: can_use_app, reason

### 2.2 Dados RFB (site público + CRM)

| Endpoint | Uso |
|----------|-----|
| `GET /api/v1/leads/filtros` | Metadados |
| `GET /api/v1/leads/filtros/municipios` | Municípios |
| `GET /api/v1/leads/filtros/cnaes` | CNAEs |
| `GET /api/v1/leads/filtros/naturezas-juridicas` | ✅ Novo |
| `GET /api/v1/leads/filtros/portes` | ✅ Novo |
| `GET /api/v1/leads/estabelecimentos` | Busca completa (API Key no SEO) |
| `GET /api/v1/leads/estabelecimentos/{cnpj}` | Ficha 14 dígitos |
| `GET /api/v1/leads/empresas/{cnpj_basico}` | Matriz 8 dígitos |

Filtros na listagem raw: `tem_telefone`, `tem_email`, `tem_socios`, CEP, bairro, logradouro, MEI, Simples, porte, natureza jurídica, situação, matriz/filial, data abertura.

### 2.3 Camada produto LeadB2B — `/api/v1/product/*` (MVP core)

Documentada no OpenAPI com tags dedicadas e fluxo `leadb2b_funil` no meta.

#### Busca mascarada (`product-search`)

| Endpoint | Função MVP |
|----------|------------|
| `GET /product/search/filters` | Metadados |
| `GET /product/search/municipios` | Municípios |
| `GET /product/search/cnaes` | CNAEs |
| `GET /product/search/companies` | Listagem **sem telefone/e-mail** + `already_working`, `has_whatsapp` |
| `GET /product/search/companies/{cnpj}` | Preview mascarado |
| `GET /product/search/companies/{cnpj}/full` | Completo **só se lead trabalhado** |

Resposta `MaskedCompanyOut`: cnpj_masked, has_phone, has_email, **has_whatsapp**, already_working.

#### Funil (`product-funnel`)

| Endpoint | Função MVP |
|----------|------------|
| `POST /product/leads/work` | **Trabalhar lead** → 201 + lead + estabelecimento |
| `GET /product/leads` | Lista por stage |
| `GET /product/leads/{id}` | Detalhe + ficha RFB |
| `PATCH /product/leads/{id}/stage` | Mover kanban |
| `PATCH /product/leads/{id}` | Notas |
| `DELETE /product/leads/{id}` | Só arquivado |
| `GET /product/leads/{id}/contact/options` | Telefones/e-mails |
| `POST /product/leads/{id}/contact/whatsapp` | URL wa.me + template |
| `POST /product/leads/{id}/contact/email` | mailto |

#### Kanban (`product-kanban`)

| Endpoint | Função |
|----------|--------|
| `GET /product/kanban` | 7 colunas + meta (active_count, slots_remaining) |
| `GET /product/kanban/stats` | Contadores |

#### Templates, export, stats, admin

| Grupo | Endpoints |
|-------|-----------|
| `product-templates` | CRUD `/product/templates` |
| `product-exports` | POST/GET exports + download CSV |
| `product-stats` | `GET /product/stats/overview` |
| `product-admin` | users, status, subscription, plans, metrics, audit |

---

## 3. Mapeamento MVP × API (cobertura)

| Requisito MVP | Onde na Global API | Status |
|---------------|-------------------|--------|
| Criar conta / login | `/auth/register`, `/login` | ✅ |
| Recuperar senha | `/auth/forgot-password`, `/reset-password` | ✅ |
| Plano ativo obrigatório | `GET /auth/me` → `product.access.can_use_app` | ✅ |
| Limites por plano | `product.limits` | ✅ |
| Busca mascarada | `/product/search/companies` | ✅ |
| Trabalhar lead | `POST /product/leads/work` | ✅ |
| Kanban 7 colunas | `GET /product/kanban` | ✅ |
| WhatsApp facilitado | `POST /product/leads/.../contact/whatsapp` | ✅ |
| E-mail facilitado | `POST /product/leads/.../contact/email` | ✅ |
| Templates `{{empresa}}` | `/product/templates` | ✅ |
| Export controlado | `/product/exports` | ✅ |
| Dashboard stats | `/product/stats/overview` | ✅ |
| Admin | `/product/admin/*` | ✅ |
| Anti-extração mascarada | `MaskedSearchOut` | ✅ |
| Trial no register | register + product subscription | ✅ (verificar seed planos) |
| Pagamento automático | — | ❌ Futuro |

---

## 4. O que **ainda falta ou precisa evoluir** na Global API

Prioridade para você implementar/ajustar **no backend da Global API** (não no leadb2b.org):

### Resolvido em produção (jun/2026)

| Item | Status |
|------|--------|
| Filtros completos `/product/search/companies` (22 params) | ✅ |
| `tem_whatsapp` na query | ✅ |
| `/product/search/filtros/naturezas-juridicas` e `/portes` | ✅ |
| `erros_product` no `/meta` | ✅ |
| Grupos `product_*` em `endpoints` no `/meta` | ✅ |
| `docs/LEADB2B-API.md` | ✅ |
| `product_kanban_stages` e `product_template_variables` no meta | ✅ |

### Alta (restante)

| # | Gap | Detalhe |
|---|-----|---------|
| 1 | **Sessão bind IP** | Troca de IP (4G/VPN) pode exigir novo login enquanto `SESSION_BIND_IP` estiver ativo. |

### Média

| # | Gap | Detalhe |
|---|-----|---------|
| 2 | **Developer page** | Confirmar seção LeadB2B atualizada no HTML (OpenAPI e meta já listam product). |
| 3 | **Stages do kanban** | Enum documentado no meta (`product_kanban_stages`). |

### Baixa / futuro

| # | Gap |
|---|-----|
| 9 | Gateway de pagamento (Stripe/Asaas) + webhook de assinatura |
| 10 | Times / multi-usuário por conta |
| 11 | Envio de e-mail pela plataforma (hoje mailto) |
| 12 | IA para variações de mensagem |

---

## 5. Arquitetura correta do LeadB2B (sem banco local)

```mermaid
flowchart LR
    Browser --> GoSSR[LeadB2B Go SSR]
    GoSSR -->|API Key| GlobalRFB["/leads/* público"]
    GoSSR -->|JWT cookie| GlobalProduct["/product/* + /auth/*"]
    GlobalProduct --> GlobalDB[(MySQL Global API)]
```

**LeadB2B NÃO deve ter:**

- `migrations/001_initial.sql`
- `internal/store` com MySQL de produto
- Tabelas `user_leads`, `plans`, etc. no repositório leadb2b.org

**LeadB2B DEVE ter:**

- Cookie `leadb2b_token` com JWT da Global API
- Handlers `/app/*` que chamam `/api/v1/product/*` com token do usuário
- Site público `/busca` com `GLOBALAPI_KEY` (modo portal)
- Cliente Go estendido: `Client.WithToken(jwt)` para product + auth

---

## 6. Rotas implementadas no LeadB2B Go

| Rota LeadB2B (BFF) | Global API |
|---------------------|------------|
| `GET /api/v1/auth/me` | `GET /api/v1/auth/me` |
| `GET /api/v1/product/search/companies` | idem |
| `POST /api/v1/product/leads/work` | idem |
| `GET /api/v1/product/kanban` | idem |
| `PATCH /api/v1/product/leads/{id}/stage` | idem |
| `POST /api/v1/product/leads/{id}/contact/*` | idem |
| `GET/POST /api/v1/product/templates` | idem |
| `POST/GET /api/v1/product/exports` | idem |
| `GET /api/v1/product/stats/overview` | idem |
| `/api/v1/product/admin/*` | idem |
| SSR `/app/*` | mesmas rotas product com JWT do cookie |

---

## 7. Conclusão

A Global API **já incorpora o modelo de negócio do MVP** na namespace `/api/v1/product/*`. O documento [`migrations/001_initial.sql`](../migrations/001_initial.sql) no repositório LeadB2B **não deve ser usado** — o schema de produto pertence ao backend da Global API.

**Para você (Global API):** priorize itens **#1–#4** da seção 4. O core (funil, kanban, limites, mascaramento, admin) **já está especificado e exposto**.

**Para o LeadB2B:** ✅ proxy/BFF implementado; `APP_DB_*` não é mais necessário para o app logado.
