Skip to content

API designed to perform internal transfers between digital bank accounts. This application allows you to: create an account, list accounts, consult the account balance, be authenticated and make transfers to other accounts.

License

Notifications You must be signed in to change notification settings

patriciapedrosaa/transfer-me

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Transfer-me

It is an API designed to perform internal transfers between digital bank accounts. This application allows you to: create an account, list accounts, consult the account balance, be authenticated and make transfers to other accounts.

Based on Clean architecture

transfer-me/
┣ app/
┃ ┣ domain/
┃ ┃  ┣ account/
┃ ┃  ┣ authentication/
┃ ┃  ┣ entities/
┃ ┃  ┣ transfer/
┃ ┃  ┗ vos/
┃ ┗ gateways/
┃    ┣ db/
┃    ┗ http/
┣ cmd/
┃  ┗ main
┗ Dockerfile

Project Overview

Endpoints

Create Accounts

Create an account

Request
  • Path: /accounts
  • Method: POST
  • Request body
  {
    "name": "gopher",
    "cpf": "12345678910",
    "secret": "mySecret"
  }
Response successful
  • 201 Created
      {
        "id": "7f3412f2-97cd-46de-afa5-35f72f34f3d3",
        "name": "gopher"
      }
Response error
  • 400 Bad Request
    • When request body has invalid fields

        {
          "error": "invalid cpf"
        }
    • When request body has invalid field types

        {
          "error": "invalid request payload"
        }
    • When body is empty

        {
          "error": "invalid fields"
        }
    • When account already exist

        {
          "error": "account already exist"
        }

List Accounts

Get the list of accounts

Request
  • Path: /accounts
  • Method: GET
Response successful
  • 200 OK
      {
        "id": "7f3412f2-97cd-46de-afa5-35f72f34f3d3",
        "name": "gopher",
        "cpf": "12345678910"
      }
Response error
  • 500 Internal server error
      {
        "error": "something went wrong"
      }

Get Balance

Get account balance

Request
  • Path: /accounts/{account_id}/balance
  • Method: GET
Response successful
  • 200 OK
      {
        "balance": 100
      }
Response errors
  • 404 Not Found

      {
        "error": "not found"
      }
  • 500 Internal server error

      {
        "error": "something went wrong"
      }

Login

Authenticate the user with jwt token

Request
  • Path: /login
  • Method: POST
  • Request body:
  {
    "cpf": "12345678910",
    "secret": "mySecret"
  }
Response successful
  • 201 Created
      {
        "Token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MzA5NTI5MjQsImlhdCI6MTYzMDk1MjAyNCwiaWQiOiI5OTRmZDJhOC1kMjJmLTQ2OTMtYWVkYS00Zjk1YmQ4MjIwMjUiLCJpc3MiOiJKV1QiLCJuYW1lIjoiZ29waGVyIiwic3ViIjoiODI0MmU4NWYtYzRhZS00MzY5LWI1Y2YtNTFmNWNlZjlmMzMwIn0.PYcE5gnv7qCBn153HMVnU0lAN7kI95YnugKmqNVhQU0"
      }
Response errors
  • 400 Bad Request

    • When the name or password is incorrect
       {
         "error":  "incorrect username or password"
       }
    • When request body has invalid field types
        {
          "error": "invalid request payload"
        }
    • When body is empty
        {
          "error": "invalid fields"
        }
  • 500 Internal server error

      {
        "error": "unexpected error"
      }

Create Transfers

Transfers from one Account to another.

Request
  • Path: /transfers
  • Method: POST
  • Request body:
  {
    "account_destination_id" : "7f3412f2-97cd-46de-afa5-35f72f34f3d3",
    "amount": 30
  }
  • Header Params:
  {
    "Authorization" : "Bearer Token"
  }
  • 201 Created
      {
        "id": "7f3412f2-97cd-46de-afa5-35f72f34f3d3"
      }
Response errors
  • 400 Bad Request

    • When authorization header is empty
        {
          "error": "empty authorization header"
        }
    • When access token is empty
        {
          "error": "empty token"
        }
    • When the authentication method is wrong
        {
          "error": "invalid auth method"
        }
    • When request body has invalid field types
        {
          "error": "invalid request payload"
        }
    • When request body is empty
        {
          "error": "invalid fields"
        }
    • When destination cpf is not found
        {
          "error": "invalid transfer data"
        }
    • When amount is invalid
        {
          "error": "the amount must be greater than zero"
        }
  • 403 Forbidden

      {
        "error": "invalid token"
      }
  • 500 Internal server error

      {
        "error": "something went wrong"
      }

List Transfers

Get the list of transfers from the authenticated user.

Request
  • Path: http://localhost:8000/transfers

  • Method: GET

  • 200 OK

      {
        "id": "7f3412f2-97cd-46de-afa5-35f72f34f3d3",
        "amount": 50,
        "account_origin_id": "014918d1-577c-4045-a415-a325bee3b1bd",
        "account_destination_id": "6a00ac20-e07f-455f-a53c-37088c7b4277",
        "created_at": "2021-09-23T11:20:55.774779-03:00"
      }
Response error
  • 500 Internal server error
      {
        "error": "something went wrong"
      }

Environment variables

The existing environment variables in the application are listed below followed by their descriptions:

Name Description
ACCESS_SECRET sign key to generate jwt
API_PORT port to start application
DB_USER database user
DB_PASSWORD database secret
DB_NAME database name
DB_HOST database host
DB_PORT database port
DB_SSLMODE database SSL mode
LOG_LEVEL application structured log level

Stack

To download it with Go previously downloaded:

$ go mod download

Starting (Docker required)

You can use the makefile to make it easier to build and run the application. A typical day to day would be:

$  make postgres
$  make createdb
$  make build (local)
$  make build-image (docker)
$  make run
$  make test

Hands On with Moq

We're using moq to mock use cases.

How to use:

  1. Indicate the interface you want to mock inserting a "//go:generate" instruction inside the code, like this:
package account

//go:generate moq -stub -out use_case_mock.go . UseCase

type UseCase interface {
	Method1() error
	Method2(i int)
}
  1. Run go generate indicating the location of the interface you want to mock, like this:
go generate ./app/domain/account/usecase.go

Unit Tests

Run the command:

$  make test

To see the coverage run the command at the root of the project:

$ go test -cover ./...

License

MIT

Acknowledgments

Special thanks to all the authors of the libraries we use and the contents, videos and articles, on which I based this application. Thanks also to my mentors and code reviewers.

About

API designed to perform internal transfers between digital bank accounts. This application allows you to: create an account, list accounts, consult the account balance, be authenticated and make transfers to other accounts.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages