← Voltar para Jornada

Mapa da Arquitetura — PixHub

Infra, dominio, servicos e seguranca

100%

Legenda

Account
PixKey
Transaction
QrCode
AuditLog
WebhookConfig

Camada de Servico

Controller
Service
DTOs
Mapper / JWT
Filter / Exception

Seguranca (Fase 03)

User / Rate Limit
Encryption
Security Logger
XSS / Config

Infraestrutura (Fase 01)

PostgreSQL / Kafka
Spring Boot / Flyway
Docker
FK (chave estrangeira)
Auditoria (audita tudo)
PK Chave primaria
FK Chave estrangeira
ENUM Enumeracao
JSON Campo JSON
UNQ Indice unico
ENC Criptografado (AES-256)
i
Hover para detalhes
minimap
Fase 01 — Infraestrutura
🐳

Docker

Containerizacao

Orquestra todos os servicos via docker compose. Cada servico roda em seu container isolado.

docker-compose.yml Dockerfile Multi-stage Build
i
Um comando sobe tudo: banco, Kafka e app. Sem instalar nada na maquina. Padrao em toda empresa seria.
🗂

PostgreSQL 16

Banco de dados relacional

Armazena todas as entidades do dominio. Roda no Docker, porta 5432.

Relacional ACID Porta 5432
i
Banco mais usado em fintechs. Suporta JSON, indices avancados, transacoes ACID. As entidades da Fase 02 moram aqui.

Apache Kafka

Mensageria assincrona

Processa transacoes PIX de forma assincrona. Modo KRaft (sem Zookeeper).

KRaft Topics Porta 9092
i
Transaction muda de PENDING para PROCESSING quando Kafka consome a mensagem. Garante que o sistema nao trava esperando o banco.

Spring Boot 3.2

Framework da aplicacao

Framework que estrutura a API REST. Gerencia dependencias, seguranca, profiles e auto-configuracao.

Java 17 REST API Profiles Security
i
As entidades JPA, repositories e services da Fase 02/03 rodam dentro do Spring Boot. Ele e o "motor" da aplicacao.

Flyway

Migrations do banco

Controla versao do schema do banco. Migrations V1, V2... executam em ordem. Nunca alterar uma ja executada.

V1..V9 Versionado Imutavel
i
Cada entidade da Fase 02 tem uma migration correspondente. Flyway garante que dev, staging e prod tenham o mesmo schema.
Fase 02 — Dominio e Entidades

Account

Conta bancaria

id
PK
i
UUID em vez de auto-increment: impossivel de prever, sem conflito em sistemas distribuidos. Padrao em fintech.
holderName
holderDocument
ENC
i
CPF ou CNPJ do titular. Criptografado com AES-256-GCM no banco (Fase 03). A validacao de digitos verificadores e obrigatoria. Define se a conta e PF ou PJ.
bankCode
branch
accountNumber
accountType
ENUM
balance i
Em producao, seria BigDecimal para evitar erros de ponto flutuante (0.1 + 0.2 ≠ 0.3 com Double).
status
ENUM
createdAt
updatedAt

PixKey

Chave PIX

id
PK
keyType
ENUM
keyValue
UNQENC
i
UNIQUE — uma chave PIX e unica no Brasil inteiro. Criptografado com AES-256-GCM no banco (Fase 03). Com IV aleatorio, a UNIQUE constraint compara ciphertext — unicidade deve ser validada no Service.
accountId
FK
i
FK para Account. Regra do BACEN: max 5 chaves por conta PF, 20 por PJ.
status
ENUM
createdAt
deactivatedAt i
Soft delete — nunca deletamos dados em fintech. A chave e desativada, nao apagada. O BACEN pode perguntar se ela existiu.

Transaction

Transferencia PIX

id
PK
endToEndId
UNQ
i
Identificador unico no ecossistema PIX inteiro. Formato BACEN: E + ISPB + data + sequencial. E o "recibo" do PIX.
amount
description
senderAccountId
FK
receiverAccountId
FK
receiverPixKey i
Salvo como texto (nao FK) porque a chave pode ser desativada depois, mas o historico da transacao precisa existir.
status
ENUM
i
Maquina de estados: PENDING → PROCESSING → COMPLETED/FAILED. So COMPLETED pode virar REFUNDED (estorno).
idempotencyKey
UNQ
i
Evita cobrar duas vezes se o cliente clica "Pagar" duas vezes por lag. Mesma chave = mesma transacao, retorna resultado anterior.
createdAt
processedAt
failureReason

QrCode

QR Code PIX

id
PK
type
ENUM
i
STATIC = lojinha aceita qualquer valor. DYNAMIC = cobranca especifica com valor fixo e vencimento.
pixKey
merchantName
merchantCity
amount
txId i
Identificador da transacao vinculada ao QR. Obrigatorio para QR dinamico no padrao BRCode do BACEN.
description
expiresAt i
QR dinamico tem prazo. Expirado = nao pode mais pagar. Igual boleto que vence.
payload i
String EMV codificada no QR Code. Segue padrao BRCode do BACEN. E isso que o app do banco le ao escanear.
status
ENUM
createdAt
🔎

