Giter Site home page Giter Site logo

zivwi's Introduction

zivwi

Drive slow, homie.

This repository contains a payment handling backend system prototype built in Go. Using NSQ, it asynchronously processes transactions.

Context

STACK: Echo + NSQ + Postgres

As stated above, this prototype has one goal: to allow transfers between accounts and the retrieval of their balances. To accomplish that, the following data model has been proposed:

  • User: email, password, first and last name. Many accounts.
  • Account: it just has a balance (expressed in cents) which can't go below zero.
  • Transfer: it stores the amount (expressed in cents), the source account and the destination account, as well as its status and timestamps (created, updated). Additionally, it counts with two optional fields: transaction concept and one to log error messages in case that the transaction can't be fulfilled.

Once presented the data model, let dive deep on the fundamentals and foundations of this solution.

First of all, while coding this prototype, my technical inspiration was highly driven by two design patterns: Event Sourcing and CQRS, which are often related one to another. In the proposed solution, these patterns have been superficially implemented. For instance, the app logs events in the flavor of "Transfers". Then, the internal services calculate in a background process (a primitive version of a CQRS Saga, having the account balances calculated on the existing Transfer records stored in the database.

By being inspired by these patterns and embracing eventual consistency, I've created a system that dodges race-conditions. It also eases out audition efforts and reduces response times, among other goodies.

In another line of decisions, I have used relational schema black arts to accomplish my goals, rather than keeping a pristine schema that does a better job on maintaining the referential integrity across tables. For instance, I decided that the "users" table would hold an array of account identifiers, allowing for faster logins by querying just once the database (without joining tables).

Setup

These are the following steps to get up and running. Before following these instructions, make sure that the ports 3000, 4150, 4151, 4160, 4161 and 4171 are not in usage.

  1. clone this repo somewhere in your $GOPATH.
  2. Move into the projects directory.
  3. docker-compose up

Usage

PROTIP: If you're a user of Paw, I left a Paw project in the repository for trying out the API.

Once set up, perform the following requests:

  1. Grab the JWT token
$ curl -X "POST" "http://localhost:3000/authorize" \
     -H 'Content-Type: application/json' \
     -d $'{
  "email": "[email protected]",
  "password": "dameDiner0"
}'
{ "token": "TOKEN" }
  1. Request for your accounts (with the following user you'll find two) and grab their respective ids.
$ curl "http://localhost:3000/q/accounts" \
     -H 'Authorization: Bearer <JWT>'
{
  "accounts": [
    {
      "id": "UUID1",
      "balance": 12000000000
    },
    {
      "id": "UUID2",
      "balance": 5600000000000000
    }
  ]
}
  1. ๐Ÿ’ธ
$ curl -X "POST" "http://localhost:3000/cmd/transfer" \
     -H 'Authorization: Bearer <TOKEN>' \
     -H 'Content-Type: application/json' \
     -d $'{
  "amount": 1,
  "message": "Te quiero",
  "from_account_id": "UUID1",
  "to_account_id": "UUID2"
}'
  1. Repeat step two, and you should see a change.

TODO's & Room for Improvement

Here, the list of improvements I would have taken on with more time:

  • Add support for currency and fully implement the Money pattern.
  • Optimize size of Docker images.
  • Added i18n support to the error messages generated by the backend (or at least to return error codes that can be easily translated in the frontend).
  • Implement GraphQL for mutations, query, payload validation and subscriptions too.
  • Add application monitoring and issue application metrics.
  • Add CI/CD integration.
  • Add more code comments.

zivwi's People

Contributors

tehanswer avatar

Stargazers

Vasiliy Bukharev avatar Andreea avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.