List functional requirements for the system (Ask the chat bot for hints if stuck.)...
track the users progress in multiple criteria
goal tracking
leaderboards
List non-functional requirements for the system...
highly available
secure and private
Estimate the scale of the system you are going to design...
user data:
name ,age- 10 bytes
weight - 3 bytes / day
activity:
highball and say 100 bytes per session
500 million users, 100 million DAU (one activity per day)
names => 5 GB
metrics per day => 10 GB / day => 3.5 TB / year
Define what APIs are expected from the system...
create_user(name, age, weight)
POST api/v1/create_user
enter_workout(user_id, workout data, timestamp)
POST /api/v1/enter_workout/{user_id,timestamp}
I'm thinking of sending multiple requests per workout for reasons I'll explain later. So this will be requested frequently.
get_data(user_id, filters = (calories, miles, any historical data really)
GET api/v1/data/{user_id},filters
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...
Relational Database for regular user data, Timeseries DB for historical data. It's important to note that many people participate in numerous activities, so we need to think about database design. Running is measured in miles, but swimming is in laps, and lifting is in sets x weights. Therefore, to avoid lots of sparse data it makes sense to have separate databases for each. TimeScaleDB makes sense here because this is time series data.
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...
for each workout, I think periodic pushes (every 30 seconds or maybe even 10 seconds) makes sense here. It allows for the data to be as specific as possible without taking up too much bandwidth. Since our app works with people all over the globe, I don't think well ever be swamped. However we can throttle for high density areas (ex. NYC in the morning) if needed. A message queue would be great to handle the high throughput. Websockets are quick to jam servers, but since people workout for max two hours, they should be okay. Web sockets will be more reliable than constant pushes. We could also ask the user how often they want to push data, as things like battery life will be affected. Furthermore, if we pair this with other devies such as Whoop or Apple Watch, we can push more information such as heart rate.
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...
We can have a microservice that checks all incoming information and compares it to its goals. It could hold the lowest leaderboard value, and if anything goes higher then it will start a service to update the values.
Explain any trade offs you have made and why you made certain tech choices...
Try to discuss as many failure scenarios/bottlenecks as possible.
If the user is in a place with low internet, we can switch to significantly lower frequency and even less data (only sending 5-10 byte updates of miles run for instance) and potentially use a local storage until the user is back in better conditions.
What are some future improvements you would make? How would you mitigate the failure scenario(s) you described above?