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. We can scale this application by sharding the database by geolocation. This way people who are in communities with different languages can query the database more efficiently
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.
We will have to implement a rate limiter for users who try and create many comments at once which can rapidly affect the comment thread structure.
we can overcome race condition 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
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