Skip to content
Closed
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
Binary file added .DS_Store
Binary file not shown.
16 changes: 14 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ bower_components
build/Release

# Dependency directories
node_modules/
jspm_packages/

# TypeScript v1 declaration files
Expand Down Expand Up @@ -80,7 +79,7 @@ typings/

# Nuxt.js build / generate output
.nuxt
dist
*/dist

# Gatsby files
.cache/
Expand All @@ -102,3 +101,16 @@ dist

# TernJS port file
.tern-port

# subfolders
/ms-transactions/application.log
/ms-transactions/error.log

/ms-fraud-detector/application.log
/ms-fraud-detector/error.log

/ms-fraud-detector/*.env
/ms-fraud-detector/*.env

/ms-fraud-detector/node_modules/
/ms-transactions/node_modules/
146 changes: 85 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,106 @@
# Yape Code Challenge :rocket:
# Installation Guide

Our code challenge will let you marvel us with your Jedi coding skills :smile:.
## Candidate: Alexander Esteban Joffre Aguirre

Don't forget that the proper way to submit your work is to fork the repo and create a PR :wink: ... have fun !!
## Architecture
![Architecture Diagram](./images/architecture-diagram.png)

- [Problem](#problem)
- [Tech Stack](#tech_stack)
- [Send us your challenge](#send_us_your_challenge)
This solution is composed by 2 micro services. They comunicate between each others using Kafka's topics. For this, both services auto connect when they start and read their respective topics.

# Problem
The flow to create and validate if a transaction is a possible fraud or not is:

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:
1. Send POST request to ***/transactions/create*** in ms-transactions. It creates the transaction into db and publish a message into **trx-created** Kafka's topic

<ol>
<li>pending</li>
<li>approved</li>
<li>rejected</li>
</ol>
2. Then, when the ***ms-fraud-detector*** notices that a new message is published into this topic, it proceeds to validate the transaction amount.
1. If it's higher than 1000, then publish a message into **trx-rejected** Kafka's topic.
2. If it's less than or equals to 1000, then publish a message into **trx-approved** Kafka's topic.

Every transaction with a value greater than 1000 should be rejected.
3. So, when ***ms-transactions*** notices that a new message is published into any of them, it proceeds to update the transaction record depending on if it's approved or rejected. Finally, it sets the ***isClosed*** with **true** to indicate that the record couldn't be updated again.

```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)]
```

# Tech Stack
## Technologies used
- NestJS Framework
- Kafka
- MongoDB

<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.
## 1. Run Dependencies with docker
Execute the following command:
```bash
docker-compose up
```

You must have two resources:
## 2. Set up kafka topics

1. Resource to create a transaction that must containt:
Run the following commands to create the 3 required kafka services to ensure the correct application behavior:

```json
{
"accountExternalIdDebit": "Guid",
"accountExternalIdCredit": "Guid",
"tranferTypeId": 1,
"value": 120
}
- `trx-created`
```bash
docker exec -it kafka /opt/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper:2181 --replication-factor 1 --partitions 1 --topic trx-created
```

2. Resource to retrieve a transaction

```json
{
"transactionExternalId": "Guid",
"transactionType": {
"name": ""
},
"transactionStatus": {
"name": ""
},
"value": 120,
"createdAt": "Date"
}
- `trx-approved`
```bash
docker exec -it kafka /opt/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper:2181 --replication-factor 1 --partitions 1 --topic trx-approved
```

## Optional
- `trx-rejected`
```bash
docker exec -it kafka /opt/kafka/bin/kafka-topics.sh --create --zookeeper zookeeper:2181 --replication-factor 1 --partitions 1 --topic trx-rejected
```

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?
## 3. Prepare transactions microservice
### 3.1 Move into the micro service for transactions folder
```bash
cd ms-transactions
```
### 3.2 Install dependencies
```bash
npm i
```
### 3.3 Set up initial data into Mongo DB
```bash
npm run migrations
```
### 3.4 Configure environment variables
create a file in this directory called .env and copy the following code into this and save it:
```
APP_PORT=3000
APP_ID=ms-transactions

You can use Graphql;
MONGODB_CONNECTION_URL=mongodb://localhost:27017/yape-anti-fraud

# Send us your challenge
KAFKA_BROKER=localhost:9092
KAFKA_CLIENT_ID=yape
KAFKA_GROUP_ID=yape
KAFKA_SUBSCRIBE_TOPICS=trx-rejected,trx-approved
```
### 3.4 Initiate service
```bash
npm run start
```
**NOTE**: to see the full documentation, once it was initiated, you can visite the *[ms-transactions API Docs](http://localhost:3000/docs)*

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.
## 4. Prepare fraud detector microservice
### 4.1 Move into the fraud-detector for transactions folder
```bash
cd ..
cd ms-fraud-detector
```
### 4.2 Install dependencies
```bash
npm i
```
### 4.3 Configure environment variables
create a file in this directory called .env and copy the following code into this and save it:
```
APP_PORT=3001
APP_ID=ms-fraud-detector

If you have any questions, please let us know.
KAFKA_BROKER=localhost:9092
KAFKA_CLIENT_ID=yape
KAFKA_GROUP_ID=yape
KAFKA_SUBSCRIBE_TOPICS=trx-created
```
### 4.4 Initiate service
```bash
npm run start
```
35 changes: 19 additions & 16 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,28 @@
version: "3.7"
services:
postgres:
image: postgres:14
mongodb_container:
container_name: mongodb
image: mongo:latest
ports:
- "5432:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- 27017:27017
zookeeper:
image: confluentinc/cp-zookeeper:5.5.3
environment:
ZOOKEEPER_CLIENT_PORT: 2181
container_name: zookeeper
image: wurstmeister/zookeeper:latest
ports:
- "2181:2181"
kafka:
image: confluentinc/cp-enterprise-kafka:5.5.3
image: wurstmeister/kafka:latest
container_name: kafka
ports:
- "9092:9092"
depends_on: [zookeeper]
environment:
KAFKA_ZOOKEEPER_CONNECT: "zookeeper:2181"
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:9093,OUTSIDE://localhost:9092
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
KAFKA_LISTENERS: INSIDE://0.0.0.0:9093,OUTSIDE://0.0.0.0:9092
KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
KAFKA_BROKER_ID: 1
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
KAFKA_JMX_PORT: 9991
ports:
- 9092:9092
volumes:
- /var/run/docker.sock:/var/run/docker.sock
Binary file added images/architecture-diagram.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ms-fraud-detector/.DS_Store
Binary file not shown.
7 changes: 7 additions & 0 deletions ms-fraud-detector/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
APP_PORT=
APP_ID=

KAFKA_BROKER=
KAFKA_CLIENT_ID=
KAFKA_GROUP_ID=
KAFKA_SUBSCRIBE_TOPICS=
25 changes: 25 additions & 0 deletions ms-fraud-detector/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module.exports = {
parser: '@typescript-eslint/parser',
parserOptions: {
project: 'tsconfig.json',
tsconfigRootDir: __dirname,
sourceType: 'module',
},
plugins: ['@typescript-eslint/eslint-plugin'],
extends: [
'plugin:@typescript-eslint/recommended',
'plugin:prettier/recommended',
],
root: true,
env: {
node: true,
jest: true,
},
ignorePatterns: ['.eslintrc.js'],
rules: {
'@typescript-eslint/interface-name-prefix': 'off',
'@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/explicit-module-boundary-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
4 changes: 4 additions & 0 deletions ms-fraud-detector/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}
8 changes: 8 additions & 0 deletions ms-fraud-detector/nest-cli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"sourceRoot": "src",
"compilerOptions": {
"deleteOutDir": true
}
}
Loading