AuditLog

Registro de auditoria

id
PK
entityType i
Polymorphic association — a mesma tabela audita Account, PixKey, Transaction e todas as outras entidades.
entityId
action
ENUM
performedBy i
Quem executou a operacao. Em caso de fraude, e isso que a investigacao usa junto com ipAddress.
oldValue
JSON
i
Snapshot JSON do estado ANTES da alteracao. Ex: {"status": "ACTIVE"}.
newValue
JSON
i
Snapshot JSON do estado DEPOIS da alteracao. Ex: {"status": "BLOCKED"}.
ipAddress
createdAt

WebhookConfig

Notificacao para clientes

id
PK
accountId
FK
url i
O endpoint do cliente que recebe notificacoes POST quando eventos acontecem (ex: transacao completada).
events i
Lista de eventos que ativam o webhook. Ex: TRANSACTION_COMPLETED, KEY_REGISTERED.
secret i
Usado para assinar o payload com HMAC. O cliente verifica que a notificacao e legitima e nao de um atacante.
status
ENUM
createdAt
Camada de Servico (Account)
🔌

AccountController

Porta de entrada HTTP

Recebe requisicoes REST e delega para o Service. Nao tem logica de negocio — e um garcom que leva o pedido para a cozinha.

POST /accounts GET /{id} PUT /{id} PATCH /block DELETE /{id}
i
7 endpoints REST. Usa @Valid para validar DTOs antes de chamar o Service. Retorna ResponseEntity com status HTTP correto (201, 200, 204).
📦

DTOs

Objetos de transferencia

Separam o que o cliente envia/recebe da estrutura interna (Entity). Nunca expor a Entity diretamente na API.

CreateAccountRequest UpdateAccountRequest AccountResponse ErrorResponse
i
Request DTOs usam Bean Validation (@NotBlank, @Pattern). Response DTOs controlam quais campos o cliente ve. ErrorResponse padroniza TODAS as respostas de erro.

AccountService

Logica de negocio

O cerebro da aplicacao. Valida regras, executa operacoes, audita e retorna DTOs. Padrao: VALIDAR → EXECUTAR → AUDITAR → RETORNAR.

createAccount getById updateAccount blockAccount deactivateAccount
i
@Transactional garante atomicidade: se falhar no meio, tudo desfaz. @Transactional(readOnly=true) nos GETs otimiza performance.
🔄

AccountMapper

Tradutor DTO ↔ Entity

Converte entre formatos: o que o cliente envia (DTO) vira o que o banco entende (Entity), e vice-versa.

toEntity() toResponse() Static methods
i
Metodos estaticos — nao precisa criar instancia. toEntity() preenche campos default (status ACTIVE, balance 0). toResponse() copia campos da Entity para o DTO.

DocumentValidator

Validacao CPF/CNPJ

Valida CPF e CNPJ pelo algoritmo de digitos verificadores (modulo 11). Rejeita documentos com todos os digitos iguais.

isValidCpf() isValidCnpj() Modulo 11
i
Mesma validacao que a Receita Federal usa. 111.111.111-11 e sintaticamente valido mas falha no digito verificador. Chamado pelo AccountService antes de criar conta.
🛑

GlobalExceptionHandler

Tratamento central de erros

Intercepta TODA excecao da API e converte em resposta JSON padronizada (ErrorResponse). O cliente nunca ve um stack trace.

BusinessException → 4xx Validation → 400 Fallback → 500
i
@ControllerAdvice captura excecoes de TODOS os controllers. Logs: warn para 4xx (erro do cliente), error para 5xx (erro do servidor).

BusinessException

Hierarquia de excecoes

Classe base que todas as excecoes de negocio herdam. Contem httpStatus e errorCode. O Handler trata TODAS de uma vez.

ResourceNotFound 404 AlreadyExists 409 RuleViolation 422 AccountBlocked 403 InsufficientBalance 422
i
6 excecoes filhas. Cada uma define seu status HTTP. O Service lanca, o Handler captura e converte em ErrorResponse automaticamente.
🔎

AuditService

Registro de auditoria

Camera de seguranca do sistema: registra toda operacao de escrita no AuditLog. Nao bloqueia nada, so registra.

logCreate() logUpdate() logStatusChange() logDelete()
i
Usa ObjectMapper (Jackson) para serializar entidades em JSON nos campos oldValue/newValue. Se a serializacao falhar, usa toString() como fallback.
🔒

SecurityConfig

Cadeia de filtros completa

Orquestra toda a seguranca HTTP: JWT filter, rate limiting, CORS, security headers e CSP. API 100% stateless.

