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

Bravo Challenge Completed #309

Open
wants to merge 13 commits 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
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
PORT=3100
COINS=USD,BRL,EUR,BTC,ETH
COINAPIKEY=98DFF6FA-EF98-4989-9658-A7E347E10EF1
MCAPIKEY=34efd9e9-37ff-43c4-b3f7-b802e5249154
LOGIN=admin
PASS=admin
SECRET=ekmliv4vt5903804reliuerwjvqkewr33042
REDIS=redis://redis:6379
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/node_modules
.env
/build
8 changes: 8 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM node:latest

WORKDIR /usr/app

COPY package*.json ./
RUN npm install

COPY . .
210 changes: 161 additions & 49 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,81 +2,193 @@

[[English](README.md) | [Portuguese](README.pt.md)]

Build an API, which responds to JSON, for currency conversion. It must have a backing currency (USD) and make conversions between different currencies with **real and live values**.
## Install

The API must convert between the following currencies:
The first step is to config this application is create a `.env` file using the `.env.example` present here as a guide. This application uses [_CoinAPI_](https://www.coinapi.io/) and also [_CoinMarketCap API_](https://coinmarketcap.com/api/) to work, so you will need to request their API keys or have them available already.

To run this API you will need to have Docker already installed in your machine. Assuming you already have it, you just need to run the following command:

`docker-compose up`

**Warning**: There is a simple redis structure on this project to facilitate testing, but in a real scenario it is recommended to replace this structure or modify to improve security/ performance (Redis can be slower inside a docker container). You can change the url using the variable REDIS on the enviroment file.

This application provides a API that converts a given currency and amount to another coin. It has the following currencies as default:
- USD
- BRL
- EUR
- BTC
- ETH

Other coins could be added as usage.
If you wish you can change the default list as well using the `.env` file. The default currencies listed on `.env` can't be removed via API.


## Conversion

### Request

`GET /conversion`

curl --location 'localhost:3100/conversion?from=BTC&to=BRL&decimalPlaces=30'

### Query Parameters
| Parameter | Description | Required | Type |
| --------------- | ------------------------------------ | -------- | ------ |
| `from` | Initial currency | Yes | string |
| `to` | Desired currency rate | Yes | string |
| `amount` | Desired amount to convert | No | number |
| `decimalPlaces` | Desired decimal places. Default is 8 | No | number |

### Response

Status: 200
Content-Type: application/json

{
"from": "BTC",
"amount": 1,
"to": "BRL",
"value": "345964.377343084448906460570000000000"
}

## Authentication

The token returned by this endpoint is required to add and remove coins from the system. This project version has only one admin user configurable in the `.env`. The token has expiration time of 2 hours.

### Request

`POST /login`

curl --location 'localhost:3100/login' \
--header 'Content-Type: application/json' \
--data '{
"login":"admin",
"password":"admin"
}'

### Body
| Field | Description | Required | Type |
| ---------- | --------------------- | -------- | ------ |
| `login` | Defined on enviroment | Yes | string |
| `password` | Defined on enviroment | Yes | string |

### Response

Status: 200
Content-Type: application/json

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRldGltZSI6MTcxNjIw....."
}

## Refresh Token

### Request

`GET /refesh`

curl --location 'localhost:3100/refresh' \
--header 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRldGltZSI6MTcxNjIwMjYxNDUyNSwiaWF0IjoxNzE2MjAyNjE0LCJleHAiOjE3MTYyMDk4MTR9.yxO-a_LBhcwUVrO4TekbT0beER5YywYBSI5kWaBy_GQ'

### Headers
| Field | Description | Required | Type |
| --------------- | ----------- | -------- | ------ |
| `Authorization` | Token | Yes | string |

### Response

Status: 200
Content-Type: application/json

{
"token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRldGltZSI6MTcxNjIw....."
}

## Add Currency

This endpoint add new currencies in this platform. Needs authentication

### Request

`POST /add`

curl --location 'localhost:3100/add' \
--header 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRldGltZSI6MTcxNjE4NzE0MzA2MSwiaWF0IjoxNzE2MTg3MTQzLCJleHAiOjE3MTYxOTQzNDN9.kc862x0RNknfeGI3baiDfKatsSupwLO-MMzD-EJx50I' \
--header 'Content-Type: application/json' \
--data '{
"symbol":"GTA",
"type":"crypto"
}'

### Body
| Field | Description | Required | Type |
| --------------------- | ---------------------------------------------------------------------- | -------- | ------ |
| `symbol` | Currency symbol | Yes | string |
| `type` | Currency type | Yes | Enum |
| `rate` | Rate default. Only to fixed type | No | number |
| `scrpprRateAsset` | The rate asset of the value searched with the scrapper. Default is USD | No | string |
| `scrpprUrl` | Web Page url. Required for the scrapper | No | string |
| `scrpprAmountTag` | Tag for looking for amount. Without the amount will be 1 | No | string |
| `scrpprRateTag` | Tag for looking for the rate. Required for the scrapper | No | string |
| `scrpprDecimalSymbol` | Decimal symbol. Default is a comma(,) | No | string |

### CurrencyTypes Enum
| Enum | Description |
| ---------- | -------------------------------------------------------------------------------------------------- |
| `fiat` | Fiat currency |
| `Crypto` | Crypto currency |
| `Fixed` | Rate fixed |
| `Scrapper` | Load currency data from a web page. Only use if you can't get the data using fiat and crypto types |

