Skip to content

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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
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:

tsx
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.

tsx
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]

Untitled

Concept Implementation Reflections

  1. Profile [User]

    1. Profile is inherently similar to posts, but it has different content format and doesn’t require reply
    2. I started by modify= the provided “post” concept, and define the interface suitable for the states of profile use.
    3. 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.
  2. Relationship [User]

    1. “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.
    2. 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.

Untitled

Vercel Deployment Link: 61040-backend.vercel.app

RESTful routes: https://github.com/srcJin/61040-backend/blob/main/server/routes.ts