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

Challenge Bravo - Tiago Celestino #319

Open
wants to merge 6 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
18 changes: 18 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
node_modules
npm-debug.log
yarn-debug.log
yarn-error.log
.git
.gitignore
.env
.env.*
*.md
.vscode
coverage
.editorconfig
.prettierrc
.prettierignore
docker-compose.yml
Dockerfile
*.test.ts
__tests__
10 changes: 3 additions & 7 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Style for every file
[*]
indent_style = space
indent_size = 2
end_of_line = lf
insert_final_newline = false
charset = utf-8
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
insert_final_newline = true
8 changes: 8 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Application
APP_NAME=currency-convert-api
PORT=3000
BASE_API_PATH=/currency-convert

# External APIs
EXCHANGE_RATE_API=https://api.exchangerate-api.com/v4
COIN_GECKO_API=https://api.coingecko.com/api/v3
51 changes: 51 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: Continuous Integration

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
validate:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'yarn'

- name: Install dependencies
run: yarn install

- name: Type check
run: yarn type-check

- name: Lint
run: yarn lint

- name: Check formatting
run: yarn format:check
tests:
needs: validate
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3

- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: '20'
cache: 'yarn'

- name: Install dependencies
run: yarn install

- name: Unit test
run: yarn test


19 changes: 19 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
.DS_Store

logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*

node_modules/

*.tsbuildinfo
.env

.vscode-test

.yarn/cache
.yarn/unplugged
.yarn/build-state.yml
.yarn/install-state.gz
2 changes: 2 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules
dist
12 changes: 12 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"semi": true,
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 120,
"tabWidth": 2,
"useTabs": false,
"bracketSpacing": true,
"arrowParens": "always",
"parser": "typescript",
"endOfLine": "auto"
}
61 changes: 61 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Build stage
FROM node:20.10.0-alpine AS builder

# Add labels for better maintainability
LABEL maintainer="Hurb Team"
LABEL description="Currency Converter API"
LABEL version="1.0"

# Set working directory
WORKDIR /app

# Set NODE_ENV for build
ENV NODE_ENV=production

# Install dependencies first (better layer caching)
COPY package.json yarn.lock ./
# Install all dependencies including devDependencies for building
RUN yarn install --frozen-lockfile --production=false

# Copy source files
COPY . .

# Build the application
RUN yarn build

# Production stage
FROM node:20.10.0-alpine

# Set working directory
WORKDIR /app

# Create a non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

# Set NODE_ENV
ENV NODE_ENV=production

# Copy only necessary files from builder
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package.json ./
COPY --from=builder /app/yarn.lock ./

# Install only production dependencies
RUN yarn install --production --frozen-lockfile && \
yarn cache clean

# Change ownership to non-root user
RUN chown -R appuser:appgroup /app

# Switch to non-root user
USER appuser

# Expose port
EXPOSE 3000

# Add healthcheck using the ping endpoint
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget --no-verbose --tries=1 --spider http://localhost:3000/currency-convert/ping || exit 1

# Start the application
CMD ["yarn", "start"]
172 changes: 114 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,138 @@
# <img src="https://avatars1.githubusercontent.com/u/7063040?v=4&s=200.jpg" alt="Hurb" width="24" /> Bravo Challenge
# Currency Converter API

[[English](README.md) | [Portuguese](README.pt.md)]
A robust API for converting between different types of currencies, including fiat currencies, cryptocurrencies, and fictional currencies.

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**.
## 🌍 Features

The API must convert between the following currencies:
- 💱 Conversion between multiple currencies
- 🏦 Support for fiat currencies
- 💰 Support for cryptocurrencies
- 🎲 Support for fictional currencies
- 🔄 Automatic exchange rate updates

- USD
- BRL
- EUR
- BTC
- ETH
## 🚀 Quick Start

Other coins could be added as usage.
### Prerequisites
- Node.js (version 18+ recommended)
- Yarn package manager

Ex: USD to BRL, USD to BTC, ETH to BRL, etc...
### Installation

The request must receive as parameters: The source currency, the amount to be converted and the final currency.
1. Clone the repository
```bash
git clone https://github.com/tcelestino/currency-converter-api.git
cd currency-converter-api
```

Ex: `?from=BTC&to=EUR&amount=123.45`
2. Configure Environment
- Rename `.env.example` to `.env`
- Update configuration as needed

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

The API must support conversion between FIAT, crypto and fictitious. Example: BRL->HURB, HURB->ETH
#### Using Docker

"Currency is the means by which monetary transactions are effected." (Wikipedia, 2021).
Build the Docker image:
```bash
docker build -t currency-converter-api:latest .
```

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.
Run the container:
```bash
docker run -p 3000:3000 currency-converter-api
```

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).
#### Local Installation

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.
Install dependencies and start:
```bash
yarn && yarn build && yarn start
```

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

- JavaScript (NodeJS)
- Python
- Go
- Ruby
- C++
- PHP
```bash
# Using Docker
docker-compose up -d

## Requirements
# Local development
yarn && yarn dev
```

- 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
## 🌐 API Endpoints

## Evaluation criteria
### Currency Conversion
`GET /currency-convert/v1/convert`
- Convert values between currencies

- **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?
**Parameters:**
- `from`: Source currency code (e.g., USD)
- `to`: Target currency code (e.g., BRL)
- `amount`: Value to be converted

## Doubts
**Example Request:**
```
GET /currency-convert/v1/convert?from=USD&to=BRL&amount=100
```

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!
### Currency Management

Godspeed! ;)
#### List Currencies
`GET /currency-convert/v1/currencies`
- Retrieve all available currencies

<p align="center">
<img src="ca.jpg" alt="Challange accepted" />
</p>
#### Add New Currency
`POST /currency-convert/v1/currencies`
- Add a new currency to the system

**Request Body:**
```json
{
"code": "GOLD2",
"name": "D&D Gold Piece",
"type": "fictional",
"rate": 0.25
}
```

#### Remove Currency
`DELETE /currency-convert/v1/currencies/:code`
- Remove an existing currency from the system

## 📄 Documentation

Comprehensive API documentation is available at:
```
http://localhost:3000/documentation
```

## 🧪 Testing

Run test suite:
```bash
yarn test
```

## 🤝 Contributing

1. Fork the repository
2. Create your feature branch (`git checkout -b feature/amazing-feature`)
3. Commit your changes (`git commit -m 'Add some amazing feature'`)
4. Push to the branch (`git push origin feature/amazing-feature`)
5. Open a Pull Request

## 📜 License

MIT

## 💡 Technology Stack

- Node.js
- TypeScript
- Fastify
- Docker
- Jest

## 🚨 Disclaimer

Exchange rates are for informational purposes and may not reflect real-time market values. Always verify rates from official sources for critical transactions.
Loading