Chapter 4: Backend Design Document - Alpha
Data Modeling
User
Purpose: To provide an identity for user account and information
Principle: Stores credential and username
States:
registered: set User
username, password: registered -> one String
registered: set User
username, password: registered -> one String
Profile [User]
Purpose: To store the user’s personal information
Principle: Each user has their initial profile when they registered. The profile can be updated. And will be deleted after user delete their account.
State:
nickname: one String
email: one String
dateJoined: one int (timestamp)
headshotUrl: one String
identity: one String
role: one int
region: set Float
liked: set Item (Post/Reply)
favorite: set Item (Post/Reply)
nickname: one String
email: one String
dateJoined: one int (timestamp)
headshotUrl: one String
identity: one String
role: one int
region: set Float
liked: set Item (Post/Reply)
favorite: set Item (Post/Reply)
Session [User]
Purpose: Manage and maintain the state of a user in the system over t period.
Principle: A session begins when a user login. Session maintains state s for time t the session will expire after time t. after a session starts (and before it ends), the getUser action returns the user identified at the start: start (u, s); getUser (s, u.)
State:
active: set Session
user: active -> one User
active: set Session
user: active -> one User
Relationship [User]
Purpose: To define and manage the connection states between users
Principle: The relationship has directional states. It will take a set of User object and record their relationship states.
State:
Rel : Relationship -> set String // define the relationship as a set
u1, u2: Rel -> set User // assign relationship between u1 and u2, the u1 is the origin, u2 is the target. u1 -> u2 forms a directional relationship
relationship: Rel -> set String // the type of relationship between two users can be follower, friend to partner, to activate different functions.
Rel : Relationship -> set String // define the relationship as a set
u1, u2: Rel -> set User // assign relationship between u1 and u2, the u1 is the origin, u2 is the target. u1 -> u2 forms a directional relationship
relationship: Rel -> set String // the type of relationship between two users can be follower, friend to partner, to activate different functions.
Map
Purpose: To provide a visual representation of geographic data and allow users to interact with it. It also serves as a base to display location based informations, such as markers.
Principle: On mobile platforms, users can use touch gestures to interact with maps. On desktop, they can use mouse. Map have multiple layers and can change themes (provided by api). Map can display markers on its geographical locations.
State:
centerPoint: set Float ((set [lng, lat]))
zoomLevel: Float
layers: set String (Collections of data visualized on the map (e.g., flower field))
markers: Symbols or icons indicating points of interest or events.
theme: Visual style (e.g., satellite, terrain, nighttime).
centerPoint: set Float ((set [lng, lat]))
zoomLevel: Float
layers: set String (Collections of data visualized on the map (e.g., flower field))
markers: Symbols or icons indicating points of interest or events.
theme: Visual style (e.g., satellite, terrain, nighttime).
Location [User]
Purpose: To represent a user’s current or last avaliable position for various functions such as finding nearby users or places.
Principle: location has two states, precise location and salted location. The salted location is a processed coordination that will return a vague location of the user.
State:
position: set Float ([lng, lat])
isSalted: one Boolean
visibility: Boolean (whether the user's location is visible to others)
position: set Float ([lng, lat])
isSalted: one Boolean
visibility: Boolean (whether the user's location is visible to others)
Nearby[Location]
Purpose: To determine the proximity of users or places relative to a given location.
Principle: Calculate the distances between users or items on the map, and return a set of items that matches the desired radius.
State:
currentLocation: Location
isNearby: one Boolean
nearbyUsers: set User
currentLocation: Location
isNearby: one Boolean
nearbyUsers: set User
Marker [User]
Purpose: To display specific points of interest, events, or user locations on the map.
Principle: The Marker can be interacted and expanded into a larger information card. The Marker has different types, now including User, and POI points of interest. If the density of the marker becomes too large, they can be clustered into one marker, which will show a list by activation.
State:
location: set Float
type: one String (User/POI)
cluster: set User
location: set Float
type: one String (User/POI)
cluster: set User
Favorite[User, Item]
Purpose: Save articles and answers for later review. It will also boost the mass voting system.
Principle: The user can click favorite from a list, and jump to the corresponding article. They can also delete their favorite item.
State:
items: set String
user: set String
favoriteCount: int
favoriteList: set String
items: set String
user: set String
favoriteCount: int
favoriteList: set String
Like[User, Item]
Purpose: A mass-voting mechanism to identify good quality contents from the community
Principle: User can upvote by clicking a button next to a post/answer. Good quality contents will raise to the top of the answer list
State:
items: one String
users: set String
likeCount: one int
items: one String
users: set String
likeCount: one int
Tag[User, Item]
Purpose: a general parameter to aid classification of posts, replies and users
Principle: the app will provide some necessary tags, like comment, article, to make the “post” and “reply” functioning. a tag can be assigned to multiple items. An item can have multiple tags. Required tags can’t be deleted, because it will be necessary for classification purpose. Normal tags can be deleted.
State:
name: Tag -> one String
owns: User -> set Tag
tags: Item -> set Tag
required: Tag -> one Boolean
name: Tag -> one String
owns: User -> set Tag
tags: Item -> set Tag
required: Tag -> one Boolean
Post [User]
Purpose: Post is the core concept of this app. It represents a general rich text message that applicable to use as article, question and knowledge(for optional function wiki)
Principle: Posts are created using editing tools in each functions. Posts can be edited or delete by the user, but can’t be edit by other user. Posts have visibility options. By default, it is set to public, meaning all users can view. It can also be set as private, friends-only or partner-only.
State:
name: one String
time: one int (timestamp)
title: one String
content: one String
tags: set String
visibility: one String // public, private, friendsOnly, partnersOnly
type: one String // article, question
likeCount: one int // do we need to store all the liked users?
favoriteCount: one int
likedBy: set User
favoritedBy: set User
name: one String
time: one int (timestamp)
title: one String
content: one String
tags: set String
visibility: one String // public, private, friendsOnly, partnersOnly
type: one String // article, question
likeCount: one int // do we need to store all the liked users?
favoriteCount: one int
likedBy: set User
favoritedBy: set User
Reply [User, Post]
Purpose: Reply contains two user cases: comment on a post, or answer on a question. It depends on a post to exist.
Principle: Replies can only be created after a post. It can’t independently exist. Only registered user can reply a post. Reply uses private parameter to identify types. Like Post, Reply can also be favorited or liked by users.
State:
name: one String
time: one int (timestamp)
title: one String
content: one String
tag: set String
linkedPost: one String
visibility: one String // public, private, friendsOnly, partnersOnly
type: one String // article, question
likeCount: one int // do we need to store all the liked users?
favoriteCount: one int
likedBy: set User
favoritedBy: set User
name: one String
time: one int (timestamp)
title: one String
content: one String
tag: set String
linkedPost: one String
visibility: one String // public, private, friendsOnly, partnersOnly
type: one String // article, question
likeCount: one int // do we need to store all the liked users?
favoriteCount: one int
likedBy: set User
favoritedBy: set User
App Definition
Write a definition of your app as a list of concepts, with type parameters instantiated appropriately, and draw a diagram (like those we looked at in lecture) showing the state of the entire app, with contours showing which subdiagrams belong to which concepts.
app WeeHive
concepts
User
Profile [User.User]
Relationship [User.User]
Session [User.User]
Post [User.User]
Reply [Post.Post, User.User]
Tag [Post.Post / User.User] // how to define a concept that can be applied to both?
Favorite [Post.Post]
Like [Post.Post]
Map
Marker[User.User] // to display the sentiment calculated from reactions for each post.
Location [User.User]
Nearby [User.User]
app WeeHive
concepts
User
Profile [User.User]
Relationship [User.User]
Session [User.User]
Post [User.User]
Reply [Post.Post, User.User]
Tag [Post.Post / User.User] // how to define a concept that can be applied to both?
Favorite [Post.Post]
Like [Post.Post]
Map
Marker[User.User] // to display the sentiment calculated from reactions for each post.
Location [User.User]
Nearby [User.User]
Concept Implementation Reflections
Profile [User]
- Profile is inherently similar to posts, but it has different content format and doesn’t require reply
- I started by modify= the provided “post” concept, and define the interface suitable for the states of profile use.
- The key difference between “post” and “profile” is one user can only have one profile but multiple posts. So the next step is to fit this need by removing some features that designed for multiple post returns.
Relationship [User]
- “Relationship” is an extended “Friend” concept. In my app, a relationship has 4 states: no relationship, one direction follow (no need for approval), two-directional friendship, and two-directional partnership. I first duplicated the existing functions and added the related functions to util.ts. I merged the outputs related to get functions, but still working on reduce redundancy.
- During implementation, I found generalizing a concept may bring additional complexity to one concept design, but it will in turn make the program structure nicer. It is a trade-off between designing one concept that can be applied to multiple use cases. Currently, my implementation heavily relies on the starter code. I hope once I get more familiarized with it I can implement more innovative concepts this week.
Related Links
Vercel Deployment Link: 61040-backend.vercel.app
RESTful routes: https://github.com/srcJin/61040-backend/blob/main/server/routes.ts