Let us assume a comment has a 200 character limit, can allow a maximum of one image/file. Assume a 10 year lifespan with 100,000 daily active users who comment on average 5 comments per user.
User{
user_id: 10 bytes,
username: 10 bytes,
password: 10 bytes,
notification_log: 100 bytes (10 notification id's for comments that were replied to)
}
(10 + 10 + 10 + 100) = 130 bytes
Notification{
notification_id: 10 bytes,
comment_id: 10 bytes
}
Report{
user_id: 10 bytes,
comment_id
}
20 bytes
Comment{
comment_id: 10 bytes,
user_id: 10 bytes,
prev_id: 10 bytes,
comment_text: 200 bytes,
media_id: 10 bytes,
date: 8 bytes,
reports: 100 bytes
}
10 + 10 + 10 + 200 + 10 + 8 =248 bytes
(248 * 5 * 100000) = 124000000 bytes of comments a day
(130 * 100000) = 13000000 bytes for user data
(124000000 + 13000000) * 365 * 10 = around 500 GB of data over 10 years
CreateAccount(username,password) -> creates an account for a user
CreateComment(user_id,prev_id, comment_text, media_id,date) -> Create a comment as a user
ModerateComment(comment_id) -> Is called whenever a user posts a comment to moderate text, or if a user has received sufficient reports (10 reports) on their comment.
ReportComment(user_id, comment_id) -> Will append a report to a comment's reports log when someone decides a comment needs moderation
SendNotification(user_id,comment_id) -> Append a notification to a user's notification inbox and show some comment data regarding the thread
DeleteComment(user_id,comment_id) -> Delete a user's comment and remove all user data from that comment and replace with text like username-> [Deleted], comment_text -> "This comment was deleted" etc
LogOut(user_id) -> Allows a user to logout of their account
User{
user_id: string,
username: string,
password: string,
notification_log: Notification[]
}
(10 + 10 + 10 + 100) = 130 bytes
Notification{
notification_id: String,
comment_id: String
}
Report{
user_id: string,
comment_id: string,
}
20 bytes
Comment{
comment_id: string,
user_id: string,
prev_id: string,
comment_text: string,
media_id: string,
date: datetime,
reports: Report[]
}
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...
CreateComment -> if prev_id is -1 then it is a new comment thread, otherwise it will be the comment id a person is responding to. Creating a comment will first push its content through a moderation service before being posted. If a user breaks moderation rules, they will receive an error informing them to change their comment
DeleteComment -> When a user deletes a comment, there are some scenarios where the comment data structure would change in a few different ways:
I choose to use a graph database like neo4j here. This is because I recognize the data structure of these comments are graphs. Neo4j would provide the most efficient way to query the database as well as make changes.
I choose to use a moderation service like openai content moderator which utilizes linear language models to detect inappropriate content. Their api is free and can cut down a lot of workload on creating our own moderation system.
I choose to use a online storage service like amazon s3 to handle image/file upload. This reduces strain on our database especially since it is a graph database which may not efficiently hold image/file data.
We can use a service like OAuth to handle user authentication.
Race condition: we can overcome this with optimistic concurrency control where we compare the the state of the database before and after a comment is submitted. We can throw an error if the comment data that is being responded to was changed