Skip to content

angelobordin/ledger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ledger

Plataforma de ingestão e categorização de extratos bancários — projeto de estudo focado em Java 21 + Spring Boot 3 + AWS, com arquitetura hexagonal e processamento assíncrono via SQS.

Construído para servir como referência prática para entrevistas em vagas que exigem Java backend e AWS. Não é "olá mundo".

Arquitetura

   ┌─────────────┐     ┌──────────┐     ┌─────────┐     ┌─────────────┐
   │  POST       │ ──▶ │   API    │ ──▶ │   S3    │     │  Postgres   │
   │ /extratos   │     │ Spring   │     │ (upload)│     │  (transac.) │
   └─────────────┘     │  Boot    │ ──▶ │   SQS   │     └─────────────┘
                       └──────────┘     │ (queue) │            ▲
                                        └────┬────┘            │
                                             ▼                 │
                                        ┌─────────┐            │
                                        │ Worker  │ ───────────┤
                                        │ (parse, │            │
                                        │categori │   ┌─────────────┐
                                        │  za)    │ ─▶│  DynamoDB   │
                                        └────┬────┘   │ (agregados) │
                                             ▼        └─────────────┘
                                        ┌─────────┐
                                        │   SNS   │ ─▶ email / webhook
                                        │ (event) │
                                        └─────────┘

Estilo: Hexagonal (ports & adapters).

  • domain/ — modelo puro, sem dependência de framework.
  • application/port/in — use cases (entrada).
  • application/port/out — contratos de infra (saída).
  • application/usecase — implementação dos use cases.
  • infrastructure/adapter/in/web — REST controllers.
  • infrastructure/adapter/in/messaging — listener SQS.
  • infrastructure/adapter/out/persistence — JPA / Postgres.
  • infrastructure/adapter/out/aws — S3, SQS, SNS, DynamoDB.

Stack

Camada Tecnologia
Linguagem Java 21 (LTS, com records, switch patterns, virtual threads)
Framework Spring Boot 3.3
AWS Spring Cloud AWS 3.2 + AWS SDK v2
Persistência PostgreSQL 16 + Spring Data JPA + Flyway
NoSQL DynamoDB (agregados mensais por categoria)
Mensageria SQS (com DLQ + redrive policy) e SNS
Storage S3 com pre-signed URLs (cliente faz upload direto, sem passar pelo backend)
Build Maven
Testes JUnit 5 + AssertJ + Testcontainers (Postgres + LocalStack)
Docs SpringDoc OpenAPI (Swagger UI em /swagger-ui.html)
Infra local Docker Compose + LocalStack

Decisões de design (relevantes para entrevista)

  • Pre-signed URL no upload: o cliente envia o arquivo direto pro S3, o backend não vira gargalo nem carrega o arquivo em memória. Padrão usado em produção.
  • Idempotência: o hash da combinação contaId + período + nomeArquivo evita reprocessar o mesmo extrato. Re-tentativas do SQS são seguras.
  • DLQ (Dead Letter Queue) configurada com maxReceiveCount = 3 — mensagens com falha repetida saem da fila principal e não bloqueiam outras.
  • Hexagonal: trocar Postgres por outro banco, ou SQS por Kafka, exige escrever um novo adapter — o domínio não muda. Mostra design responsável.
  • @Transactional apenas no use case — adapter de persistência não declara transação.
  • Records do Java 21 para DTOs/eventos/value objects imutáveis.
  • Sem Lombok: o projeto inteiro roda só com a linguagem (records + switch patterns + getters explícitos onde precisa). Demonstra que conhece o Java moderno.

Como rodar

Pré-requisitos

  • Java 21 (recomendo via SDKMAN: sdk install java 21.0.11-tem)
  • Maven 3.9+ (sdk install maven)
  • Docker

1. Subir infraestrutura local

docker compose up -d

Sobe:

  • Postgres em localhost:5436
  • LocalStack (S3 + SQS + SNS + DynamoDB) em localhost:4566
  • Script de inicialização cria bucket, filas, tópico e tabela DynamoDB automaticamente.

2. Rodar a aplicação

mvn spring-boot:run

A aplicação sobe em http://localhost:8090 no profile local (lê do LocalStack).

3. Importar um extrato

# 3.1 Pedir URL de upload
RESPONSE=$(curl -s -X POST http://localhost:8090/api/v1/extratos \
  -H 'Content-Type: application/json' \
  -d '{
    "contaId": "11111111-1111-1111-1111-111111111111",
    "periodoInicio": "2026-04-01",
    "periodoFim": "2026-04-30",
    "nomeArquivo": "abril-2026.csv"
  }')
echo $RESPONSE

EXTRATO_ID=$(echo $RESPONSE | jq -r .extratoId)
UPLOAD_URL=$(echo $RESPONSE | jq -r .uploadUrl)

# 3.2 Subir o CSV no S3 via pre-signed URL
curl -X PUT --data-binary @exemplos/extrato-exemplo.csv \
  -H 'Content-Type: text/csv' \
  "$UPLOAD_URL"

# 3.3 Disparar processamento (manual por enquanto — em prod seria S3 Event Notification)
# A mensagem já foi enviada na SQS pelo passo 3.1 — o worker já está processando.

# 3.4 Consultar
sleep 2
curl -s http://localhost:8090/api/v1/extratos/$EXTRATO_ID | jq

Comandos úteis

# Rodar testes
mvn test

# Inspecionar recursos do LocalStack
aws --endpoint-url=http://localhost:4566 s3 ls
aws --endpoint-url=http://localhost:4566 sqs list-queues
aws --endpoint-url=http://localhost:4566 sns list-topics
aws --endpoint-url=http://localhost:4566 dynamodb scan --table-name ledger-agregados

# Acessar Postgres
psql -h localhost -p 5436 -U ledger -d ledger

Roadmap de estudo

Etapa O que adiciona Conceito AWS / Java
1 (atual) Upload + processamento async + categorização S3 pre-signed, SQS, SNS, DynamoDB, Flyway
2 S3 Event Notification ⇒ SQS automático (sem disparo manual) EventBridge / S3 → SQS
3 Testes de integração com Testcontainers + LocalStack TestContainers, perfis de teste
4 Resiliência: retry, circuit breaker, idempotência forte Resilience4j, Outbox Pattern
5 Observabilidade: métricas Micrometer + traces OpenTelemetry CloudWatch, X-Ray
6 Autenticação JWT + Spring Security Cognito ou JWT próprio
7 Deploy: Docker image + ECS Fargate via Terraform IaC, ECS, ECR, IAM
8 Lambda Java 21 (SnapStart) para processamento AWS Lambda + Java

Por que cada serviço AWS

  • S3 — armazenamento de objetos. Padrão para arquivos. Pre-signed URLs são a forma certa de receber upload sem expor backend.
  • SQS — fila gerenciada. Desacopla a ingestão do processamento, permite retry automático e DLQ.
  • SNS — pub/sub. Fan-out: um evento "extrato processado" pode notificar múltiplos consumidores (email, BI, sistema legado) sem o produtor saber quem está ouvindo.
  • DynamoDB — NoSQL serverless. Bom para agregados pré-calculados com chave conhecida (consulta contaId + anoMes é O(1)).

About

Plataforma de ingestao de extratos bancarios - estudo Java 21 + Spring Boot 3 + AWS (S3, SQS, SNS, DynamoDB) com arquitetura hexagonal

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors