Initial commit

This commit is contained in:
tiago
2026-10-01 11:00:47 -03:00
commit 9d2ab731ee
149 changed files with 11351 additions and 0 deletions
+41
View File
@@ -0,0 +1,41 @@
# 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