# Motor de Envio de E-mails (Email Engine)

## Visão Geral

O motor de envio de e-mails (*Email Engine*) é a camada responsável pela entrega de mensagens em massa, suporte a múltiplos remetentes (SMTP e AWS SES), sanitização de código HTML, rastreamento de engajamento (aberturas) e processamento resiliente de bounces/complaints.

---

## Architecture de Transportes (Providers)

O disparo de mensagens utiliza a interface desacoplada `MailProvider` (`src/modules/campaigns/providers/mail-provider.ts`). A fábrica `MailProviderFactory` seleciona a implementação concreta em tempo de execução de acordo com o `SenderProvider` cadastrado no remetente da campanha:

```
                  ┌─────────────────────┐
                  │ MailProviderFactory │
                  └──────────┬──────────┘
                             │
       ┌─────────────────────┼─────────────────────┐
       ▼                     ▼                     ▼
┌──────────────┐     ┌──────────────┐     ┌──────────────────┐
│ SesMail      │     │ Nodemailer   │     │ InMemoryMail     │
│ Provider     │     │ MailProvider │     │ Provider         │
└──────┬───────┘     └──────┬───────┘     └────────┬─────────┘
       │                    │                      │
       ▼                    ▼                      ▼
    AWS SES              SMTP /                Testes
    API v2               Mailpit               Unitários
```

### 1. AWS SES Provider (`SesMailProvider`)
- **Uso**: Ambientes de produção com alto volume de envio.
- **Tecnologia**: SDK v2 oficial da AWS (`@aws-sdk/client-sesv2`).
- **Recursos**: Suporta identidades de domínio validadas via DKIM, envio com Configuration Set ativado para tracking nativo da AWS e controle de taxa por segundo (`SES_SEND_RATE_PER_SECOND`).

### 2. SMTP Provider (`NodemailerMailProvider`)
- **Uso**: Provedores de e-mail tradicionais (SendGrid, Mailgun, servidores SMTP próprios) e ambiente de desenvolvimento local (Mailpit).
- **Segurança de Credenciais**: A senha SMTP é armazenada no banco de dados com **criptografia reversível AES-256-GCM** (`src/shared/infra/crypto/crypto.ts`). A descriptografia ocorre estritamente na memória durante a inicialização do transporte Nodemailer, garantindo que credenciais não fiquem expostas em texto puro.

### 3. In-Memory Provider (`InMemoryMailProvider`)
- **Uso**: Suíte de testes unitários com Vitest.
- **Funcionamento**: Simula a aceitação de e-mails gravando as mensagens enviadas em um array em memória (`sentMails`), permitindo asserções sem realizar chamadas de rede.

---

## Fluxo de Disparo de Campanha

Ao acionar a Server Action `dispatchCampaignAction(campaignId)`:

```
[DispatchCampaignUseCase]
       │
       ├─► 1. Valida se a campanha existe e está em status DRAFT
       │
       ├─► 2. Carrega o remetente (Sender) e descriptografa a senha SMTP se necessário
       │
       ├─► 3. Busca os contatos ativos da lista vinculada (excluindo UNSUBSCRIBED e BOUNCED)
       │
       ├─► 4. Filtra a lista removendo e-mails presentes na SuppressedEmail (supressão)
       │
       ├─► 5. Cria os registros de log iniciais em CampaignLog com status PENDING
       │
       ├─► 6. Atualiza o status da campanha para SENDING
       │
       ├─► 7. Executa o disparo concorrente em lotes via runInBatches() e RateLimiter:
       │       │
       │       ├── Injeta o pixel de rastreamento no HTML (se SMTP)
       │       ├── Injeta o cabeçalho/link List-Unsubscribe (RFC 8058)
       │       ├── Converte HTML para texto puro (Plain Text fallback)
       │       ├── Envia via MailProvider.sendMail()
       │       └── Atualiza CampaignLog para SUCCESS (com messageId) ou FAILED (com errorMessage)
       │
       └─► 8. Define o status final da campanha (SENT ou COMPLETED_WITH_ERRORS)
```

---

## Sanitização e Formatação do E-mail

Antes do envio, o conteúdo da mensagem passa pelas entidades de domínio em `src/modules/campaigns/entities/`:

1. **Sanitização de HTML (`sanitize-html.ts`)**:
   - Limpa o HTML da campanha utilizando a biblioteca `sanitize-html`.
   - Permite tags de layout seguras (tabelas, imagens, links, formatação) e remove scripts maliciosos ou atributos de eventos inline (`onclick`, etc.).
2. **Conversão para Texto Puro (`html-to-plain-text.ts`)**:
   - Converte a mensagem HTML em uma versão alternativa `text/plain` usando `cheerio`.
   - Melhora a pontuação do e-mail em filtros Anti-SPAM dos provedores de destino.
3. **Construção do Conteúdo (`build-email-content.ts`)**:
   - Injeta o cabeçalho `List-Unsubscribe` e `List-Unsubscribe-Post: List-Unsubscribe=One-Click`.
   - Injeta o link visual de descadastro no rodapé do e-mail: `${APP_BASE_URL}/unsubscribe/${contactId}`.
   - Adiciona a tag de imagem para o pixel de rastreamento de aberturas quando enviado via SMTP.

---

## Tracking de Aberturas e Eventos

### 1. Open Tracking via Pixel (Envios SMTP)
Para envios via SMTP, uma tag de imagem de 1x1 pixel transparente é adicionada ao final do corpo HTML:
```html
<img src="${APP_BASE_URL}/api/track/open/${campaignLogId}.gif" width="1" height="1" alt="" style="display:none" />
```
Quando o cliente de e-mail renderiza a imagem, a requisição atinge `GET /api/track/open/[token]`, que registra a abertura no banco via `RecordEmailOpenUseCase` e responde uma imagem GIF de 43 bytes com cache desabilitado.

### 2. Open Tracking e Eventos Nativos (Envios AWS SES)
Envios realizados via AWS SES registram aberturas, entregas, bounces e reclamações diretamente nos servidores da AWS. Esses eventos são publicados no tópico AWS SNS e recebidos na rota `POST /api/webhooks/ses`:

- **Delivery**: Atualiza o evento em `EmailEvent` e confirma a entrega.
- **Bounce (Hard Bounce)**: Atualiza o status do log para falha, altera o status do contato para `BOUNCED` e insere o e-mail na tabela `suppressed_emails`.
- **Complaint (SPAM)**: Insere o e-mail na lista de supressão com motivo `COMPLAINT`.

---

## Domínios e Verificação DNS (AWS SES)

Para garantir a entregabilidade dos e-mails enviados pelo SES:

1. O usuário cadastra o domínio no painel (`createDomainAction`).
2. O sistema aciona `SesIdentityProvider` para criar a identidade no SES e obter os registros CNAME para **DKIM (DomainKeys Identified Mail)** e TXT/MX para **Custom MAIL FROM Domain**.
3. O utilitário `build-dns-records.ts` formata a lista de registros DNS que o usuário deve adicionar no seu provedor de DNS (Cloudflare, GoDaddy, Route53, etc.).
4. A verificação periódica ocorre via `verifyDomainAction` ou pelo cron de polling `POST /api/domains/poll`.

---

## Suppression List (Lista de Supressão)

A lista de supressão (`suppressed_emails`) protege a reputação do remetente bloqueando envios para endereços conhecidos por falhas definitivas:

- **Razões de Supressão (`SuppressionReason`)**:
  - `BOUNCE`: Hard bounce retornado pelo provedor de destino (caixa postal inexistente).
  - `COMPLAINT`: O destinatário marcou a mensagem como SPAM.
  - `MANUAL`: O e-mail foi adicionado manualmente à lista de bloqueio.
- Antes de disparar qualquer e-mail, a aplicação consulta a tabela `suppressed_emails` e remove imediatamente os destinatários afetados, evitando penalizações nas taxas de entrega da AWS.

---

## Rate Limiting e Processamento em Lotes

Para evitar o bloqueio de portas ou o estouro de limites de taxa de envio da API AWS SES:

- **`runInBatches` (`src/modules/campaigns/providers/run-in-batches.ts`)**: Divide o array de contatos em lotes menores e processa as promessas de envio com um nível de concorrência configurável.
- **`RateLimiter` (`src/modules/campaigns/providers/rate-limiter.ts`)**: Implementa o algoritmo de balde de tokens (*token bucket*), garantindo que os disparos não ultrapassem o limite definido na variável `SES_SEND_RATE_PER_SECOND`.