JwtFilter → RateLimit → Auth CORS (5173/4173/3000) Security Headers + CSP BCrypt PasswordEncoder
i
Toda request passa por: CORS → CSRF(off) → JwtFilter → RateLimitFilter → Authorization. /auth/** e publico, o resto exige JWT. Headers: nosniff, DENY, no-store, CSP.
👤

User

Usuario de autenticacao

id
PK
fullName
email
UNQ
password i
Hash BCrypt da senha — NUNCA texto puro. BCrypt inclui salt automatico. Resultado: "$2a$10$xK..."
role
ENUM
i
USER ou ADMIN. Define permissoes no @PreAuthorize. Default: USER.
status
ENUM
i
ACTIVE ou LOCKED. Bloqueado apos 5 tentativas falhas de login (brute force protection). Desbloqueia apos 30 min.
failedLoginAttempts i
Contador de tentativas falhas. Reseta ao fazer login com sucesso. Ao atingir 5, muda status para LOCKED.
lockedUntil i
Timestamp ate quando a conta esta bloqueada. NULL = conta ativa. Desbloqueio automatico quando LocalDateTime.now() ultrapassa.
accountId
FK
i
FK nullable para Account. Um usuario pode ter 0 ou 1 conta bancaria vinculada. A vinculacao e feita apos criar a conta.
createdAt
Fase 03 — Seguranca e Autenticacao
🔌

AuthController

Endpoints de autenticacao

Porta de entrada para registro, login e renovacao de tokens. Todos os endpoints sao publicos (nao exigem JWT).

POST /register (201) POST /login (200) POST /refresh (200)
i
Liberado no SecurityConfig: /api/v1/auth/**. Usa @Valid para validar DTOs. Retorna AuthResponse com accessToken + refreshToken.
📦

Auth DTOs

Objetos de autenticacao

Requests validados com Bean Validation e response padronizado com tokens JWT.

RegisterRequest LoginRequest RefreshTokenRequest AuthResponse
i
RegisterRequest: @NoHtml em fullName, @Email, @Size(min=8) na senha. AuthResponse: accessToken, refreshToken, expiresIn (segundos).

AuthService

Logica de autenticacao

Registro, login e refresh. Brute force protection: 5 tentativas → 30min lock. Mensagens genericas para impedir user enumeration.

register() login() refresh() Brute Force Protection
i
Padrao VALIDAR → EXECUTAR → AUDITAR → RETORNAR. Senhas BCrypt. Nunca diz "email nao existe" ou "senha errada" — sempre "Credenciais invalidas".
🔑

JwtService

Geracao e validacao JWT

Gera e valida tokens JWT com HMAC-SHA256. Access token (15min) + refresh token (7d) com rotacao.

generateAccessToken() generateRefreshToken() validateToken() HMAC-SHA256
i
Claims: sub (userId), email, role, type (access/refresh). Secret via env var JWT_SECRET. getTokenType() e getEmailFromToken() para validacao no refresh.
🛡

JwtAuthenticationFilter

Filtro de autenticacao JWT

OncePerRequestFilter que extrai Bearer token, valida com JwtService e preenche o SecurityContext com a identidade do usuario.

Bearer token SecurityContext OncePerRequestFilter
i
Posicao na cadeia: ANTES do AuthorizationFilter. Se token invalido, nao seta SecurityContext → AuthorizationFilter rejeita → EntryPoint retorna 401 JSON.

RateLimitingFilter

Controle de requisicoes

Token Bucket via Bucket4j. Limita por IP (auth) ou por usuario (demais). Headers: X-RateLimit-Limit, Remaining, Retry-After.

Auth: 5/min (IP) Transaction: 30/min Query: 60/min 429 Too Many Requests
i
Bucket4j com greedy refill. ConcurrentHashMap de buckets por chave. Posicao: DEPOIS do JwtFilter (precisa do SecurityContext para saber o usuario).
👁

SecurityEventLogger

Logs de seguranca

Logger dedicado com prefixo [SECURITY]. Registra IP + User-Agent automaticamente via RequestContextHolder.

LOGIN_SUCCESS/FAILED ACCOUNT_LOCKED REGISTRATION TOKEN_REFRESH
i
7 tipos de evento. Facilita busca no Kibana/Grafana por "[SECURITY]". Usado pelo AuthService em todos os eventos sensiveis.
🔐

EncryptedStringConverter

Criptografia AES-256-GCM

AttributeConverter JPA que cifra ao salvar e decifra ao ler. Transparente para Service e Controller.

AES-256-GCM IV aleatorio Auth Tag (integridade) Chave via env var
i
Aplicado em Account.holderDocument e PixKey.keyValue. Base64(IV + ciphertext + authTag). Chave: ENCRYPTION_KEY env var. Fail-fast se chave != 32 bytes.
🛡

@NoHtml + Validator

Protecao anti-XSS

Annotation customizada + ConstraintValidator. Rejeita HTML tags, event handlers e javascript: URLs em campos de texto.

Bean Validation Regex detection Reject strategy
i
Aplicado em holderName (Account) e fullName (User). Detecta: <script>, onclick=, javascript:, HTML entities. API bancaria nao precisa de HTML em nenhum campo.