Cabify backend test
Resolution
This resolution in this repository is the one for Cabify Backend Challenge
And was thought in these steps:
- Analysis of the problem
- Environment setup. Repository with CI via gitlab and gitlab pipelines
- Was written using TDD for most of the core packages.
- Overall testing and documentation writing
Databases are all objects (dictionaries) in memory, as the exercise described. Besides this solution fits the problem, in a real world scenario i would use:
- Redis: for basket memory, to provide a fast, scalable and reliable source for user sessions and their baskets
- Postgres: for products and strategies database, as it's a simple yet reliable datastore
Requirements
Node v11.0.0
Go 1.11.1
To run the server locally
Docker 18.06.01-ce
Those versions are development tested. Despite it may work with earlier versions, i recommend using this
Run
You can run it with docker
via:
docker build -t rburdet/cabify .
docker run -it --rm -p 3000:3000 rburdet/cabify
Or locally using make
via:
make
make run
You can see what other commands are available by running make help
You can run the client via:
cd cli
npm i
npm start
Considerations
- Promotion order matter, so applying bulk and then 2x1 is different as applying 2x1 and then bulk.
- This promotions are loaded in a (mocked) database, production code should be a microservice for asking discounts strategies.
- I didn't work using git flow because it was me alone on this project and i saw no gains in using it.
- Dockerfile has a multi stage build to provide smaller images size, this one is
16.1MB
.
Client
Client is a simple CLI made with Node.js
, its a simple index file with inquirer handling user input.
Future work
On the server:
- Today baskets doesnt expire or finish ( as it wasn't an exercise requirement ). I should use TTLs on them and accept finishing a session/basket.
- There aren't many safity checks for edge cases, like posting to a non existent basket, will do nothing but wont notify anything weird. I should implement http 4xx and 5xx cases, and a better logging logic.
On the client:
- all the configuration is static.
- While the server keeps a basket ID in which you can make your operations at any time, the client generates a basket ID with every execution, you could think about it like a new session.
- I used promises and async/await to show that i can use both of them.