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
111 changes: 111 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# ============================================
# Spring Boot (Java + Maven)
# ============================================

# Compiled class files
*.class
*.jar
*.war
*.ear

# Logs
*.log
logs/
spring.log

# Temporary files
*.tmp
*.bak
*.swp
*.swo
*.old
*.orig

# ============================================
# Maven
# ============================================
target/
.mvn/
!.mvn/wrapper/maven-wrapper.jar
.settings/
dependency-reduced-pom.xml
release.properties
pom.xml.tag
pom.xml.releaseBackup
pom.xml.versionsBackup
pom.xml.next
pom.xml.backup
buildNumber.properties

# ============================================
# IntelliJ IDEA
# ============================================
.idea/
*.iml
*.iws
out/
.idea_modules/
.idea/workspace.xml
.idea/tasks.xml
.idea/dictionaries
.idea/httpRequests
.idea/caches/
.idea/libraries/

# ============================================
# VS Code (opcional si usas ambos IDEs)
# ============================================
.vscode/
.history/

# ============================================
# Environment / Configuration
# ============================================
.env
*.env.local
*.key
*.pem
*.crt
*.jks
*.p12
*.der

# Spring configuration files (keep templates only)
application-*.yml
application-*.yaml
application-*.properties
!application-example.yml
!application-example.yaml
!application-example.properties

# ============================================
# Test / Coverage
# ============================================
test-output/
surefire-reports/
jacoco.exec
reports/
coverage/

# ============================================
# OS files
# ============================================
# macOS
.DS_Store
.AppleDouble
.LSOverride

# Windows
Thumbs.db
ehthumbs.db
Desktop.ini

# Linux
*~

# ============================================
# Misc
# ============================================
bin/
tmp/
.cache/
200 changes: 167 additions & 33 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
# Yape Code Challenge :rocket:
# Transaction Service – Yape Code Challenge

Our code challenge will let you marvel us with your Jedi coding skills :smile:.
Este proyecto implementa un **microservicio de transacciones** desarrollado con **Spring Boot 3**, siguiendo el enfoque de **Arquitectura Hexagonal (Ports & Adapters)** y un **flujo event-driven con Kafka**.

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

