Arquitetura do Sistema

Arquitetura e Tecnologias

Entenda como as tecnologias se relacionam, o fluxo de requisições, cache e acesso aos bancos de dados.

Stack Tecnológico

Framework

  • NestJS 11.x
  • TypeScript
  • Node.js

Bancos de Dados

  • MongoDB (Mongoose + pool)
  • PostgreSQL (TypeORM + pool)

Cache & Mensageria

  • Redis (ioredis)
  • Apache Kafka

Storage & APIs

  • MinIO (S3 Compatible)
  • GraphQL (Apollo)
  • REST API

Autenticação

  • JWT (Passport)
  • Argon2id
  • Login social
  • Active Directory

Serviços

  • Graylog (Logging GELF)
  • SMTP / MailHog (Email)
  • WhatsApp (Evolution API)
  • Terminus (/health)

Configurações e Environment Variables

Todas as configurações são centralizadas através de arquivos de config em src/config/ e acessadas via ConfigService. As variáveis de ambiente são carregadas automaticamente.

Arquivos de Config

  • app.config.ts - Configurações da aplicação
  • database.config.ts - MongoDB e PostgreSQL (inclui pool)
  • redis.config.ts - Cache Redis
  • kafka.config.ts - Mensageria Kafka
  • jwt.config.ts - Autenticação JWT
  • argon2.config.ts - Hash de senhas
  • google-oauth.config.ts - Google OAuth2
  • facebook-oauth.config.ts - Facebook OAuth2
  • twitter-oauth.config.ts - X / Twitter OAuth2 (PKCE)
  • github-oauth.config.ts - GitHub OAuth2
  • figma-oauth.config.ts - Figma OAuth2
  • linkedin-oauth.config.ts - LinkedIn OpenID Connect
  • slack-oauth.config.ts - Slack OpenID Connect
  • atlassian-oauth.config.ts - Atlassian OAuth 2.0 (3LO)
  • gitlab-oauth.config.ts - GitLab OAuth2
  • bitbucket-oauth.config.ts - Bitbucket OAuth2
  • discord-oauth.config.ts - Discord OAuth2
  • twitch-oauth.config.ts - Twitch OAuth2
  • steam-openid.config.ts - Steam OpenID 2.0
  • reddit-oauth.config.ts - Reddit OAuth2
  • amazon-oauth.config.ts - Amazon Login with Amazon
  • patreon-oauth.config.ts - Patreon OAuth2
  • dropbox-oauth.config.ts - Dropbox OAuth2
  • metamask-auth.config.ts - MetaMask SIWE (EIP-4361)
  • ad-ldap.config.ts - Active Directory LDAP/LDAPS (AD DS on-prem)
  • apple-oauth.config.ts - Apple Sign In (OIDC form_post)
  • smtp.config.ts - Email SMTP
  • minio.config.ts - Storage MinIO
  • graylog.config.ts - Logging Graylog (GELF)
  • graphql.config.ts - GraphQL
  • whatsapp.config.ts - WhatsApp API

Exemplo de Uso

TypeScriptConfigService
constructor(private configService: ConfigService) {}

// Acessar configuração
const mongoUri = this.configService.get('database.mongoUri');
const redisHost = this.configService.get('redis.host');
const jwtSecret = this.configService.get('jwt.secret');

Fluxo de Requisição

1. Cliente faz requisição HTTP

Requisição chega ao servidor NestJS com headers (Authorization, Content-Type, etc.)

2. Security (IP / catch-all)

SecurityModule registra rotas de API inválidas e pode bloquear IPs (catch-all em production/staging). API admin em /api/v1/security — veja a página Security.

3. Autenticação JWT

JwtAuthGuard valida o token JWT. Rotas marcadas com @Public() são ignoradas.

4. Autorização por Roles

RolesGuard verifica se o usuário possui as roles necessárias definidas via @Roles()

5. Interceptor de Cache

TypeOrmCacheInterceptor ou MongooseCacheInterceptor verifica se há dados em cache no Redis

6. Controller/Resolver

Requisição chega ao controller (REST) ou resolver (GraphQL)

7. Service Layer

Lógica de negócio é executada no service, que utiliza repositories para acesso a dados

8. Repository Pattern

O service do módulo injeta o repositório escolhido — PostgreSQL (TypeORM) e/ou MongoDB (Mongoose) — conforme a necessidade do domínio. Os dois repositórios por domínio permitem um único banco ou CQRS (commands em um, queries em outro).

