42 lines
2.7 KiB
Markdown
42 lines
2.7 KiB
Markdown
# Etapa 06 — API REST do backend
|
|
|
|
## Objetivo
|
|
Expor os endpoints REST que o frontend vai consumir: autenticação, disparo de buscas, consulta/listagem de leads, exportação e curadoria de ramos.
|
|
|
|
## Contexto
|
|
Esta etapa também implementa a persistência com deduplicação (que ainda não existia nas etapas anteriores) e o worker que processa buscas pendentes de forma assíncrona.
|
|
|
|
## Tarefas
|
|
|
|
1. Criar `security/` com autenticação JWT:
|
|
- `POST /auth/login` — recebe email/senha, retorna token JWT
|
|
- Proteger todos os demais endpoints exigindo o token
|
|
2. Criar `worker/BuscaWorker`:
|
|
- Processo assíncrono (`@Scheduled` com polling, ou `@Async`) que busca registros `buscas` com status `pendente`, executa o `BuscaOrchestrator` (etapas 03+05) e, ao final, aplica o `LeadNormalizerService` (etapa 04) em cada lead extraído
|
|
- Antes de persistir, checar duplicidade por `hash_dedup` e `place_id`; se já existir, atualizar o vínculo com a nova busca em vez de duplicar
|
|
- Atualizar `busca.status`, `busca.total_encontrados`, `busca.finalizado_em` ao concluir (ou `erro` + `detalhe_erro` em caso de falha)
|
|
3. Criar `controller/BuscaController`:
|
|
- `POST /buscas` — cria uma nova busca (termo, localização, ramo opcional) com status `pendente`
|
|
- `GET /buscas` — lista buscas (paginado, filtrável por status)
|
|
- `GET /buscas/{id}` — detalhe de uma busca específica, incluindo status e total de leads encontrados
|
|
4. Criar `controller/LeadController`:
|
|
- `GET /leads` — lista leads paginada, com filtros por ramo, cidade/UF, status, busca de origem
|
|
- `GET /leads/{id}` — detalhe de um lead
|
|
- `PATCH /leads/{id}/status` — atualizar status do lead (novo, contatado, qualificado, convertido, descartado)
|
|
- `GET /leads/export` — exportação em CSV dos leads filtrados
|
|
5. Criar `controller/RamoController`:
|
|
- `GET /ramos` — lista ramos cadastrados
|
|
- `POST /ramos` — cria novo ramo (curadoria manual)
|
|
- `PATCH /ramos/{id}/aliases` — adiciona um alias a um ramo existente (para a fila de curadoria de categorias sem mapeamento)
|
|
- `GET /leads/sem-ramo` — lista leads com `ramo_id = null` pendentes de curadoria
|
|
6. Documentar a API (Swagger/OpenAPI via springdoc) para facilitar a integração do frontend
|
|
|
|
## Critérios de aceite
|
|
|
|
- [ ] Login retorna JWT válido e endpoints protegidos rejeitam requisição sem token
|
|
- [ ] Criar uma busca via API resulta, em segundos/minutos, em leads persistidos sem duplicação
|
|
- [ ] Listagem de leads suporta paginação e os filtros definidos
|
|
- [ ] Exportação CSV funciona com os filtros aplicados
|
|
- [ ] Fila de curadoria de ramos (`/leads/sem-ramo`) reflete corretamente os leads sem mapeamento
|
|
- [ ] Documentação Swagger acessível e atualizada
|