Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,5 @@ dist

# TernJS port file
.tern-port

.idea
214 changes: 165 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,198 @@
# Yape Code Challenge :rocket:
# Solución Técnica - Sistema de Transacciones con Anti-Fraude

Our code challenge will let you marvel us with your Jedi coding skills :smile:.
La estructura del proyecto es hexagonal, con dos microservicios principales: `Transaction` y `Antifraud`.

Don't forget that the proper way to submit your work is to fork the repo and create a PR :wink: ... have fun !!
## 📋 Stack Tecnológico

- [Problem](#problem)
- [Tech Stack](#tech_stack)
- [Send us your challenge](#send_us_your_challenge)
- **Java 17** - Lenguaje base
- **Spring Boot 3.5.11** - Framework principal
- **Spring WebFlux** - Programación reactiva no bloqueante
- **R2DBC** - Operaciones reactivas con base de datos
- **Apache Kafka** - Mensajería asíncrona
- **PostgreSQL** - Base de datos persistente

# Problem
---

Every time a financial transaction is created it must be validated by our anti-fraud microservice and then the same service sends a message back to update the transaction status.
For now, we have only three transaction statuses:
## 🏗️ Arquitectura

<ol>
<li>pending</li>
<li>approved</li>
<li>rejected</li>
</ol>
### Gestión de Concurrencia
- **Bloqueo Optimista**: Maneja actualizaciones concurrentes sin bloquear lecturas
- **Control de Duplicados**: Prevención de transacciones duplicadas

Every transaction with a value greater than 1000 should be rejected.
### Tipos de Transacción
- `1` = Depósito
- `2` = Retiro

```mermaid
flowchart LR
Transaction -- Save Transaction with pending Status --> transactionDatabase[(Database)]
Transaction --Send transaction Created event--> Anti-Fraud
Anti-Fraud -- Send transaction Status Approved event--> Transaction
Anti-Fraud -- Send transaction Status Rejected event--> Transaction
Transaction -- Update transaction Status event--> transactionDatabase[(Database)]
## 🔄 Flujo de Comunicación

### Servicio de Transacciones (Transaction)
**Produce a**: `anti-fraud-topic`
- Datos de transacción recién creada (estado: `PENDING`)
- Inmediatamente después de persistir envia el mensaje a Kafka para validación

**Consume de**: `transaction-topic`
- Estado final de validación (`APPROVED` / `REJECTED`)
- Acción: Actualiza estado en base de datos

### Servicio Anti-Fraude (Antifraud)
**Consume de**: `anti-fraud-topic`
- Transacción a validar
- Rechaza transacciones con valor > $1000

**Produce a**: `transaction-topic`
- Resultado de validación con ID de transacción y nuevo estado
- Después de procesar cada mensaje, envía el resultado a Kafka para que Transaction actualice su estado

---

## 🚀 Cómo Ejecutar

Se tiene 2 modos de ejecución: Local (Infraestructura con docker y microservicios corriendo en tu máquina) o Automatizado (con todo el sistema dockerizado).

### 💻 MODO LOCAL

#### 1. Levantar infraestructura
```powershell
docker-compose -f docker-compose.local.yml up -d
```

**Incluye:**
- PostgreSQL (puerto 5432)
- Zookeeper (puerto 2181)
- Kafka (puerto 9092)

#### 2. Ejecutar microservicios desde el IDE

### Requisitos Previos

### Java 17
Este proyecto requiere **Java 17**. Asegúrate de tener instalado JDK 17 y configurado en tu variable de entorno `JAVA_HOME`.

#### Windows
```powershell
# Verificar versión de Java
java -version

# Configurar JAVA_HOME (reemplaza la ruta con tu instalación de JDK 17)
setx JAVA_HOME "C:\Program Files\Java\jdk-17"
setx PATH "%JAVA_HOME%\bin;%PATH%"

# Reinicia tu terminal para aplicar cambios
```

#### Mac
```bash
# Verificar versión de Java
java -version

# Configurar JAVA_HOME en ~/.zshrc o ~/.bash_profile
export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-17.jdk/Contents/Home
export PATH=$JAVA_HOME/bin:$PATH

# Aplicar cambios
source ~/.zshrc # o source ~/.bash_profile
```

**Opción A - Terminal:**
```powershell
# Terminal 1 - Antifraud
cd antifraud
./mvnw spring-boot:run

# Terminal 2 - Transaction
cd transaction
./mvnw spring-boot:run
```

**Opción B - IntelliJ IDEA:**
- Click derecho en `AntifraudApplication.java` → Run
- Click derecho en `TransactionApplication.java` → Run

---

### 🐳 MODO AUTOMATIZADO (Docker Completo)

#### Levantar todo el sistema
```powershell
docker-compose up --build -d
```

# Tech Stack
**Incluye:**
- PostgreSQL
- Zookeeper
- Kafka
- Antifraud (Dockerizado, puerto 8081)
- Transaction (Dockerizado, puerto 8080)

#### Detener
```powershell
docker-compose down
```

---

## 📍 Puertos y Servicios

| Servicio | Puerto | URL |
|----------|--------|-----|
| Transaction | 8080 | http://localhost:8080 |
| Antifraud | 8081 | http://localhost:8081 |
| PostgreSQL | 5432 | localhost:5432 |
| Kafka | 9092 | localhost:9092 |
| Zookeeper | 2181 | localhost:2181 |


<ol>
<li>Node. You can use any framework you want (i.e. Nestjs with an ORM like TypeOrm or Prisma) </li>
<li>Any database</li>
<li>Kafka</li>
</ol>
---

We do provide a `Dockerfile` to help you get started with a dev environment.
## 📮 Pruebas con POSTMAN

You must have two resources:
### 1️⃣ Crear Transacción

1. Resource to create a transaction that must containt:
**POST** `http://localhost:8080/transactions`

**Body (JSON):**
```json
{
"accountExternalIdDebit": "Guid",
"accountExternalIdCredit": "Guid",
"accountExternalIdDebit": "6085462b-f1da-48a0-8f11-72ee428b2a32",
"accountExternalIdCredit": "1cb43a09-01a7-4019-b683-589b6b00ea58",
"tranferTypeId": 1,
"value": 120
"value": 900
}
```

2. Resource to retrieve a transaction
**Response (201 CREATED):**
```json
{
"transactionExternalId": "47f62081-95c7-483b-a000-91c0e391f696"
}
```

---

### 2️⃣ Obtener Transacción

**GET** `http://localhost:8080/transactions/{transactionExternalId}`

**Parámetro:**
- `transactionExternalId`: ID de la transacción a consultar

**Response (200 OK):**
```json
{
"transactionExternalId": "Guid",
"transactionExternalId": "47f62081-95c7-483b-a000-91c0e391f696",
"transactionType": {
"name": ""
"name": "DEPOSIT"
},
"transactionStatus": {
"name": ""
"name": "APPROVED"
},
"value": 120,
"createdAt": "Date"
"value": 900.00,
"createdAt": "2026-03-01T19:11:52.070044"
}
```

## Optional

You can use any approach to store transaction data but you should consider that we may deal with high volume scenarios where we have a huge amount of writes and reads for the same data at the same time. How would you tackle this requirement?

You can use Graphql;

# Send us your challenge
---

When you finish your challenge, after forking a repository, you **must** open a pull request to our repository. There are no limitations to the implementation, you can follow the programming paradigm, modularization, and style that you feel is the most appropriate solution.
### 📌 Notas Importantes

If you have any questions, please let us know.
- **tranferTypeId**: `1` = Depósito, `2` = Retiro
2 changes: 2 additions & 0 deletions antifraud/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/mvnw text eol=lf
*.cmd text eol=crlf
33 changes: 33 additions & 0 deletions antifraud/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
HELP.md
target/
.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/

### VS Code ###
.vscode/
3 changes: 3 additions & 0 deletions antifraud/.mvn/wrapper/maven-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
wrapperVersion=3.3.4
distributionType=only-script
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.12/apache-maven-3.9.12-bin.zip
15 changes: 15 additions & 0 deletions antifraud/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM eclipse-temurin:17-jdk-alpine AS build
WORKDIR /app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
COPY src src
RUN chmod +x mvnw
RUN ./mvnw clean package -DskipTests

FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=build /app/target/antifraud-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8081
ENTRYPOINT ["java", "-jar", "app.jar"]

Loading