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 - Daniel Lemos #322

Open
wants to merge 17 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
13 changes: 13 additions & 0 deletions .env-example
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
ENVIRONMENT="development"
PORT="8080"

# ---------- Database
DB_ROOT_PASSWORD="root"
DB_USER="user"
DB_PASSWORD="userpass"
DB_SCHEMA="currency_db"
DB_HOST="database-currency"
DB_PORT="3306"

# ---------- Providers
EXCHANGE_RATE_API_URL=https://v6.exchangerate-api.com/v6/4285ff5060b46fdc0a60ec09/latest/USD
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.env
challenge-bravo*
.vscode
.idea
*.session.sql
47 changes: 47 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Build stage
FROM golang:1.23.3-alpine AS builder

WORKDIR /app

# Copy only essential files for dependency management
COPY go.mod go.sum ./

RUN go mod download

# Copy the rest of the source code
COPY . .

# Format and check the code
RUN go fmt ./...
RUN go vet ./...

# Build the application with CGO disabled and optimized for size
RUN CGO_ENABLED=0 go build -ldflags="-s -w" -o challenge-bravo

# Production stage
FROM alpine:3.12

WORKDIR /app

# Install the tzdata package and set the timezone
RUN apk add --no-cache tzdata \
&& cp /usr/share/zoneinfo/America/Sao_Paulo /etc/localtime \
&& rm -rf /var/cache/apk/*

# Copy the binary from the build stage
COPY --from=builder /app/challenge-bravo .

# Copy the .env file ##DEV ONLY
COPY .env .env

# Copy the script to the container
COPY docker/cronjob/run_sync.sh /usr/local/bin/run_sync.sh

# Add the cronjob
RUN echo "0 0 * * * /usr/local/bin/run_sync.sh" >> /etc/crontabs/root

# Set the command to run the application
CMD ["./challenge-bravo"]

# Expose port 8080
EXPOSE 8080
30 changes: 30 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@

.PHONY: run-api, create-api, shutdown, test test-external-provider test-application

run-api:
docker compose up -d database-currency && sleep 4 && docker compose up -d currency-api

create-api:
docker compose build --no-cache --pull

shutdown:
docker compose down --rmi all

sync-data:
docker exec -it currency-api /bin/sh -c './challenge-bravo -sync'

prepare: create-api run-api sync-data

seek-and-destroy:
docker docker rm -v -f currency-api && docker rm -v -f database-currency

# Regra para rodar todos os testes
test: test-external-provider test-application

# Regra para rodar os testes no pacote external
test-external-provider:
go test -count=1 ./pkg/external/... -v

# Regra para rodar os testes no pacote application
test-application:
go test -count=1 ./application/... -v
151 changes: 93 additions & 58 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,82 +1,117 @@
# <img src="https://avatars1.githubusercontent.com/u/7063040?v=4&s=200.jpg" alt="Hurb" width="24" /> Bravo Challenge
# Conversor de Moedas

[[English](README.md) | [Portuguese](README.pt.md)]
API para conversão monetária.
Moeda de lastro: USD.
Possível fazer conversões entre diferentes moedas

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

The API must convert between the following currencies:
- Go 1.23.3
- Docker

- USD
- BRL
- EUR
- BTC
- ETH
## Como usar?

Other coins could be added as usage.
- Clone o repositório
- Copie o arquivo .env.example para .env com o comando ```cp .env.example .env```
- Rode ```make prepare``` no terminal e aguarde a API subir na porta 8085
- Pronto! Agora você pode acessar o [Swagger](http://localhost:8085/swagger/index.htm) do projeto e verificar o resultado!

Ex: USD to BRL, USD to BTC, ETH to BRL, etc...
### API Conversão de Moedas

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`
Caso você tenha interesse em acessar a API por um Postman abaixo tem a descrição das rotas.

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

The API must support conversion between FIAT, crypto and fictitious. Example: BRL->HURB, HURB->ETH
#### Conversão V1

"Currency is the means by which monetary transactions are effected." (Wikipedia, 2021).
**Rota:** http://localhost:8085/v1/conversion

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.
**Parametros:** Passados diretamente na rota
* ```from``` Moeda de onde vamos converter o valor
* ```to``` Moeda para onde vamos converter o valor
* ```amount``` Valor a ser convertido

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).
*Exemplo:* ```?from=BRL&to=USD&amount=123.45```

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

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

- JavaScript (NodeJS)
- Python
- Go
- Ruby
- C++
- PHP
**Rota:** http://localhost:8085/v1/currency

## Requirements
**Método:** POST

- 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
**Parâmetros:** Passados no corpo da requisição

## Evaluation criteria
* ```code``` Código da moeda a ser adicionada
* ```name``` Nome da moeda a ser adicionada
* ```currency_rate``` Valor referente ao valor desta moeda se comparada ao **backing_currency** (Que não está implementado e por isso é referente ao USD marretado no código)
* ```backing_currency``` Se essa é a moeda padrão do sistema (Não Implementado)

- **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?
*Exemplo de corpo da requisição:*

## Doubts
```
{
"code": "HURB",
"name": "Hurb Coin"
"currency_rate": 1.5
"backing_currency": false
}
```

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! ;)
#### Remover Moeda V1

<p align="center">
<img src="ca.jpg" alt="Challange accepted" />
</p>
**Rota:** http://localhost:8085/v1/currency/{id}

**Método:** DELETE

**Parâmetros:** Passados diretamente na rota

* ```id``` Índice no database da moeda a ser removida

*Exemplo:* http://localhost:8085/v1/currency/165

---

#### Listar Moedas V1

**Rota:** http://localhost:8085/v1/currency

**Método:** GET

**Parâmetros:** Nenhum

*Exemplo:* http://localhost:8085/v1/currency

---

#### Atualizar Cotação V1

**Rota:** http://localhost:8085/v1/currency/{id}

**Método:** PUT

**Parâmetros:** O ```id``` é passado diretamente na rota, mas os outros são passados no corpo da requisição

* ```code``` Código da moeda a ser adicionada
* ```name``` Nome da moeda a ser adicionada
* ```currency_rate``` Valor referente ao valor desta moeda se comparada ao **backing_currency** (Que não está implementado e por isso é referente ao USD marretado no código)
* ```backing_currency``` Se essa é a moeda padrão do sistema (Não Implementado)

*Exemplo de corpo da requisição:*

```
{
"code": "HURB",
"name": "Hurb Coin"
"currency_rate": 1.8
"backing_currency": false
}
```

## Próximos Passos

* Adicionar testes automatizados
82 changes: 0 additions & 82 deletions README.pt.md

This file was deleted.

31 changes: 31 additions & 0 deletions application/conversion/entity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package conversion

// ConversionData conversion info
// @Description Request to Convert a specified amount from one currency to another
type ConversionData struct {
From string `json:"from" binding:"required"`
To string `json:"to" binding:"required"`
Amount string `json:"amount" binding:"required"`
}

type ConversionValues struct {
From CurrencyRate
To CurrencyRate
Amount string
}

type CurrencyRate struct {
Code string `json:"code"`
CurrencyRate string `json:"currency_rate"`
}

// ConversionResponse conversion info
// @Description Response from conversion
type ConversionResponse struct {
Description string `json:"description"`
Amount string `json:"amount"`
}

type UseCase interface {
ConvertMoney(c *ConversionValues) (*ConversionResponse, error)
}
Loading