90 lines
4.5 KiB
Markdown
90 lines
4.5 KiB
Markdown
# Etapa 7/8 — Motor de Alertas (BullMQ)
|
|
|
|
## Contexto do projeto
|
|
|
|
Continuação do **SeConectai Vendas**. Já existem: setup, auth com RLS,
|
|
painel master completo, integrações Evolution API/e-mail com serviço
|
|
central de envio (`AlertDispatchService`), CRUD de customers/produtos, e
|
|
o módulo completo de vendas/parcelas/dashboards.
|
|
|
|
Esta é a etapa que **automatiza** o que até agora só existia como
|
|
endpoint manual: verificação de vencimentos e disparo de alertas, nos
|
|
dois níveis do sistema (master→tenant e tenant→customer).
|
|
|
|
## Tarefas
|
|
|
|
1. **Infraestrutura de filas**
|
|
- Configurar `@nestjs/bullmq` conectado ao Redis já disponível no
|
|
`docker-compose`.
|
|
- Criar duas filas: `alertas-mensalidade` (master→tenant) e
|
|
`alertas-cobranca` (tenant→customer).
|
|
- Criar um processo/worker separado do processo web principal (pode
|
|
ser o mesmo container em dev, mas documentar como se separaria em
|
|
produção — ex: `main.ts` vs `worker.ts`, ou um segundo serviço no
|
|
`docker-compose` chamado `worker` rodando o mesmo build com um
|
|
comando diferente).
|
|
|
|
2. **Módulo `alert-templates`**
|
|
- CRUD de `alert_templates`:
|
|
- Nível master (`MasterGuard`): templates padrão da plataforma
|
|
(`tenant_id = null`), tipo `mensalidade_tenant`.
|
|
- Nível tenant (`TenantGuard`, role `tenant_admin`): templates
|
|
próprios, tipo `cobranca_cliente` (e outros tipos que fizerem
|
|
sentido, ex: `venda_confirmada`, `lembrete_vencimento`). Se o
|
|
tenant não tiver template próprio para um tipo/canal, usar o
|
|
template padrão do master como fallback.
|
|
- Implementar renderização de placeholders (`{{nome}}`, `{{valor}}`,
|
|
`{{vencimento}}`, etc — listar todos os placeholders suportados por
|
|
tipo de template em um arquivo de constantes, documentado).
|
|
|
|
3. **Job diário: `mensalidade_tenant`**
|
|
- Cron (ex: todo dia às 8h, horário configurável via env) que:
|
|
1. Roda a lógica equivalente ao endpoint
|
|
`POST /master/faturas/atualizar-atrasadas` (marca faturas
|
|
vencidas como `atrasado`, tenant vira `inadimplente`).
|
|
2. Para toda `tenant_faturas` com vencimento em N dias (configurável,
|
|
ex: 3 dias antes) ou já vencida e ainda sem alerta hoje, enfileira
|
|
um job na fila `alertas-mensalidade` com os dados necessários.
|
|
- Worker da fila `alertas-mensalidade`: busca template
|
|
(`mensalidade_tenant`, canal `whatsapp` e/ou `email` conforme
|
|
configurado), renderiza, chama `AlertDispatchService`, grava
|
|
resultado em `alert_logs`, atualiza `tenant_faturas.alerta_enviado_em`.
|
|
|
|
4. **Job diário: `cobranca_cliente`** (por tenant)
|
|
- Mesmo padrão do job acima, mas iterando `sale_payments` de todos os
|
|
tenants ativos: marca atrasadas, enfileira alerta para parcelas
|
|
próximas do vencimento ou já atrasadas (respeitando
|
|
`alerta_enviado_em` para não notificar duas vezes no mesmo dia).
|
|
- Usa a instância WhatsApp e config de e-mail **do tenant dono da
|
|
venda**, não a do master.
|
|
|
|
5. **Idempotência e resiliência**
|
|
- Garantir que um mesmo job não dispare o mesmo alerta duas vezes
|
|
(checar `alerta_enviado_em` antes de enfileirar, e novamente antes
|
|
de enviar, dentro do worker, para lidar com concorrência).
|
|
- Configurar retry com backoff exponencial no BullMQ para falhas
|
|
transitórias de envio (ex: Evolution API fora do ar), com limite de
|
|
tentativas (ex: 3) e log do erro final em `alert_logs.erro`.
|
|
- Endpoint de observabilidade: `GET /master/alertas/logs` e
|
|
`GET /tenant/alertas/logs` para consultar `alert_logs` com filtros
|
|
(canal, status, período).
|
|
|
|
## Critérios de aceite
|
|
|
|
- [ ] Worker processa as duas filas de forma independente do processo
|
|
web (documentado como escalar workers separadamente)
|
|
- [ ] Template do tenant sobrepõe o padrão do master quando existe; usa
|
|
fallback quando não existe
|
|
- [ ] Placeholders são substituídos corretamente na renderização
|
|
- [ ] Job diário marca faturas/parcelas atrasadas corretamente
|
|
- [ ] Alerta de mensalidade chega no WhatsApp/e-mail do tenant em teste
|
|
controlado (vencimento simulado para "hoje")
|
|
- [ ] Alerta de cobrança chega no WhatsApp/e-mail do customer, usando a
|
|
instância/config do tenant correto (testar com 2 tenants
|
|
diferentes)
|
|
- [ ] Mesmo alerta não é disparado duas vezes no mesmo dia (testar
|
|
rodando o job duas vezes seguidas)
|
|
- [ ] Falha de envio é reprocessada com retry e, após esgotar tentativas,
|
|
fica registrada em `alert_logs` com erro
|
|
- [ ] Endpoints de consulta de logs funcionam com os filtros esperados
|