An open API service indexing awesome lists of open source software.

https://github.com/diegomaiasantos/dotnet-engineering-challenge

Desafio técnico .NET com tratamento de duplicidade, retry e concorrência em processamento de pagamentos.
https://github.com/diegomaiasantos/dotnet-engineering-challenge

challenge csharp dotnet

Last synced: about 2 months ago
JSON representation

Desafio técnico .NET com tratamento de duplicidade, retry e concorrência em processamento de pagamentos.

Awesome Lists containing this project

README

          

# Desafio Técnico – Processamento de Pagamentos

## ❌ O que estava errado no código original

A implementação original apresentava alguns problemas importantes:

- **Processamento de eventos duplicados:** o mesmo `Id` poderia ser processado mais de uma vez.
- **Ausência de retry:** em caso de falha no método `Pagar`, o pagamento era ignorado sem nova tentativa.
- **Exceções ignoradas:** o bloco `catch` estava vazio, ocultando falhas e dificultando o diagnóstico.
- **Falta de retorno estruturado:** não havia forma de identificar quais pagamentos falharam.

---

## ✅ O que foi alterado e por quê

- **Controle de duplicidade:**
Foi utilizado `ConcurrentDictionary` para garantir que cada `Id` seja processado apenas uma vez, inclusive em cenário concorrente.

- **Implementação de retry:**
Cada pagamento é tentado até 3 vezes antes de ser considerado falha, tratando possíveis instabilidades do serviço externo.

- **Processamento simultâneo (diferencial):**
Foi utilizado `Parallel.ForEach` para processar múltiplos pagamentos em paralelo.

- **Thread safety:**
- `ConcurrentDictionary` para controle de IDs
- `ConcurrentBag` para armazenar falhas
- `lock` para proteger a soma do total (tipo `decimal` não é thread-safe)

- **Retorno estruturado:**
Foi criado um objeto de resultado contendo o total processado e a lista de falhas, permitindo melhor controle e visibilidade.

---

## 📊 Decisões de implementação

### 🔎 Forma de reportar falhas

Optei por **retornar os pagamentos que falharam** dentro do objeto de resultado, ao invés de utilizar apenas logs ou lançar exceções.

**Motivos da escolha:**

- Permite que o processamento continue mesmo com falhas pontuais
- Preserva o valor total processado com sucesso
- Dá visibilidade completa das falhas ao consumidor do método
- Mantém a solução mais flexível, permitindo que a camada superior decida como tratar os erros

---

### 🧱 Criação de classes e estrutura

Foram criados os seguintes objetos auxiliares:

- `ResultadoProcessamento`: encapsula o total processado e a lista de falhas
- `PagamentoFalhou`: representa um pagamento que não foi processado após todas as tentativas

**Motivo:**

Melhorar a organização, legibilidade e clareza da resposta do método, evitando retornos simples que não representam todo o estado do processamento.

---

### ⚙️ Versão do .NET

O projeto original estava configurado para **.NET 10**.

Para execução no ambiente disponível, a solução foi adaptada para **.NET 8**, mantendo total compatibilidade com a lógica implementada e sem impacto no comportamento esperado.

---

## 🚀 O que faria a mais se tivesse mais tempo

- Implementação de testes automatizados cobrindo cenários de sucesso, retry e falha definitiva
- Adição de logging estruturado para rastreamento de erros
- Separação do serviço de pagamento via interface para facilitar testes
- Configuração externa do número de tentativas (retry)
- Criação de versões separadas para processamento sequencial e paralelo