9. Logging (Graylog)

Interceptor e exception filter enviam logs estruturados em GELF para o Graylog (quando GRAYLOG_ENABLED=true).

10. Resposta e Cache

Dados são retornados ao cliente e, se aplicável, armazenados no Redis para próximas requisições

Sistema de Cache

Como Funciona

O sistema de cache utiliza Redis como camada intermediária para armazenar resultados de consultas frequentes, reduzindo a carga nos bancos de dados e melhorando o tempo de resposta.

Interceptors de Cache

  • TypeOrmCacheInterceptor - Cache para consultas TypeORM (PostgreSQL)
  • MongooseCacheInterceptor - Cache para consultas Mongoose (MongoDB)
  • CacheService - Serviço centralizado para gerenciar cache

Configuração Redis

EnvironmentRedis Config
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0
REDIS_TTL=3600  # Time to Live em segundos

Fluxo de Cache

  1. Requisição chega ao interceptor de cache
  2. Interceptor verifica se existe chave no Redis
  3. Se existe: retorna dados do cache (cache hit)
  4. Se não existe: executa query no banco, armazena no Redis e retorna (cache miss)
  5. Dados expiram automaticamente após TTL configurado

Persistência: Mongo, Postgres e CQRS-ready

Padrão do template

O template mantém MongoDB e PostgreSQL no stack. Cada domínio pode ter dois repositórios; o service escolhe um banco ou ambos (CQRS). Não há split command/query obrigatório — a escolha é por módulo.

Connection pools

Ambas as conexões usam pool explícito (config em database.config.ts). O endpoint GET /health inclui metadados do pool nos checks de postgres e mongo.

EnvironmentPool
POSTGRES_POOL_MAX=10
POSTGRES_POOL_MIN=2
POSTGRES_POOL_IDLE=30000
POSTGRES_POOL_TIMEOUT=5000

MONGO_POOL_MAX=10
MONGO_POOL_MIN=0
MONGO_POOL_IDLE=30000
MONGO_POOL_TIMEOUT=5000

PostgreSQL

  • • Schema relacional e tipado (TypeORM)
  • • Repository: ResourcePostgresRepository
  • • Use como única fonte de verdade ou como lado de queries em CQRS

MongoDB

  • • Schema flexível e documental (Mongoose)
  • • Repository: ResourceMongoRepository
  • • Use sozinho ou como lado de commands em CQRS

Exemplo: um banco só

TypeScriptResourceService
constructor(
  private readonly postgresRepo: ResourcePostgresRepository,
) {}

async create(data: CreateResourceDto) {
  return this.postgresRepo.create(data);
}

async findAll() {
  return this.postgresRepo.findAll();
}

Exemplo: ativar CQRS

Injete ambos os repositórios no service: commands em um banco, queries no outro. Opcionalmente sincronize com Kafka para consistência eventual.

TypeScriptResourceService (CQRS)
constructor(
  private readonly mongoRepo: ResourceMongoRepository,      // commands
  private readonly postgresRepo: ResourcePostgresRepository, // queries
) {}

async create(data: CreateResourceDto) {
  const resource = await this.mongoRepo.create(data);
  // publicar evento Kafka para projetar no Postgres...
  return resource;
}

async findAll() {
  return this.postgresRepo.findAll();
}

Mongo ou Postgres

Você pode usar só Postgres, só Mongo, ou ambos (CQRS). A escolha é no service/módulo, sem remover a infraestrutura do outro banco do projeto.

Como as Tecnologias se Relacionam

Diagrama de Relacionamento

NestJS

Framework Core

MongoDB

Disponível / CQRS

PostgreSQL

Persistência / queries

Redis

Cache

Kafka

Mensageria

MinIO

Storage

Graylog

Logs GELF

  • NestJS ↔ MongoDB/PostgreSQL: Framework se comunica com bancos através de Mongoose e TypeORM; o service escolhe qual repositório usar
  • NestJS ↔ Redis: Cache interceptors utilizam Redis para armazenar resultados
  • NestJS ↔ Kafka: Eventos e mensagens são publicados/consumidos via Kafka (útil para projetar dados em CQRS)
  • NestJS ↔ MinIO: Upload e download de arquivos via API S3-compatible
  • NestJS ↔ Graylog: Logs estruturados via GELF HTTP (interceptor + exception filter)
  • MongoDB ↔ PostgreSQL (opcional): Em um desenho CQRS, sincronização via eventos Kafka ou processos assíncronos