Skip to content

feat: Implemented microservices architecture with Service & Repository patterns #456

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
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
149 changes: 95 additions & 54 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,123 @@
# Yape Code Challenge :rocket:
# Microservices Project With Kafka And NestJS

Our code challenge will let you marvel us with your Jedi coding skills :smile:.
Yape project using a microservices architecture, implementing the Service and Repository pattern, with writes handled by Kafka and reads managed through GraphQL (GraphJS), integrating Redis for performance optimization.

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

- [Problem](#problem)
- [Tech Stack](#tech_stack)
- [Send us your challenge](#send_us_your_challenge)
To Make Requests To The API, You Need To Authenticate Using A `Bearer Token` Generate With `ms-users` . Ensure You Have A Valid Access Token Before Making Requests.

# Problem
### Authentication Headers

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:
Include The Following Header In All Your HTTP Requests:

<ol>
<li>pending</li>
<li>approved</li>
<li>rejected</li>
</ol>
```plaintext
Authorization: Bearer <your-token-here>
```

## Microservices

- **ms-transaction:** Manages Transactions.
- **ms-antifraud:** Handles Fraud Detection.
- **ms-users:** Handles security in requests.

## Challenge Using Following Technologies:

- NestJS
- Typescript
- Kafka
- Kafka UI
- Postgres
- Docker
- DockerHub
- Dockerfile
- CI/CD
- Swagger
- JWT
- Redis
- Graphql


## 1 Initial Proyect

Root Directory `docker-compose.yml` And Run File To Create Docker Containers.

```
docker-compose up
```

## 2 Initial Microservices User

Enter To Directory `ms-users` To Install Dependencies And To Start The Server.

```
npm run install
npm run start:dev
```

## 3 Initial Microservices Transaction

Every transaction with a value greater than 1000 should be rejected.
Enter To Directory `ms-transaction` To Install Dependencies And To Start The Server.

```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)]
```
npm run install
npm run start:dev
```

# Tech Stack
## 4 Initial Microservices Antifraud

<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>
Enter To Directory `ms-antifraud` To Install Dependencies And To Start The Server.

We do provide a `Dockerfile` to help you get started with a dev environment.
```
npm run install
npm run start:dev
```

You must have two resources:
## Docker Hub

1. Resource to create a transaction that must containt:
## Images Docker Hub

```json
- **ms-transaction**: [Docker Hub - ms-transaction](https://hub.docker.com/r/rafamandevops/ms-transaction)
- **ms-antifraud**: [Docker Hub - ms-antifraud](https://hub.docker.com/r/rafamandevops/ms-antifraud)
- **ms-users**: [Docker Hub - ms-users](https://hub.docker.com/r/rafamandevops/ms-users)


# API Documentation
## Ms Transaction

### Show API Swagger Documentation

```
GET /docs
```

### Create Transaction
```
POST /transactions
```
```
{
"accountExternalIdDebit": "Guid",
"accountExternalIdCredit": "Guid",
"accountExternalIdDebit": "{{$guid}}",
"accountExternalIdCredit": "{{$guid}}",
"tranferTypeId": 1,
"value": 120
"value": {{randomFloatValue}}
}
```

2. Resource to retrieve a transaction

```json
### Get Transaction
```
GET /transactions/c9e286f7-0d78-4d16-8e21-a720324b1f50
```
```
{
"transactionExternalId": "Guid",
"transactionExternalId": "c9e286f7-0d78-4d16-8e21-a720324b1f50",
"transactionType": {
"name": ""
"name": 1
},
"transactionStatus": {
"name": ""
"name": "APPROVED"
},
"value": 120,
"createdAt": "Date"
"value": 298.26,
"createdAt": "2024-08-17T02:22:06.182Z"
}
```

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

If you have any questions, please let us know.
34 changes: 32 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,16 @@ services:
ports:
- "5432:5432"
environment:
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=qwerty12345@@
volumes:
- postgres-vol:/var/lib/postgresql/data

zookeeper:
image: confluentinc/cp-zookeeper:5.5.3
environment:
ZOOKEEPER_CLIENT_PORT: 2181

kafka:
image: confluentinc/cp-enterprise-kafka:5.5.3
depends_on: [zookeeper]
Expand All @@ -23,3 +27,29 @@ services:
KAFKA_JMX_PORT: 9991
ports:
- 9092:9092

kafkagui:
image: provectuslabs/kafka-ui:latest
ports:
- "8087:8080"
restart: always
environment:
- KAFKA_CLUSTERS_0_NAME=testerick
- KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS=kafka:29092
depends_on:
- kafka

redis:
image: redis:latest
container_name: redis-server
ports:
- "6379:6379"
command: ["redis-server", "--appendonly", "yes"]
volumes:
- redis-vol:/data
environment:
- REDIS_PASSWORD=Clarita24@@

volumes:
postgres-vol:
redis-vol:
1 change: 1 addition & 0 deletions ms-antifraud/.env.stage.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PORT=4000
25 changes: 25 additions & 0 deletions ms-antifraud/.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',
},
};
56 changes: 56 additions & 0 deletions ms-antifraud/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# compiled output
/dist
/node_modules
/build

# Logs
logs
*.log
npm-debug.log*
pnpm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# OS
.DS_Store

# Tests
/coverage
/.nyc_output

# IDEs and editors
/.idea
.project
.classpath
.c9/
*.launch
.settings/
*.sublime-workspace

# IDE - VSCode
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json

# dotenv environment variable files
.env
.env.development.local
.env.test.local
.env.production.local
.env.local

# temp directory
.temp
.tmp

# Runtime data
pids
*.pid
*.seed
*.pid.lock

# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
4 changes: 4 additions & 0 deletions ms-antifraud/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}
18 changes: 18 additions & 0 deletions ms-antifraud/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
FROM node:20

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

RUN npm run build

ENV STAGE=dev

EXPOSE 3000


CMD ["npm", "run", "start:prod"]
Loading