- [Yape Code Challenge :rocket:](#yape-code-challenge-rocket)
- [Problem](#problem)
- [Tech Stack](#tech-stack)
- [Optional](#optional)
- [Send us your challenge](#send-us-your-challenge)
Todos los endpoints intercambian datos en **JSON** y el sistema está preparado para ejecutarse **localmente con Docker Compose**.

---

# Problem

Expand All @@ -31,54 +28,191 @@ Every transaction with a value greater than 1000 should be rejected.
Anti-Fraud -- Send transaction Status Rejected event--> Transaction
Transaction -- Update transaction Status event--> transactionDatabase[(Database)]
```
---

# Tech Stack
## Arquitectura

<ol>
<li>Java. You can use any framework you want</li>
<li>Any database</li>
<li>Kafka</li>
</ol>
El proyecto sigue **Arquitectura Hexagonal**, separando claramente responsabilidades:

```
├── application
│ ├── dto
│ ├── service
│ └── usecase
├── domain
│ ├── model
│ └── port
├── infrastructure
│ ├── inbound
│ │ ├── rest
│ │ └── kafka
│ ├── outbound
│ │ ├── persistence
│ │ └── kafka
│ └── config
```

---

## Ejecución local (sin Docker)

### Requisitos
- Java 17
- Maven 3.9+
- PostgreSQL
- Kafka + Zookeeper

### Compilar y ejecutar tests
```bash
mvn clean compile
mvn test
mvn verify
```

Reporte JaCoCo:
```
target/site/jacoco/index.html
```
## Docker Compose (PostgreSQL + Kafka + Transaction Service + Antifraud)

### Requisitos
- Docker y Docker Compose

### 1) Construir el `.jar`
Desde la raíz del proyecto (donde está el `pom.xml`):

```bash
mvn clean package
```

El ejecutable jar se genera en:

```
target/transaction-service-0.0.1.jar
```

> empaquetar mas pruebas unitarias & cobertura:
> ```bash
> mvn clean verify
> ```

## ***Antifraud Service***

El servicio de **Antifraud** se encuentra implementado en un repositorio independiente y se integra con este microservicio mediante eventos Kafka.

Repositorio:
https://github.com/alessandrojre/antifraud-service

En el entorno local, el `docker-compose` levanta automáticamente este servicio para simular el flujo completo:
Transaction Service → Kafka → Antifraud Service → Kafka → Transaction Service.

We do provide a `Dockerfile` to help you get started with a dev environment.

You must have two resources:
## Levantar el ecosistema con Docker Compose

1. Resource to create a transaction that must containt:
Ubícate en la carpeta `devops` (donde está el `docker-compose.yml`) y ejecuta:

```bash
cd devops
docker compose up --build
```

Para ejecutar en segundo plano:

```bash
docker compose up -d --build
```
Ver contenedores activos:

```bash
docker ps
```
Para ver logs:

```bash
docker compose logs -f
```

Para detener y eliminar contenedores:

```bash
docker compose down
```

Para eliminar también el volumen de Postgres:

```bash
docker compose down -v
```

---

## Probar endpoints REST

### Crear transacción
```bash
curl --location --request POST 'http://localhost:8080/transactions' \
--header 'Content-Type: application/json' \
--data-raw '{
"accountExternalIdDebit": "11111111-1111-1111-1111-111111111111",
"accountExternalIdCredit": "22222222-2222-2222-2222-222222222222",
"tranferTypeId": 1,
"value": 150.75
}'
```

Response:
```json
{
"accountExternalIdDebit": "Guid",
"accountExternalIdCredit": "Guid",
"tranferTypeId": 1,
"value": 120
"transactionExternalId": "83a3d905-ee35-4201-9958-0fde4d7267b8"
}
```
---



2. Resource to retrieve a transaction
### Obtener transacción por ID
```bash
curl --location --request GET \
'http://localhost:8080/transactions/{transactionExternalId}'
```

Response:
```json
{
"transactionExternalId": "Guid",
"transactionExternalId": "83a3d905-ee35-4201-9958-0fde4d7267b8",
"transactionType": {
"name": ""
"name": "TRANSFER"
},
"transactionStatus": {
"name": ""
"name": "APPROVED"
},
"value": 120,
"createdAt": "Date"
"value": 150.75,
"createdAt": "2025-12-29T00:00:00Z"
}
```

## Optional
---

## Docker Compose

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?
Levantar todo el entorno:
```bash
docker-compose up --build
```

You can use Graphql;
Servicios:
- Transaction Service → 8080
- Antifraud Service → 8081
- PostgreSQL → 5432
- Kafka → 9092

# 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.
## Stack Tecnológico

If you have any questions, please let us know.
- Java 17
- Spring Boot 3.5
- PostgreSQL
- Kafka
- Docker
- JUnit 5 + Mockito + AssertJ + JaCoCo
16 changes: 16 additions & 0 deletions devops/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
FROM eclipse-temurin:17-jre-alpine

RUN addgroup -S spring && adduser -S spring -G spring
USER spring

WORKDIR /app

ARG JAR_FILE=../target/*.jar
COPY ${JAR_FILE} app.jar

ENV JAVA_OPTS=""
ENV SPRING_PROFILES_ACTIVE=default

EXPOSE 8080

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
13 changes: 13 additions & 0 deletions devops/antifraud/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
FROM eclipse-temurin:17-jre-alpine

RUN addgroup -S spring && adduser -S spring -G spring
USER spring

WORKDIR /app

COPY antifraud-service-0.0.1.jar app.jar

ENV JAVA_OPTS=""
EXPOSE 8081

ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
Loading