Skip to content

Latest commit

 

History

History
389 lines (315 loc) · 13.5 KB

File metadata and controls

389 lines (315 loc) · 13.5 KB

🏛️ Arquitetura e Conceitos - Payment Processor

📐 Diagrama de Arquitetura

┌─────────────────────────────────────────────────────────────────┐
│                         API Layer (REST)                        │
│                     PaymentController.java                      │
└────────────────────────┬───────────────────────────────────────┘
                         │
┌────────────────────────┴───────────────────────────────────────┐
│                    Application Layer (CQRS)                     │
├─────────────────────────────┬───────────────────────────────────┤
│   PaymentCommandService     │     PaymentQueryService           │
│   (Write Side)              │     (Read Side)                   │
└────────────────────────┬────┴──────────────────┬────────────────┘
                         │                       │
┌────────────────────────┴───────────────────────┴────────────────┐
│                       Domain Layer (DDD)                        │
│                                                                 │
│  ┌──────────────┐     ┌─────────────────────────────────┐     │
│  │   Payment    │────▶│       Domain Events             │     │
│  │  (Aggregate) │     │  - PaymentCreatedEvent          │     │
│  └──────────────┘     │  - PaymentValidatedEvent        │     │
│                       │  - PaymentAuthorizedEvent       │     │
│                       │  - PaymentCapturedEvent         │     │
│                       │  - PaymentCompletedEvent        │     │
│                       │  - PaymentFailedEvent           │     │
│                       │  - PaymentRefundedEvent         │     │
│                       └─────────────────────────────────┘     │
└────────────────────────┬───────────────────────────────────────┘
                         │
┌────────────────────────┴───────────────────────────────────────┐
│                   Infrastructure Layer                          │
│                                                                 │
│  ┌──────────────────┐              ┌──────────────────────┐    │
│  │   EventStore     │──────────────│ EventStoreRepository │    │
│  │  (Serialization) │              │      (JPA)           │    │
│  └──────────────────┘              └──────────────────────┘    │
│                                              │                 │
│                                    ┌─────────┴─────────┐       │
│                                    │  EventStoreEntity │       │
│                                    │    (Database)     │       │
│                                    └───────────────────┘       │
└─────────────────────────────────────────────────────────────────┘

🎯 Event Sourcing - Como Funciona

Conceito

Em vez de armazenar apenas o estado atual, armazenamos todos os eventos que levaram a esse estado.

Exemplo Prático

CRUD Tradicional:

Payment Table:
┌────┬──────────┬────────┬───────────┐
│ ID │ Customer │ Amount │  Status   │
├────┼──────────┼────────┼───────────┤
│  1 │ CUST-123 │ 100.00 │ COMPLETED │ ← Apenas estado final
└────┴──────────┴────────┴───────────┘

Event Sourcing:

Event Store:
┌────┬─────────────────────┬─────────┬────────────────────────────┐
│ ID │    Event Type       │ Version │         Payload            │
├────┼─────────────────────┼─────────┼────────────────────────────┤
│  1 │ PaymentCreated      │    0    │ {customer: "CUST-123", ... │
│  2 │ PaymentValidated    │    1    │ {...}                      │
│  3 │ PaymentAuthorized   │    2    │ {authCode: "AUTH-123"}     │
│  4 │ PaymentCaptured     │    3    │ {txnId: "TXN-456"}         │
│  5 │ PaymentCompleted    │    4    │ {...}                      │
└────┴─────────────────────┴─────────┴────────────────────────────┘
                                            ↓
                        Replay eventos para reconstruir estado
                                            ↓
                    Payment(status=COMPLETED, version=4)

Vantagens

  1. Auditoria Completa

    • Sabemos exatamente o que aconteceu e quando
    • Compliance e regulamentação
  2. Time-Travel Debugging

    • Podemos ver o estado em qualquer ponto no tempo
    • Útil para investigar bugs
  3. Replay de Eventos

    • Podemos reprocessar eventos
    • Criar novas projeções
  4. Event-Driven Architecture

    • Base para microsserviços
    • Comunicação assíncrona

🔄 CQRS - Command Query Responsibility Segregation

Conceito

Separar operações de escrita (Commands) e leitura (Queries).

Implementação no Projeto

Write Side (Commands):

@Service
public class PaymentCommandService {
    public PaymentDTO createPayment(CreatePaymentCommand cmd) {
        Payment payment = Payment.create(...);
        eventStore.save(payment);  // Gera eventos
        return toDTO(payment);
    }
    
    public void processPayment(String id) {
        Payment payment = eventStore.load(id);
        payment.validate();
        payment.authorize(...);
        payment.capture(...);
        payment.complete();
        eventStore.save(payment);  // Persiste eventos
    }
}

Read Side (Queries):

@Service
public class PaymentQueryService {
    public PaymentDTO getPayment(String id) {
        Payment payment = eventStore.load(id);
        return toDTO(payment);
    }
    
    public PaymentHistoryDTO getHistory(String id) {
        List<Events> events = eventStore.loadEvents(id);
        return buildHistory(events);
    }
}

Benefícios

  1. Escalabilidade

    • Write e Read podem escalar independentemente
    • Otimização específica para cada lado
  2. Performance

    • Read models podem ser otimizados (cache, denormalização)
    • Writes focam em consistência
  3. Flexibilidade

    • Múltiplas projeções do mesmo dado
    • Diferentes modelos para diferentes casos de uso

🔁 Saga Pattern

Conceito

Coordenar transações distribuídas através de uma série de transações locais.

Implementação - Fluxo de Pagamento

public void processPayment(String paymentId) {
    Payment payment = eventStore.load(paymentId);
    
    try {
        // Step 1: Validate
        payment.validate();
        eventStore.save(payment);
        
        // Step 2: Authorize
        String authCode = externalAuthService.authorize(...);
        payment.authorize(authCode);
        eventStore.save(payment);
        
        // Step 3: Capture
        String txnId = externalPaymentGateway.capture(...);
        payment.capture(txnId);
        eventStore.save(payment);
        
        // Step 4: Complete
        payment.complete();
        eventStore.save(payment);
        
    } catch (Exception e) {
        // Compensating Transaction
        payment.fail(e.getMessage(), "SAGA_FAILURE");
        eventStore.save(payment);
        throw e;
    }
}

Tipos de Saga

1. Orchestration (usado no projeto)

  • Um orquestrador central coordena o fluxo
  • Mais controle, mais acoplamento

2. Choreography

  • Cada serviço publica eventos
  • Outros serviços reagem
  • Menos controle, menos acoplamento

🏢 Domain-Driven Design (DDD)

Componentes no Projeto

1. Aggregate Root

public class Payment {
    private String id;  // Aggregate ID
    private PaymentStatus status;
    private List<DomainEvent> uncommittedEvents;
    
    // Business logic
    public void authorize(String code) {
        if (status != VALIDATED) {
            throw new IllegalStateException("...");
        }
        // Apply event
    }
}

2. Value Objects

public enum PaymentStatus {
    PENDING, VALIDATED, AUTHORIZED, ...
}

3. Domain Events

public abstract class DomainEvent {
    private final String eventId;
    private final Instant occurredAt;
    private final String aggregateId;
    // ...
}

4. Repository Pattern

public interface EventStoreRepository 
    extends JpaRepository<EventStoreEntity, Long> {
    List<EventStoreEntity> findByAggregateId(String id);
}

📊 Comparação: Antes vs Depois

Sistema de Biblioteca (Antigo)

Pontos Fracos:

  • ❌ Sem histórico de mudanças
  • ❌ Arquitetura simples demais
  • ❌ Sem testes
  • ❌ Persistência em arquivo texto
  • ❌ Sem API REST
  • ❌ Conceitos básicos apenas

Código:

public class Biblioteca {
    private ArrayList<Livro> livros;
    
    public void emprestar(int id) {
        for (Livro l : livros) {
            if (l.getId() == id) {
                l.setEmprestado(true);
                salvar();  // Sobrescreve arquivo
                return;
            }
        }
    }
}

Payment Processor (Novo)

Pontos Fortes:

  • ✅ Event Sourcing - histórico completo
  • ✅ CQRS - escalabilidade
  • ✅ Saga Pattern - transações distribuídas
  • ✅ DDD - design rico de domínio
  • ✅ Spring Boot - framework enterprise
  • ✅ Testes automatizados
  • ✅ API REST documentada
  • ✅ Docker ready
  • ✅ Patterns avançados

Código:

@Service
public class PaymentCommandService {
    public void processPayment(String id) {
        Payment payment = eventStore.load(id);
        
        // Saga Pattern
        payment.validate();
        payment.authorize(authCode);
        payment.capture(txnId);
        payment.complete();
        
        // Event Sourcing
        eventStore.save(payment);
    }
}

🎓 Conceitos para Entrevistas

Event Sourcing

P: O que é Event Sourcing?
R: É armazenar mudanças de estado como uma sequência de eventos em vez de apenas o estado atual. Permite auditoria completa e replay de eventos.

P: Quando usar Event Sourcing?
R: Quando precisar de:

  • Auditoria completa
  • Time-travel debugging
  • Event-driven architecture
  • Compliance regulatório

CQRS

P: Por que separar Commands e Queries?
R: Para escalar independentemente, otimizar cada lado separadamente, e ter flexibilidade em modelos de dados diferentes.

Saga Pattern

P: Como garantir consistência em transações distribuídas?
R: Usando Saga Pattern com compensating transactions. Se algo falha, executamos ações de compensação para desfazer mudanças.

DDD

P: O que é um Aggregate?
R: É um cluster de objetos de domínio que são tratados como uma unidade para mudanças de dados. Tem um Aggregate Root que garante consistência.


🚀 Próximos Níveis

Nível 1 (Atual) ✅

  • Event Sourcing básico
  • CQRS simples
  • Saga local

Nível 2 (Próximo)

  • Snapshots para performance
  • Projections (Read Models)
  • Kafka/RabbitMQ integration

Nível 3 (Avançado)

  • Distributed Saga
  • Event-driven microservices
  • CQRS com bancos separados
  • Event Store clustering

📚 Recursos para Aprofundar

  • Livros:

    • "Domain-Driven Design" - Eric Evans
    • "Implementing Domain-Driven Design" - Vaughn Vernon
    • "Microservices Patterns" - Chris Richardson
  • Artigos:

    • Martin Fowler - Event Sourcing
    • Martin Fowler - CQRS
    • Microservices.io - Saga Pattern
  • Cursos:

    • DDD & Event Sourcing (Pluralsight)
    • Spring Boot Microservices (Udemy)