Deployed the solution in an ec2 instance; you can check out from here - http://mojaams.uraniumreza.me
Pizza ordering services with the following functionality:
- Order a pizza:
- Specify the desired pizza type (margarita, marinara, salami), the number of pizza items and their size (small, medium, large). Example: 1 x Salami small, 2 x Marinara large, 1 x Salami medium
- An order should contain information about the customer: name, address
- It should be possible to track the status of order delivery. (new, preparing, delivering, delivered)
- Update an order:
- There should be a possibility to update the order details (pizzas/number of pizzas/size)
- There should be a possibility to change the status of order delivery
- An order in some delivery statuses (e.g. delivered) could not be updated
- Remove an order
- Retrieve an order
- List orders
- Provide filtering by status/customer
I've created 5 tables for the solution of the task. Used sequelize
with PostgreSQL
for migration, seed, and querying from the tables.
Items
for storing pizza-items related information i.e.name
andstatus
. The default status of each item isactive
. We caninactive
a particular item so that end-users won't see a particular item.Variants
for storing different variations e.g. large, medium, etc. Here, we have only thename
field.ItemVariants
is the table to normalize the many-many relationship betweenItems
andVariants
; here we'll haveitemId
,variantId
andstatus
to identify each item variation. Now, this table has one-to-many relationship with the other two tables. For simplicity, I'm assuming that each item will have at least one variant!Orders
to keep customer information i.e.name
andaddress
and thestatus
of the order. The initial status of each order ispending
.OrderItems
is to store all the order-items and theirquantity
. Each order-item has astatus
so that an order-item can becanceled
separately.
- express.js: To develop the RESTful API service
- joi: To create my own
validator
middleware forrequest
object validation- Created a global
error-handler
along with extending theError
object to create acustomError
- Created a global
- jest and supertest: For unit-testing the
services
and integration testing the routes/end-points
filename | description |
---|---|
bin/www | contains the server |
config/config.json | sequelize config file |
src/__tests__ | contains all the unit-tests and integration-tests |
src/controllers | defines all the end-points |
src/middlewares | contains all the middlewares |
src/migrations | all the migration files generated by sequelize |
src/models | contains data-models of each table |
src/seeders | seed-data to initialize the database with dummy data |
src/services | contains all the business-logics for controllers |
I've used postman
during my API-services development time; here's the collection that might help you to test the _API_s easily: MoJaams Postman API Collection
- Get item list filtered with
status
(optional, if not sent fetch all items regardless of thestatus
)
GET :: /api/v1/items?status=active
- Create a single item; just need to send the
name
POST :: /api/v1/items
- Create a variant with a name; same as the item creation
POST :: /api/v1/variants
- Retrieve information of a single variant
GET :: /api/v1/variants/:variantId
- Get all the item-variants filtered with
status
GET :: /api/v1/item-variants
- Create a order with
customerName
,customerAddress
anditems
POST :: /api/v1/orders
- Get order-list filtered-by
status
andcustomerName
; support of pagination
GET :: /api/v1/orders
- Retrieve a particular order detail
GET :: /api/v1/orders/:orderId
- Update particular order information; also update order-items information
PATCH :: /api/v1/orders/:orderId
To remove an order we can use the patch
API to update the status to canceled
I wrote extensive unit-tests and integration-tests for the create-order APIs and services. I also wrote a few unit-tests for items and item-variants services. Here's the code-coverage report -
- create-react-app: To bootstrap the project
- prop-types: For static type checking for all the components
- use-http: For data-fetching purpose
- cypress, jest: For snapshot-tests and end-to-end tests
As the main task is to build a simplified UI to place an order; I didn't use
react-router
, I believe it could be an overkill for this task. Also, I didn't use any state management tools e.g.redux
/mobx
. The amount of data/state we had to manage for this task is too little to jump into configuringredux
.
Everything under src
directory -
filename | description |
---|---|
cypress/e2e | contains e2e test specs |
src/__tests__ | contains all the snapshot-tests |
src/components | contains all components |
src/App.js | root component; container-component |
src/App.css | all the styles |
Used jest
and react-test-render
to write snapshot tests for all the components. Wrote a cypress spec for app.js
to test the whole end-to-end test of the order creation process. Here's the snap video:
First, we need to clone the repo -
git clone [email protected]:uraniumreza/MoJaams.git
Then, we'll build our docker containers -
docker-compose up --build
Wait for our docker containers to be up! And then we'll run the database creation (both dev
and test
), migration and seed scripts -
docker exec --user postgres mojaams_db /bin/sh -c 'createdb mojaams_test; createdb mojaams_dev;'
docker exec mojaams_backend /bin/sh -c "npx sequelize-cli db:migrate; npx sequelize-cli db:seed:all;"
So, our services are up; we can test - MoJaams
docker exec mojaams_backend /bin/sh -c "npm test"
SnapShot tests: docker exec mojaams_frontend /bin/sh -c "cd app; npm test;"
E2E test: docker exec mojaams_frontend /bin/sh -c "cd app; npm run test:e2e;"