Authorizer is an application that authorizes a transaction for a specific account following a set of predefined rules.
The authorizer is going to be provided JSON lines as input in the stdin and should provide a JSON line output for each one — imagine this as a stream of events arriving at the authorizer.
All operations in the stream are transformed into account statements and saved in a history for later usage.
The authorizer utilizes design patterns to provide a maintainable code.
The adapter pattern creates a builder to handle each type of operation.
Strategy pattern offers a structure to handle multiple violations that can occur in an operation.
The program handles two kinds of operations, deciding on which one according to the line that is being processed:
- Account creation
- Transaction authorization
For the sake of simplicity, you can assume:
- All monetary values are positive integers using a currency without cents
- Transactions will arrive in chronological order
Input
Creates the account with available-limit
and active-card
set. For simplicity's sake, we will assume the application will deal with just one account.
Output
The created account's current state + all business logic violations.
Business rules
- Once created, the account should not be updated or recreated:
account-already-initialized
.
Examples
input
{"account": {"active-card": true, "available-limit": 100}}
...
{"account": {"active-card": true, "available-limit": 350}}
output
{"account": {"active-card": true, "available-limit": 100}, "violations": []}
...
{"account": {"active-card": true, "available-limit": 100}, "violations": ["account-already-initialized" ]}
Input
Tries to authorize a transaction for a particular merchant
, amount
, and time
given the account's state and last authorized transactions.
Output
The created account's current state + all business logic violations.
Business rules
- No transaction should be accepted without a properly initialized account:
account-not-initialized
- No transaction should be accepted when the card is not active:
card-not-active
- The transaction amount should not exceed the available limit:
insufficient-limit
- There should not be more than 3 transactions on a 2-minute interval:
high-frequency-small-interval
- There should not be more than 1 similar transaction (same amount and merchant) in a 2 minutes interval:
doubled-transaction
Examples
Given there is an account with active-card
: true and available-limit
: 100
input
{"transaction": {"merchant": "Burger King", "amount": 20, "time": "2019-02-13T10:00:00.000Z"}}
output
{"account": {"active-card": true, "available-limit": 80}, "violations": []}
- Ruby v2.7.2
To run Authorizer you just need to run:
$ bin/authorize
It will open a prompt and you can provide JSON
lines. Alternatively, you can input a stream of events from a file.
$ cat operations
{"account": {"active-card": true, "available-limit": 100}}
{"transaction": {"merchant": "Burger King", "amount": 20, "time": "2019-02-13T10:00:00.000Z"}}
{"transaction": {"merchant": "Habbib's", "amount": 90, "time": "2019-02-13T11:00:00.000Z"}}
$ bin/authorize < operations
Make sure to have installed Ruby v2.7.2 in your console, then run:
$ bundle install
$ bin/authorize
$ docker-compose run authorizer bin/authorize
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/authorizer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
The api is available as open source under the terms of the MIT License.
Everyone interacting in the Authorizer project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the code of conduct.