- Description
- Requirements
- Deadline
- Schedule
- Requirements to run local
- Run local
- Project Architecture
- Endpoints
- Info About Requests
- Requests in postman
- Requests in swagger
- Next steps
- The technical challenge consists of creating an API REST that exposes an system based on transactions common to common or common to storekeeper, but not storekeeper to storekeeper.
-
Technical requirements:
- Golang application
- Relational database (your preference)
- RESTFul pattern
- Clean code
-
Extra:
- Container our application
- Semantic commit
- Unit tests
- Swagger documentation
- The test starts on
📅 16 feb 2023 - Thursday
with 7 days (calendar days) of time to finish - Ergo the deadline is
📅 23 feb 2023 - Thursday
Docker version 20.10.23
=> install dockerDocker Compose version v2.12.2
(for docker-compose commands) => install docker composeGNU Make 4.2.1
(for makefile commands) => install make- You have to use
docker-compose
insteaddocker compose
- All environment variables that you need are in
./.env.example
file - Ports:
- For this project you need to have ports open in your sistem, that PORTS are:
- 3000 (to api)
- 6379 (to redis)
- 8081 (to redis-commander)
- 5432 (to postgres database)
- If you dont have one of those PORTS opened, You will have kill them with those commands:
sudo lsof -i:<PORT>
(to discover what is in your PORT with value )sudo kill -9 <PID>
(to kill what is running in your PORT with PID value )
- If you need to run your application without docker (not recommended):
go version go1.18.4 linux/amd64
=> install go - I recommend use postman to test endpoints (but you have more options) => install postman
- Clone repository
- If you choose HTTPS:
git clone https://https://github.com/aaguero96/technical_challenge_q2bank/blob.git
- If you choose SSH:
git clone git@github.com:aaguero96/technical_challenge_q2bank.git
- Install dependencies
go mod tidy
- .env file
- In root directory has one file named
.env.example
- copy that file and rename that to
.env
(if you prefer runcp ./.env.example ./.env
) - fill up the env vars with correct values (only in case of this project the file envs has correct values)
- Run project with docker-compsoe
docker-compose up
(await for messageListening and serving HTTP on :3000
to start)
- Other commands
- If you need to recreate your database run:
make reset-db
- If you recreate your application run:
make re-run
- If you need to test services (in moment) run:
make unit-test
- If you need to generate swagger file run:
make generate-swagger
- If you need to run just your api service local run:
make run-dev
./.github
: have workflows and templates for git commits, pushs, pulls, ..../initializers
: have functions that use to instance an external/internal service./utils
: have simple functions that are used in other directories./models
: have one model for every table in project./migrate/seeders
: have one seeder (initial values in database) for tables that you need./migrate/migrate.go
: have one main function whitch create your database./repository
: have others directories that one of them represents actions in database./service
: have others directories that one of them represents services./handler
: have others directories that one of them represents handlers for your http requests./middleware
: have functions that use to handle with http requests before the handler (if you need)./routes
: have functions that instance a new route with http methods./extenalAPI
: have others directories that one of them represents uses of external API./events/producer
: have functions that produce messages for redis./events/consumer/handler
: have functions that consume messages from redis./events/consumer/main.go
: have main funtion that start consuming of messages from redis
- Relations in database are in the image bellow:
- Details about tables in database
-
users
- password should contain at least 5 characters, at least one upper case, at least one lower case, at least one numeric, at least one special
- if register_type_id is related to "CPF" register_number should have 11 digits and if is "CNPJ" register_number should have 14 digits
- email has to be correct format
-
transactions
- payer_id should not be related with "storekeeper"
- status has 5 possiblities: denied, in process, completed, canceled, cancel in progress
- POST localhost:3000/v1/login
- Query param:
agree_cookie: bool
- Body:
{
"email": "string",
"password": "string"
}
- Response:
{
"token": "string",
"expiring_in": "string"
}
- Cookies: this method put token in localhost cookies as "token"
- POST localhost:3000/v1/users
- Query param:
agree_cookie: bool
- Body:
{
"name": "string",
"email": "string",
"password": "string",
"register_number": int,
"register_type_id": int,
"user_type_id": int
}
- Response:
{
"token": "string",
"expiring_in": "string"
}
- Cookies: this method put token in localhost cookies as "token"
- GET localhost:3000/v1/users
- Headers: Bearer token (or cookie "token" if has saved)
- Response:
[
{
"name": "string",
"email": "string",
"wallet_id": int
}
]
- GET localhost:3000/v1/users/:id
- Headers: Bearer token (or cookie "token" if has saved)
- Params:
id int
- Response:
{
"name": "string",
"register_number": int,
"register_type_id": int,
"email": "string",
"wallet_id": int,
"user_type_id": int
}
- GET localhost:3000/v1/register-types
- Headers: Bearer token (or cookie "token" if has saved)
- Response:
[
{
"id": int,
"type": "string"
}
]
- GET localhost:3000/v1/user-types
- Headers: Bearer token (or cookie "token" if has saved)
- Response:
[
{
"id": int,
"type": "string"
}
]
- GET localhost:3000/v1/user-types/:id
- Headers: Bearer token (or cookie "token" if has saved)
- Params:
id int
- Response:
{
"user_type_id": int,
"user_type": "string"
}
- GET localhost:3000/v1/wallets
- Headers: Bearer token (or cookie "token" if has saved)
- Response:
[
{
"id": int,
"amount": float
}
]
- GET localhost:3000/v1/wallets/:id
- Headers: Bearer token (or cookie "token" if has saved)
- Params:
id int
- Response:
{
"wallet_id": int,
"amount": float
}
- PATCH localhost:3000/v1/wallets/:id
- Headers: BasicAuth
- Params:
id int
- Body:
{
"amount": float
}
- Response:
{
"wallet_id": int,
"amount": float
}
- POST localhost:3000/v1/transactions
- Headers: Bearer token (or cookie "token" if has saved)
- Body:
{
"payer_id": int,
"payee_id": int,
"amount": float
}
- Response:
{
"transaction_id": int,
"payer_id": int,
"payee_id": int,
"amount": float,
"status": "in progress"
}
- GET localhost:3000/v1/transactions
- Headers: Bearer token (or cookie "token" if has saved)
- Response:
[
{
"payer_id": int,
"payee_id": int,
"amount": float,
"status": "string"
}
]
- GET localhost:3000/v1/transactions/:id
- Headers: Bearer token (or cookie "token" if has saved)
- Params:
id int
- Response:
{
"transaction_id": int,
"payer_id": int,
"payee_id": int,
"amount": float,
"status": "string"
}
- DELETE localhost:3000/v1/transactions/:id
- Headers: Bearer token (or cookie "token" if has saved)
- Params:
id int
- Response: ``
- To must of endpoints you need a token access, this token is adquired in two endpoints (the body is an example but work in that database):
POST localhost:3000/v1/login
body { "email": "email1@testmail.com", "password": "Def4!t*1" }
POST localhost:3000/v1/users
body { "name": "andre aguero", "email": "andre@teste.com", "password": "Def4!t*0", "register_number": 12345678900, "register_type_id": 1, "user_type_id": 2 }
- In endpoint
PATCH localhost:3000/v1/wallets/:id
the BasicAuth is:- username: admin
- password: admin
- I put that here just because is demonstrative, this is not secure in real projects (this would be passed by keybase or other software)
- If you have both cookie and token but the user is different, the preference is token
- Import collection to postman
- In this repository has one file name
psotman.json
- Visit postman and select option
import
(as image bellow)
- Defining postman envs
- In postman select option
Environments
(as image bellow)
- Use collection
- In postman select option
Collections
and you have acees to all endpoints (as image bellow)
- Access
localhost:3000/docs/index.html
- You have three options to navigate on swagger:
- Not authenticated: you just have acces to not lock endpoints (POST /v1/login and POST /v1/users)
- authenticated with BearerToken: you have acess to every endpoint but not to PATCH /v1/wallets/:id
- authenticated with Basic authorization: you have access just to endpoint PATCH /v1/wallets/:id
- Authenticate
- To authenticate you press the button in up rigth on page (as image bellow)