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
10 changes: 10 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 16 additions & 0 deletions .idea/checkstyle-idea.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

479 changes: 479 additions & 0 deletions .idea/dbnavigator.xml

Large diffs are not rendered by default.

11 changes: 11 additions & 0 deletions .idea/encodings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions .idea/jarRepositories.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

97 changes: 39 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,63 @@
# Yape Code Challenge :rocket:
# Yape Code Challenge - Quarkus

Our code challenge will let you marvel us with your Jedi coding skills :smile:.

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

- [Problem](#problem)
- [Tech Stack](#tech_stack)
- [Send us your challenge](#send_us_your_challenge)

# 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:

<ol>
<li>pending</li>
<li>approved</li>
<li>rejected</li>
</ol>

Every transaction with a value greater than 1000 should be rejected.

```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)]
```
Sistema de transacciones financieras con validación anti-fraude usando Kafka y arquitectura hexagonal.

# Tech Stack

<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>
- **Quarkus 3.8** - Framework Java
- **PostgreSQL 15** - Base de datos
- **Apache Kafka** - Mensajería de eventos
- **Redis** - Cache e idempotencia
- **Arquitectura Hexagonal** - Clean Architecture

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

You must have two resources:
### Crear Transacción

1. Resource to create a transaction that must containt:
```bash
POST http://localhost:8080/transactions
Content-Type: application/json

```json
{
"accountExternalIdDebit": "Guid",
"accountExternalIdCredit": "Guid",
"accountExternalIdDebit": "550e8400-e29b-41d4-a716-446655440000",
"accountExternalIdCredit": "550e8400-e29b-41d4-a716-446655440001",
"tranferTypeId": 1,
"value": 120
"value": 500
}
```

2. Resource to retrieve a transaction

**Respuesta (201 Created):**
```json
{
"transactionExternalId": "Guid",
"transactionExternalId": "generated-uuid",
"transactionType": {
"name": ""
"name": "Transfer"
},
"transactionStatus": {
"name": ""
"name": "pending"
},
"value": 120,
"createdAt": "Date"
"value": 500,
"createdAt": "2024-01-15T10:30:00"
}
```

## 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?
### Consultar Transacción

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.
```bash
GET http://localhost:8080/transactions/{transactionExternalId}
```

If you have any questions, please let us know.
**Respuesta (200 OK):**
```json
{
"transactionExternalId": "uuid",
"transactionType": {
"name": "Transfer"
},
"transactionStatus": {
"name": "approved"
},
"value": 500,
"createdAt": "2024-01-15T10:30:00"
}
```
6 changes: 6 additions & 0 deletions antifraud-service/antifraud-service.iml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<module version="4">
<component name="CheckStyle-IDEA-Module" serialisationVersion="2">
<option name="activeLocationsIds" />
</component>
</module>
91 changes: 91 additions & 0 deletions antifraud-service/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.yape</groupId>
<artifactId>yape-challenge</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>

<artifactId>antifraud-service</artifactId>
<name>Anti-Fraud Service</name>
<description>Microservice for validating transactions against fraud rules</description>

<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-reactive-messaging-kafka</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-redis-client</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-fault-tolerance</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-smallrye-health</artifactId>
</dependency>

<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5-mockito</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>smallrye-reactive-messaging-in-memory</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.yape.antifraud.domain.model;

import java.math.BigDecimal;
import java.util.UUID;

public class TransactionToValidate {

private UUID transactionExternalId;
private BigDecimal value;

public TransactionToValidate() {
}

public TransactionToValidate(UUID transactionExternalId, BigDecimal value) {
this.transactionExternalId = transactionExternalId;
this.value = value;
}

public UUID getTransactionExternalId() {
return transactionExternalId;
}

public void setTransactionExternalId(UUID transactionExternalId) {
this.transactionExternalId = transactionExternalId;
}

public BigDecimal getValue() {
return value;
}

public void setValue(BigDecimal value) {
this.value = value;
}
}
Loading