# 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