Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

53 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

authorize

Simple authorization handler created for Nubank

Table of Contents

Architecture

This architecture proposal for an authorization handler was based on some premises:

  • Isolation of the business logic (provide good test coverage)
  • Extension (to add new rules and violations)
  • Easy maintenance

To fulfill the first premise, I thought I could implement the Repository Pattern. In this way, it was possible to separate the data access logic from the domain logic. This would be concentrated in a layer called Service. I tried in some way to apply the bounded context (DDD) to isolate the domains and I believe I've arrived a reasonable result. I believe that architectures are evolutionary and the proposed structure could at some point receive other layers to accompany the needs and growth of the application.

It was interesting to take the challenge of developing the project in clojure. I am not proficient in that language and yet I realized its benefits. The agility in development and the ease of refactoring were often notorious. These points were only achieved by the guarantee that the unit tests brought. In this way it was possible to maintain a good code coverage (90%>) throughout the development.

Dependencies

Setup

Docker: build and usage

This script uses the same environment variables as libpq to connect to a PostgreSQL server.

docker build -t authorizer .
docker run -i authorizer < operations

Lein usage

This script uses the same environment variables as libpq to connect to a PostgreSQL server.

lein run < operations

Uberjar: build and usage

This script uses the same environment variables as libpq to connect to a PostgreSQL server.

lein uberjar
java -jar target/authorize-standalone.jar < operations

Binary: build and usage

This script uses the same environment variables as libpq to connect to a PostgreSQL server.

lein bin
bin/authorize < operations

Violations

Are a set of rules that transactions must satisfy to be captured.

Already initialized

Check if account was previously initialized. Return "account-already-initialized" if true.

Payload events example
{ "account": { "activeCard": true, "availableLimit": 100 } }
{ "account": { "activeCard": true, "availableLimit": 100 } }
{ "transaction": { "merchant": "Bullguer", "amount": 10, "time": "2019-02-13T11:00:00.000Z" } }
docker run -i authorizer < operations

Output

{"account":{"activeCard":true,"availableLimit":100},"violations":[]}
{"account":{"activeCard":true,"availableLimit":100},"violations":["account-already-initialized"]}
{"account":{"activeCard":true,"availableLimit":90},"violations":[]}

Card not active

Check if card is active at account entity. Return "card-not-active" if true and and block the transaction from been captured.

Payload events example
{ "account": { "activeCard": false, "availableLimit": 100 } }
{ "transaction": { "merchant": "Starbucks", "amount": 10, "time": "2019-02-13T11:00:00.000Z" } }
docker run -i authorizer < operations

Output

{"account":{"activeCard":false,"availableLimit":100},"violations":[]}
{"account":{"activeCard":false,"availableLimit":100},"violations":["card-not-active"]}

Doubled transaction

Check if there were two or more transactions with the same merchant and amount in a time window (2 minutes). Return "doubled-transaction" if true and block the transaction from been captured.

Payload events example
{ "account": { "activeCard": true, "availableLimit": 100 } }
{ "transaction": { "merchant": "Cuor di Crema", "amount": 10, "time": "2019-02-13T11:00:00.000Z" } }
{ "transaction": { "merchant": "Cuor di Crema", "amount": 10, "time": "2019-02-13T11:00:00.000Z" } }
{ "transaction": { "merchant": "Cuor di Crema", "amount": 10, "time": "2019-02-13T11:00:00.000Z" } }
docker run -i authorizer < operations

Output

{"account":{"activeCard":true,"availableLimit":100},"violations":[]}
{"account":{"activeCard":true,"availableLimit":90},"violations":[]}
{"account":{"activeCard":true,"availableLimit":80},"violations":[]}
{"account":{"activeCard":true,"availableLimit":80},"violations":["doubled-transaction"]}

High frequency at small interval

Check if there were three or more transactions in a time window (2 minutes). Return "high-frequency-small-interval" if true and block the transaction from been captured.

Payload events example
{ "account": { "activeCard": true, "availableLimit": 100 } }
{ "transaction": { "merchant": "Lojas Americanas", "amount": 10, "time": "2019-02-13T11:00:10.000Z" } }
{ "transaction": { "merchant": "Lojas Americanas", "amount": 10, "time": "2019-02-13T11:00:43.000Z" } }
{ "transaction": { "merchant": "Submarino", "amount": 10, "time": "2019-02-13T11:00:55.000Z" } }
{ "transaction": { "merchant": "Ricardo Eletro", "amount": 10, "time": "2019-02-13T11:00:59.000Z" } }
{ "transaction": { "merchant": "Kalunga", "amount": 10, "time": "2019-02-13T11:01:11.000Z" } }
{ "transaction": { "merchant": "Kalunga", "amount": 10, "time": "2019-02-13T11:05:11.000Z" } }
docker run -i authorizer < operations

Output

{"account":{"activeCard":true,"availableLimit":100},"violations":[]}
{"account":{"activeCard":true,"availableLimit":90},"violations":[]}
{"account":{"activeCard":true,"availableLimit":80},"violations":[]}
{"account":{"activeCard":true,"availableLimit":70},"violations":[]}
{"account":{"activeCard":true,"availableLimit":70},"violations":["high-frequency-small-interval"]}
{"account":{"activeCard":true,"availableLimit":70},"violations":["high-frequency-small-interval"]}
{"account":{"activeCard":true,"availableLimit":60},"violations":[]}


Insufficient limit

Check if available amount is bigger than the transaction amount. Return "insufficient-limit" if true and block the transaction from been captured.

Payload events example
{ "account": { "activeCard": true, "availableLimit": 60 } }
{ "transaction": { "merchant": "Tok&Stok", "amount": 50, "time": "2019-02-13T11:00:10.000Z" } }
{ "transaction": { "merchant": "Bullguer", "amount": 13, "time": "2019-02-13T11:00:43.000Z" } }
docker run -i authorizer < operations

Output

{"account":{"activeCard":true,"availableLimit":60},"violations":[]}
{"account":{"activeCard":true,"availableLimit":10},"violations":[]}
{"account":{"activeCard":true,"availableLimit":10},"violations":["insufficient-limit"]}

Development

Run tests

Run all unit tests

lein midje

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages