Skip to content
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

feat: kafka challenge #433

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#lock files
./**/*lock.json
./**/yarn.lock

# Logs
logs
*.log
Expand Down Expand Up @@ -38,7 +42,7 @@ bower_components
build/Release

# Dependency directories
node_modules/
./**/node_modules/
jspm_packages/

# TypeScript v1 declaration files
Expand Down
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"trailingComma": "all"
}
136 changes: 134 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,20 @@ 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 !!

- [Yape Code Challenge :rocket:](#yape-code-challenge-rocket)
- [Problem](#problem)
- [Tech Stack](#tech_stack)
- [Send us your challenge](#send_us_your_challenge)
- [Tech Stack](#tech-stack)
- [Optional](#optional)
- [Send us your challenge](#send-us-your-challenge)
- [Solution](#solution)
- [Graph](#graph)
- [Api GraphQL](#api-graphql)
- [GetTransaction](#gettransaction)
- [CreateTransaction](#createtransaction)
- [UpdateTransaction](#updatetransaction)
- [Set Up project](#set-up-project)
- [With Docker](#with-docker)
- [Local](#local)

# Problem

Expand Down Expand Up @@ -80,3 +91,124 @@ You can use Graphql;
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.

# Solution
## Graph

![My Image](md_docs/graph-solution.png)

## Api GraphQL

#### GetTransaction

```
POST GetTransaction =>
http://localhost:3000/graphql
**Query**
query getTransaaction($idTransaction: String!){
getTransaction(input:{
idTransaction:$idTransaction
}){
transactionExternalId
transactionType{
name
}
transactionStatus{
name
}
createdAt
value
}
}
**Variables**
{
"idTransaction":"e4d03d07-5af7-4678-ac68-3b9c02c724c2"
}
```

#### CreateTransaction

```
POST GetTransaction =>
http://localhost:3000/graphql
**Mutation**
mutation createTransaction(
$accountExternalIdDebit: String!
$accountExternalIdCredit: String!
$tranferTypeId: Int!
$value: Int!
){
createTransaction(input: {
accountExternalIdDebit: $accountExternalIdDebit
accountExternalIdCredit: $accountExternalIdCredit
tranferTypeId: $tranferTypeId
value: $value
}){
transactionExternalId
transactionType{
name
}
transactionStatus{
name
}
createdAt
value
}
}
**Variables**
{
"accountExternalIdDebit": "fd890dcc-cd1b-42bd-937a-7a692fa35e8b",
"accountExternalIdCredit": "fd890dcc-cd1b-42bd-937a-7a692fa35e8b",
"tranferTypeId": 2,
"value": 100
}
```

#### UpdateTransaction

```
POST UpdateTransaction =>
http://localhost:3000/graphql
**Mutation**
mutation($idTransaction: String!, $status: String!){
updateTransaction(
input:{
idTransaction: $idTransaction,
status: $status
}
){
transactionExternalId
transactionStatus{
name
}
}
}
**Variables**
{
"idTransaction":"e4d03d07-5af7-4678-ac68-3b9c02c724c2"
}
```
# Set Up project

### With Docker

```
> docker compose up -d
```

### Local

> **Note:** Recommendation to install libraries using yarn to avoid problems with library subdependencies
>**Note:** Use Node 20.* or higher

```
> docker compose up -f docker-compose.local.yml -d
> cd anti_fraud_service
> yarn install
> cd ..
> cd transaction_rest
> yarn install
> cd ..
> npm run start:fraudservice
> npm run start:transaction
```
22 changes: 22 additions & 0 deletions anti_fraud_service/.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#CACHE REDIS
REDIS_URL=redis://localhost:6379

#POSTGRE CONFIG
PG_HOST=localhost
PG_PORT=5432
PG_USERNAME=postgres
PG_PASSWORD=postgres
PG_DATABASE=postgres

#PORT ANTIFRAUD SERVICE
ANTI_FRAUD_PORT=3002

#API
API_TRANSACTIONS=http://localhost:3000/graphql

#KAFKA
KAFKA_BROKER=localhost:9092
KAFKA_CLIENT_ID=ANTI_FRAUD_CLIENT
KAFKA_TOPIC=ANTI_FRAU_TOPIC
KAFKA_GROUP_ID_ANTI_FRAUD=ANTI_FRAUD_VALIDATE
KAFKA_GROUP_ID_APPROVE_DECLINE=ANTI_FRAUD_APPROVE_DECLINE
26 changes: 26 additions & 0 deletions anti_fraud_service/.eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
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',
},
'prettier/prettier': {},
};
5 changes: 5 additions & 0 deletions anti_fraud_service/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
package-lock.json
dist
.env
tsconfig.build.tsbuildinfo
15 changes: 15 additions & 0 deletions anti_fraud_service/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM node:20-alpine

RUN yarn install

WORKDIR /usr/src/app

COPY package.json ./

RUN yarn install

COPY . .

EXPOSE 3001

CMD [ "yarn", "start" ]
9 changes: 9 additions & 0 deletions anti_fraud_service/nest-cli.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"$schema": "https://json.schemastore.org/nest-cli",
"collection": "@nestjs/schematics",
"entryFile": "/Infraestructure/Bootstrap/main.js",
"sourceRoot": "./src",
"compilerOptions": {
"deleteOutDir": true
}
}
74 changes: 74 additions & 0 deletions anti_fraud_service/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
{
"name": "anti_fraud_service",
"version": "1.0.1",
"description": "",
"author": "Elver Valverde",
"private": true,
"license": "ISC",
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/Infraestructure/Bootstrap/main.js",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@apollo/server": "4.10.0",
"@nestjs/axios": "^3.0.2",
"@nestjs/common": "10.0.0",
"@nestjs/config": "3.2.0",
"@nestjs/core": "10.0.0",
"@nestjs/platform-express": "10.0.0",
"axios": "^1.6.7",
"kafkajs": "2.2.4",
"reflect-metadata": "0.2.0",
"rxjs": "7.8.1"
},
"devDependencies": {
"@nestjs/cli": "10.0.0",
"@nestjs/schematics": "10.0.0",
"@nestjs/testing": "10.0.0",
"@types/express": "4.17.17",
"@types/jest": "29.5.2",
"@types/node": "20.3.1",
"@types/supertest": "6.0.0",
"@typescript-eslint/eslint-plugin": "6.0.0",
"@typescript-eslint/parser": "6.0.0",
"eslint": "8.42.0",
"eslint-config-prettier": "9.0.0",
"eslint-plugin-prettier": "5.0.0",
"jest": "29.5.0",
"prettier": "3.0.0",
"source-map-support": "0.5.21",
"supertest": "6.3.3",
"ts-jest": "29.1.0",
"ts-loader": "9.4.3",
"ts-node": "10.9.1",
"tsconfig-paths": "4.2.0",
"typescript": "5.1.3"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
".+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
5 changes: 5 additions & 0 deletions anti_fraud_service/src/Application/Common/Contants.common.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const TRANSACTION_STATUS = {
PENDING_REVIEW: 'PENDING',
APPROVED_TRANSACTION: 'APPROVED',
TRANSACTION_DECLINED: 'DECLINED',
};
1 change: 1 addition & 0 deletions anti_fraud_service/src/Application/Common/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './Contants.common';
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export class CreateTransactionRequest {
accountExternalIdDebit: string;
accountExternalIdCredit: string;
tranferTypeId: number;
value: number;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export class GeTransactionRequest {
idTransaction: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export class KafkaConsumerRequest {
transactionExternalId: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export class UpdateTransactionRequest {
idTransaction: string;
status: string;
}
4 changes: 4 additions & 0 deletions anti_fraud_service/src/Application/Dto/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from './GetTransactionRequest.dto';
export * from './CreateTransactionRequest.dto';
export * from './UpdateTransactionRequest.dto';
export * from './KafkaConsumerRequest.dto';
Loading