Destaque

LetterDrop

Plataforma de newsletters construída com NestJS e microsserviços, utilizando RabbitMQ para processamento assíncrono, rastreamento idempotente de entregas e tratamento resiliente de falhas.

Principais pontos
  • Arquitetura com dois microsserviços NestJS
  • Comunicação assíncrona através de RabbitMQ
  • Processamento de newsletters em lotes
  • Entrega idempotente com checkpoint de processamento
  • Dead Letter Queue para mensagens que falharam
  • Tratamento de bounces através do Resend
  • Controle de acesso com JWT e RBAC
  • Docker Compose para infraestrutura completa
Tecnologias utilizadas
LetterDrop

Visão geral

O LetterDrop é uma plataforma de newsletters desenvolvida para explorar arquitetura de microsserviços, comunicação assíncrona e processamento resiliente de mensagens.

A aplicação possui uma API principal responsável por autenticação, assinantes e newsletters, além de um microsserviço separado responsável pelo envio dos emails.

O projeto utiliza RabbitMQ para desacoplar a criação de uma campanha do processamento potencialmente demorado de milhares de emails.

Como funciona

Quando um administrador envia uma newsletter, a API não realiza todos os envios diretamente.

Primeiro, a newsletter muda para o estado QUEUED e a API publica um evento no RabbitMQ.

O Mailer consome esse evento e começa a processar os assinantes em lotes de 5, utilizando concorrência e rate limiting configuráveis.

Cada entrega é registrada individualmente. Caso o processo seja interrompido, o Mailer consegue continuar a partir do checkpoint armazenado sem precisar reenviar tudo novamente.

Arquitetura

A arquitetura é composta por dois serviços NestJS:

API:

  • REST API
  • Autenticação e autorização
  • Gerenciamento de assinantes
  • Gerenciamento de newsletters
  • Persistência PostgreSQL
  • Publicação de eventos no RabbitMQ

Mailer:

  • Consumidores RabbitMQ
  • Processamento dos envios
  • Integração com Resend
  • Rastreamento das entregas
  • Tratamento de falhas e DLQ

PostgreSQL é utilizado como banco compartilhado, mas acessado diretamente apenas pela API.

RabbitMQ funciona como camada de comunicação entre os serviços, utilizando exchanges, filas, consumidores e Dead Letter Queue.

Funcionalidades

O projeto possui diversos fluxos voltados para confiabilidade e observabilidade:

  • Cadastro e confirmação de assinantes
  • Cancelamento de inscrição
  • Criação e gerenciamento de newsletters
  • Autenticação JWT
  • RBAC para ADMIN e SUPER_ADMIN
  • Envio assíncrono de newsletters
  • Processamento em lotes
  • Controle de entregas individuais
  • Retomada através de checkpoints
  • Dead Letter Queue
  • Tratamento de emails rejeitados pelo provedor
  • Estados DRAFT, QUEUED, PROCESSING, SENT, PARTIAL e FAILED
  • Estados PENDING, CONFIRMED, UNSUBSCRIBED e BOUNCED

Decisões técnicas

A separação entre API e Mailer evita que uma operação potencialmente longa bloqueie a API.

RabbitMQ permite que o trabalho permaneça na fila mesmo quando o Mailer está indisponível.

O rastreamento individual das entregas e o checkpoint evitam o reprocessamento desnecessário de assinantes já processados.

Mensagens que não conseguem ser processadas são encaminhadas para uma Dead Letter Queue, permitindo análise posterior das falhas.

Tokens de confirmação e cancelamento são armazenados utilizando SHA-256 em vez do valor original.

Processo

O fluxo principal pode ser resumido como:

Admin → API NestJS → RabbitMQ → Mailer NestJS → Resend → rastreamento da entrega

Em caso de falha:

Consumer → Dead Letter Exchange → Dead Letter Queue → DeadLettersConsumer

Esse fluxo permite separar a responsabilidade de receber a solicitação da responsabilidade de executar os envios.

Aprendizados

O LetterDrop foi um dos projetos mais aprofundados do portfólio e serviu para estudar conceitos de arquitetura distribuída que vão além de uma API REST tradicional.

Os principais aprendizados envolveram microsserviços, RabbitMQ, processamento assíncrono, idempotência, checkpoints, Dead Letter Queue, comunicação interna entre serviços, rate limiting e tratamento de falhas.

Também houve contato com documentação de APIs, testes unitários e e2e, health checks, Docker e validação de configuração com Zod.