An application that authorizes a transaction for a specific account following a set of predefined rules.
The program handles two kinds of operations, deciding on which one according to the line that is being processed:
- Account creation
- Transaction authorization
Your program 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.
$ 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"}}
$ authorize < operations
{"account": {"active-card": true, "available-limit": 100}, "violations": []}
{"account": {"active-card": true, "available-limit": 80}, "violations": []}
{"account": {"active-card": true, "available-limit": 80}, "violations": ["insufficient-limit"]}
The program should not rely on any external database. Internal state should be handled by an explicit in-memory structure. State is to be reset at application start.
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.
Creates the account with available-limit and active-card set. For simplicity sake, we will assume
the application will deal with just one account.
The created account's current state + any business logic violations.
- Once created, the account should not be updated or recreated:
account-already-initialized.
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" ]}
Tries to authorize a transaction for a particular merchant, amount and time given the account's state and last
authorized transactions.
The account's current state + any business logic violations.
You should implement the following rules, keeping in mind new rules will appear in the future:
-
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 available limit:
insufficient-limit -
There should not be more than 3 transactions on a 2 minute interval:
high-frequency-small-interval(the input order cannot be relied upon, since transactions can eventually be out of order respectively to theirtimes) -
There should not be more than 1 similar transactions (same amount and merchant) in a 2 minutes interval:
doubled-transaction
input
{"transaction": {"merchant": "Burger King", "amount": 20, "time": "2019-02-13T10:00:00.000Z"}}
output
{"account": {"active-card": true, "available-limit": 80}, "violations": []}
input
{"transaction": {"merchant": "Habbib's", "amount": 90, "time": "2019-02-13T11:00:00.000Z"}}
output
{"account": {"active-card": true, "available-limit": 80}, "violations": ["insufficient-limit"]}
To run the tests:
make test
$ cargo doc --no-depsmit