Ex: USD to BRL, USD to BTC, ETH to BRL, etc...
**Warning**: The fixed and scrapper types will be overrited if the currency is found within CoinAPI.io and/or MarketCap API. They are mean to be used when you can't find the coin by normal means. Ex: Ficticious coin as D&D Coin.

The request must receive as parameters: The source currency, the amount to be converted and the final currency.

Ex: `?from=BTC&to=EUR&amount=123.45`
### Scrapper Example
curl --location 'localhost:3100/add' \
--header 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRldGltZSI6MTcxNjIwNDA3Mzg4MiwiaWF0IjoxNzE2MjA0MDczLCJleHAiOjE3MTYyMTEyNzN9._jjuooOorYKFB4IsQ10MqDWyZTgWmJ29F5llaEA0BW0' \
--header 'Content-Type: application/json' \
--data '{
"symbol":"GTAOnline",
"type":"scrapper",
"scrpprRateAsset":"BRL",
"scrpprUrl":"https://store.playstation.com/pt-br/product/UP1004-CUSA00419_00-GTAVCASHPACK000D",
"scrpprAmountTag":".psw-c-t-2",
"scrpprRateTag":".psw-t-title-m"
}'

Also build an endpoint to add and remove API supported currencies using HTTP verbs.
### Response

The API must support conversion between FIAT, crypto and fictitious. Example: BRL->HURB, HURB->ETH
Status: 200
Content-Type: application/json

"Currency is the means by which monetary transactions are effected." (Wikipedia, 2021).
{
"message": "Asset GTA6 added with success!"
}

Therefore, it is possible to imagine that new coins come into existence or cease to exist, it is also possible to imagine fictitious coins such as Dungeons & Dragons coins being used in these transactions, such as how much is a Gold Piece (Dungeons & Dragons) in Real or how much is the GTA$1 in Real.

Let's consider the PSN quote where GTA$1,250,000.00 cost R$83.50 we clearly have a relationship between the currencies, so it is possible to create a quote. (Playstation Store, 2021).
## Remove Currency

Ref:
Wikipedia [Institutional Website]. Available at: <https://pt.wikipedia.org/wiki/Currency>. Accessed on: 28 April 2021.
Playstation Store [Virtual Store]. Available at: <https://store.playstation.com/pt-br/product/UP1004-CUSA00419_00-GTAVCASHPACK000D>. Accessed on: 28 April 2021.
This endpoint removes currencies from this application. Needs authentication. Default coins can't be removed.

You can use any programming language for the challenge. Below is the list of languages ​​that we here at Hurb have more affinity:
### Request

- JavaScript (NodeJS)
- Python
- Go
- Ruby
- C++
- PHP
`DELETE /remove/:asset`

## Requirements
curl --location --request DELETE 'localhost:3100/remove/IOTA' \
--header 'Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRldGltZSI6MTcxNjE4NzE0MzA2MSwiaWF0IjoxNzE2MTg3MTQzLCJleHAiOjE3MTYxOTQzNDN9.kc862x0RNknfeGI3baiDfKatsSupwLO-MMzD-EJx50I'

- Fork this challenge and create your project (or workspace) using your version of that repository, as soon as you finish the challenge, submit a _pull request_.
- If you have any reason not to submit a _pull request_, create a private repository on Github, do every challenge on the **main** branch and don't forget to fill in the `pull-request.txt` file. As soon as you finish your development, add the user `automator-hurb` to your repository as a contributor and make it available for at least 30 days. **Do not add the `automator-hurb` until development is complete.**
- If you have any problem creating the private repository, at the end of the challenge fill in the file called `pull-request.txt`, compress the project folder - including the `.git` folder - and send it to us by email.
- The code needs to run on macOS or Ubuntu (preferably as a Docker container)
- To run your code, all you need to do is run the following commands:
- git clone \$your-fork
- cd \$your-fork
- command to install dependencies
- command to run the application
- The API can be written with or without the help of _frameworks_
- If you choose to use a _framework_ that results in _boilerplate code_, mark in the README which piece of code was written by you. The more code you make, the more content we will have to rate.
- The API needs to support a volume of 1000 requests per second in a stress test.
- The API needs to include real and current quotes through integration with public currency quote APIs

## Evaluation criteria
### Response

- **Organization of code**: Separation of modules, view and model, back-end and front-end
- **Clarity**: Does the README explain briefly what the problem is and how can I run the application?
- **Assertiveness**: Is the application doing what is expected? If something is missing, does the README explain why?
- **Code readability** (including comments)
- **Security**: Are there any clear vulnerabilities?
- **Test coverage** (We don't expect full coverage)
- **History of commits** (structure and quality)
- **UX**: Is the interface user-friendly and self-explanatory? Is the API intuitive?
- **Technical choices**: Is the choice of libraries, database, architecture, etc. the best choice for the application?
Status: 200
Content-Type: application/json

## Doubts
{
"message": "Asset GTA6 removed with success!"
}

Any questions you may have, check the [_issues_](https://github.com/HurbCom/challenge-bravo/issues) to see if someone hasn't already and if you can't find your answer, open one yourself. new issue!

Godspeed! ;)
Done! ;)

<p align="center">
<img src="ca.jpg" alt="Challange accepted" />
<img src="completed.jpg" alt="Challange completed" />
</p>
Loading