first commit
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
# 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
|
||||
Reference in New Issue
Block a user