List functional requirements for the system (Ask the chat bot for hints if stuck.)...
List non-functional requirements for the system...
Estimate the scale of the system you are going to design...
Define what APIs are expected from the system...
Customers
GET /items
accepts filter query parameter
{
description: text,
price[lte,gte,eq]: text,
popularity: text,
sort_by: text,
order_by: text,
offset: int,
limit: int,
}
Response will be a list of item descriptions like title, price, status, and image.
GET /items/
Given an item ID, fetch detailed description about the item and the latest status on whether it's still available.
POST /orders
request body
{
items: [
{
item_id: text,
quantity: int
}
],
payment_info: json,
promo_code: text,
}
Given a customer's cart and customer's payment information, we can place an order.
GET /orders?customer_id=
Given a customer ID, fetch the latest N orders
POST /items
request body
{
item_id: text,
business_id: text,
inventory_metadata: json,
price: decimal,
amount: int
}
We want to have a well defined inventory metadata json data structure and perform some data validation to ensure our clients can parse the data correctly.
PUT /items
request body
{
item_id: text,
business_id: text,
inventory_metadata: json,
price: decimal,
amount: int
}
Defining the system data model early on will clarify how data will flow among different components of the system. Also you could draw an ER diagram using the diagramming tool to enhance your design...
Focusing on the NoSQL DB data schema
Inventory and order NoSQL DB
Item table
{
id: text (primary key),
business_id: text ("foreign key" to the business id in the SQL DB),
title: text,
summary: text,
descriptors: json,
price: decimal,
created_at: timestamp,
modified_at: timetamp,
}
We can partition by business_id and item id to keep all the items from the same business in the same partition.
Sort by created_at so we can access the most recent items
item_quantity table
{
id: text,
business_id: text
quantity: int
}
We can partition by business_id and item id to keep all the items
Order table
{
customer_id: text,
order_id: text
items: [
{
id: text,
quantity: text,
price: decimal
}
],
promo_code: text,
taxes: decimal,
shipping: decimal,
total_price: decimal,
transaction_date: timestamp
}
We can partition by customer id and order id and sort by the transaction date. This way we can keep all the orders from the same customer in the same partition
You should identify enough components that are needed to solve the actual problem from end to end. Also remember to draw a block diagram using the diagramming tool to augment your design. If you are unfamiliar with the tool, you can simply describe your design to the chat bot and ask it to generate a starter diagram for you to modify...
Explain how the request flows from end to end in your high level design. Also you could draw a sequence diagram using the diagramming tool to enhance your explanation...
Dig deeper into 2-3 components and explain in detail how they work. For example, how well does each component scale? Any relevant algorithm or data structure you like to use for a component? Also you could draw a diagram using the diagramming tool to enhance your design...
Explain any trade offs you have made and why you made certain tech choices...
Storing item counts in SQL vs NoSQL store
Storing Item Counts in SQL (ACID):
Tradeoffs:
Storing Item Counts in NoSQL:
Tradeoffs:
Given that our system is a read-heavy system, I think we will store the item counts a NoSQL table. A document database like MongoDB still offers strong consistency, so if an item count gets to 0 during order placement API calls, our service will be able to return an error to the user to inform them that an item is out of stock.
Try to discuss as many failure scenarios/bottlenecks as possible.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?