Assignment 4: Backend Design & Implementation
Assignment Instructions
These are the 6.1040 assignment instructions for this assignment. It goes into greater depth about the expectations, requirements, and deliverables for this assignment. It also includes a rubric detailing how this assignment will be graded.
Community Carpool
A communal carpool coordination social network connecting users that are traveling to the same activity, using location data to help plan the most efficient and convenient routes.
Summary
I implemented my Concepts and was able to successfully deploy these Concepts to Vercel. This required a lot of functionality to be implemented, designing/structuring synchronizations, and database development! Many of these concepts will be modified (or implemented differently) as I progress with the project. As I continue to develop these ideas, I plan to modify my backend structure to better handle my needs. Everything below is my objective/goal.
Backend Deployment
GitHub Repository for Community Carpool's Backend
Vercel Deployment for Community Carpool's Backend
Abstract Data Model Diagram

Concepts
Location
Purpose
A physical address/location associated with another entity (User, Activity, etc.)
Principle
Locations represent physical addresses on Earth that are associated with a User or an Activity. They must be valid addresses.
State
locations: set Location
address: stringlocations: set Location
address: stringActions
verifyRealAddress(address: str) -> Location
## Check public maps APIs to see whether address exists
assert address is real
setLocation(address: str) -> Location
location = verifyRealAddress(address: str)
location.address = address
locations += locationverifyRealAddress(address: str) -> Location
## Check public maps APIs to see whether address exists
assert address is real
setLocation(address: str) -> Location
location = verifyRealAddress(address: str)
location.address = address
locations += locationMap [Location | Entities]
Purpose
Display the Locations on a map.
Principle
Maps would display the Locations of Users, Activities, or other entities that have a Location associated with them on a visual graphic, making it easy for Users to visualize where things are geographically.
State
locations: set Location
map: set Entitieslocations: set Location
map: set EntitiesActions
displayLocationOnMap(map: Map, location: Location) -> Map
map += location
displayUserOnMap(map: Map, user: User) -> Map
assert user.address != None
map += User.address
removeUserFromMap(map: Map, user: User) -> Map
map i= User.address
removeFromMap(map: Map, location: Location)
assert location in map
map -= locationdisplayLocationOnMap(map: Map, location: Location) -> Map
map += location
displayUserOnMap(map: Map, user: User) -> Map
assert user.address != None
map += User.address
removeUserFromMap(map: Map, user: User) -> Map
map i= User.address
removeFromMap(map: Map, location: Location)
assert location in map
map -= locationUser
Purpose
Allow users to create a public-facing user profile so that they can use tha app.
Principle
Users are represented by user profiles, which enables users to register for Activity Groups, set their addresses, and serves as a one-stop-shop for information about that user.
State
registeredUsers: set User
username: string, password: string -> register(u: string, p: string) -> User
name: string
address: string -> setLocation(address) -> Location
activities: set Activity
carpools: set CarpoolsregisteredUsers: set User
username: string, password: string -> register(u: string, p: string) -> User
name: string
address: string -> setLocation(address) -> Location
activities: set Activity
carpools: set CarpoolsActions
register(username: str, password: str) -> user: User
assert username not in registeredUsers
user = User()
user.username = username
user.password = password
user.name = None
user.address = None
registeredUsers[username] = user
authenticate(username: str, password: str) -> user: User
assert username in registeredUsers
registeredUsers[username].password == password
addName(user: User, name: str)
user.name = name
renameUser(user: User, name: str)
user.name = name
addHomeAddress(user: User, address: Location) -> Location
location: Location = setLocation(address)
user.address = location
location.homeAddresses += user
updateHomeAddress(user: User, location: Location)
user.address = location
deleteHomeAddress(user: User)
user.address = Noneregister(username: str, password: str) -> user: User
assert username not in registeredUsers
user = User()
user.username = username
user.password = password
user.name = None
user.address = None
registeredUsers[username] = user
authenticate(username: str, password: str) -> user: User
assert username in registeredUsers
registeredUsers[username].password == password
addName(user: User, name: str)
user.name = name
renameUser(user: User, name: str)
user.name = name
addHomeAddress(user: User, address: Location) -> Location
location: Location = setLocation(address)
user.address = location
location.homeAddresses += user
updateHomeAddress(user: User, location: Location)
user.address = location
deleteHomeAddress(user: User)
user.address = NoneSession [User]
Purpose
Authenticate a User for a period of time and set them as the active User
Principle
When a Session starts, a user's credentials and data is saved and they are "logged in" for the duration of the Session, which ultimately expires when a User "logs out". Sessions store data associated with that user for the period that the Session is active.
State
activeSessions: set Session
user: activeSessions -> UseractiveSessions: set Session
user: activeSessions -> UserActions
startSession(user: User) -> session: Session
assert user not in activeSessions
activeSessions += session
session.user = user
getUser(session: Session) -> user: User
assert session in activeSessions
user = session.user
end(session: Session)
assert session in activeSessions
activeSessions -= session
session.user = NonestartSession(user: User) -> session: Session
assert user not in activeSessions
activeSessions += session
session.user = user
getUser(session: Session) -> user: User
assert session in activeSessions
user = session.user
end(session: Session)
assert session in activeSessions
activeSessions -= session
session.user = NoneActivity [User]
Purpose
A subset of Users in a private group, where data is only accessible to those in the group.
Principle
Activities are subsets of Users who all share a commonality (participating in the same activity). Private messaging, information, and data can be accessed by Users who have been approved to join the Activity and is only accessible to Activity members.
State
managers: set User
members: set User
activityGroups: set Activity
destination: one Location
name: string
creator: one User
schedule: set Timemanagers: set User
members: set User
activityGroups: set Activity
destination: one Location
name: string
creator: one User
schedule: set TimeActions
createActivity(manager: User, destination: Location, name: str) -> Activity
assert name not in activityGroups
activity = Activity()
activity.name = name
activity.managers += manager
activity.destination = destination
activityGroups += activity
modifyDestination(activity: Activity, manager: User, destination: Location)
assert manager in activity.managers
activity.destination = destination
setActivityPassword(activity: Activity, user: User, code: str)
assert user in activity.managers
assert activity.password == None
activity.password = code
modifyActivityPassword(activity: Activity, user: User, og_pass: str, new_pass: str)
assert user in activity.managers
assert activity.password == og_pass
activity.password = new_pass
addMember(activity: Activity, user: User, password: str)
assert user not in activity.members
assert user not in activity.managers
assert activity.password == password
activity.members += user
addManager(activity: Activity, manager: User, user: User)
assert manager in activity.managers
assert user not in activity.managers
activity.members -= user
activity.managers += user
removeMember(activity: Activity, manager: User, user: User)
assert manager in activity.managers
assert user in activity.members
assert user not in activity.managers
activity.members -= user
removeManager(activity: Activity, manager: User)
assert manager in activity.managers
assert user not in activity.members
activity.managers -= managercreateActivity(manager: User, destination: Location, name: str) -> Activity
assert name not in activityGroups
activity = Activity()
activity.name = name
activity.managers += manager
activity.destination = destination
activityGroups += activity
modifyDestination(activity: Activity, manager: User, destination: Location)
assert manager in activity.managers
activity.destination = destination
setActivityPassword(activity: Activity, user: User, code: str)
assert user in activity.managers
assert activity.password == None
activity.password = code
modifyActivityPassword(activity: Activity, user: User, og_pass: str, new_pass: str)
assert user in activity.managers
assert activity.password == og_pass
activity.password = new_pass
addMember(activity: Activity, user: User, password: str)
assert user not in activity.members
assert user not in activity.managers
assert activity.password == password
activity.members += user
addManager(activity: Activity, manager: User, user: User)
assert manager in activity.managers
assert user not in activity.managers
activity.members -= user
activity.managers += user
removeMember(activity: Activity, manager: User, user: User)
assert manager in activity.managers
assert user in activity.members
assert user not in activity.managers
activity.members -= user
removeManager(activity: Activity, manager: User)
assert manager in activity.managers
assert user not in activity.members
activity.managers -= managerCarpool [User, Activity]
Purpose
A subset of Users in the same ActivityGroup that will commute together.
Principle
Carpools are subsets of Users in the same Activity who will commute to the Activity together. Private messaging, information, and data can be accessed by Users who have been approved to join the Carpool and is only accessible to Carpool members.
State
driver: one User
members: set User
capacity: Integer
activity: one Activity
schedule: getActivityTimes(Activity) -> set Timesdriver: one User
members: set User
capacity: Integer
activity: one Activity
schedule: getActivityTimes(Activity) -> set TimesActions
createCarpoolGroup(driver: User, activity: Activity, capacity: int, name: str) -> Carpool
assert name not in activity.carpools
carpool = Carpool()
carpool.name = name
carpool.driver = user
carpool.capacity = capacity
carpool.destination = activity.destination
activity.carpools += carpool
addMember(carpool: Carpool, user: User)
assert user not in carpool.members
assert user != carpool.driver
assert carpool.capacity < len(carpool.members)
carpool.members += user
changeDriver(carpool: Carpool, og_driver: User, new_driver: User)
assert og_driver == carpool.driver
assert new_driver in carpool.members
carpool.members -= new_driver
carpool.members += og_driver
carpool.driver = new_driver
removeMember(carpool: Carpool, user: User)
assert user in carpool.members
assert user != carpool.driver
carpool.members -= usercreateCarpoolGroup(driver: User, activity: Activity, capacity: int, name: str) -> Carpool
assert name not in activity.carpools
carpool = Carpool()
carpool.name = name
carpool.driver = user
carpool.capacity = capacity
carpool.destination = activity.destination
activity.carpools += carpool
addMember(carpool: Carpool, user: User)
assert user not in carpool.members
assert user != carpool.driver
assert carpool.capacity < len(carpool.members)
carpool.members += user
changeDriver(carpool: Carpool, og_driver: User, new_driver: User)
assert og_driver == carpool.driver
assert new_driver in carpool.members
carpool.members -= new_driver
carpool.members += og_driver
carpool.driver = new_driver
removeMember(carpool: Carpool, user: User)
assert user in carpool.members
assert user != carpool.driver
carpool.members -= userPost [User]
Purpose
Enables Users to share information with each other.
Principle
Users can create content and upload it to Carpool Community as a Post, allowing other Users to interact with this content, Comment on it, and react to it. Posts are a semi-public form of communication, where Users choose which subset of Users can view the Post.
State
posts: set Post
content: Post -> one Content
user: Post -> one User
reactions: Reaction -> set Reactionsposts: set Post
content: Post -> one Content
user: Post -> one User
reactions: Reaction -> set ReactionsActions
createPost(user: User, content: Content) -> Post
post = Post()
post.creator = user
post.content = content
posts += post
modifyPost(user: user, post: Post, content: Content)
assert post in posts
assert post.creator == user
post.content = content
deletePost(user: user, post: Post)
assert post in posts
assert post.creator == user
posts -= postcreatePost(user: User, content: Content) -> Post
post = Post()
post.creator = user
post.content = content
posts += post
modifyPost(user: user, post: Post, content: Content)
assert post in posts
assert post.creator == user
post.content = content
deletePost(user: user, post: Post)
assert post in posts
assert post.creator == user
posts -= postComment [User, Post]
Purpose
Enables Users to comment on already existing Posts.
Principle
Users can comment on Posts and share their thoughts with other Users on Community Carpool. These Comments would be public to everyone that can view the Post they are associated with, and unlike Posts, Comments cannot exist without a "parent-Post".
State
comments: Post -> set Comments
content: Comment -> one Content
author: Comment -> one User
reactions: Reaction -> set Reactionscomments: Post -> set Comments
content: Comment -> one Content
author: Comment -> one User
reactions: Reaction -> set ReactionsActions
createComment(user: User, post: Post, content: Content) -> Comment
assert post in posts
comment = Comment()
comment.creator = user
comment.content = content
comment.post = post
post.comments += comment
comments += comment
modifyComment(user: user, comment: comment, content: Content)
assert comment in comments
assert comment.creator == user
comment.content = content
deleteComment(user: user, comment: Comment)
assert comment in comments
assert comment.creator == user or comment.post.creator == user
comment.post.comments -= comment
comments -= commentcreateComment(user: User, post: Post, content: Content) -> Comment
assert post in posts
comment = Comment()
comment.creator = user
comment.content = content
comment.post = post
post.comments += comment
comments += comment
modifyComment(user: user, comment: comment, content: Content)
assert comment in comments
assert comment.creator == user
comment.content = content
deleteComment(user: user, comment: Comment)
assert comment in comments
assert comment.creator == user or comment.post.creator == user
comment.post.comments -= comment
comments -= commentReaction [User, Entity]
Clarification on Entity
Entity is being used as a generalized term for a Concept. In this case, an Entity can be a Post, Comment, or a Message.
Purpose
Enables Users to React to an Entity (another Concept), demonstrating support for/against the Entity publicly.
Principle
Users can React to an Entity, which will appear publicly to all parties that can view the original Entity. This acts as a sort of feedback mechanism for others to gauge Users responses to something.
State
reactionTotals: Entity -> set Reaction -> one integer
reactedUsers: Entity -> set User -> one Reaction
reactions: set ReactionreactionTotals: Entity -> set Reaction -> one integer
reactedUsers: Entity -> set User -> one Reaction
reactions: set ReactionActions
react(user: User, entity: Entity, r: Reaction)
assert r in reactions
assert entity.reactedUsers.users != user
entity.reactionTotals[r] += 1
entity.reactedUsers[user] = r
modifyReaction(user: user, entity: Entity, r: Reaction)
assert r in reactions
assert user in entity.reactedUsers
entity.reactionTotals[entity.reactedUsers[user]] -= 1
entity.reactionTotals[r] += 1
entity.reactedUsers[user] = r
deleteReaction(user: user, entity: Entity)
assert user in entity.reactedUsers
entity.reactionTotals[entity.reactedUsers[user]] -= 1
entity.reactedUsers -= userreact(user: User, entity: Entity, r: Reaction)
assert r in reactions
assert entity.reactedUsers.users != user
entity.reactionTotals[r] += 1
entity.reactedUsers[user] = r
modifyReaction(user: user, entity: Entity, r: Reaction)
assert r in reactions
assert user in entity.reactedUsers
entity.reactionTotals[entity.reactedUsers[user]] -= 1
entity.reactionTotals[r] += 1
entity.reactedUsers[user] = r
deleteReaction(user: user, entity: Entity)
assert user in entity.reactedUsers
entity.reactionTotals[entity.reactedUsers[user]] -= 1
entity.reactedUsers -= userMessage [User]
Purpose
Messages allow Users to directly communicate with each other privately.
Principle
Messages serve as a private form of communication between two (or more) Users who may or may not share a connection through Activities or Carpools. It is a general, private form of communication.
State
messages: set Messagemessages: set MessageActions
sendMessage(sender: User, recipient: User, content: Content)
assert sender in registeredUsers
assert recipient in registered Users
assert sender != recipient
message = Message()
message.content = content
message.time = now()
sender.messages[recipient][sent] += message
recipient.messages[sender][recieved] += messagesendMessage(sender: User, recipient: User, content: Content)
assert sender in registeredUsers
assert recipient in registered Users
assert sender != recipient
message = Message()
message.content = content
message.time = now()
sender.messages[recipient][sent] += message
recipient.messages[sender][recieved] += messageReflection
Overall, implementing the backend of a project whose scope is as complex and detailed as this one made me realize how much thought and planning goes into these kind of RESTful database designs. Time and time again, I would develop a concept, then realize that I omitted a key piece of information or did not efficiently handle a particular edge case. This required me to redo many portions of the assignment throughout the past two weeks. Using Concepts was also tremendously useful, as it allowed me to reuse certain functions and behaviors across multiple different use-cases. Generalizing data objects into these broader concept categories is incredibly efficient and useful. Abstracting logic and the capabilities of the code is essential to minimizing bugs, ensuring a consistent user-experience, and maintaining a level of uniformity/interdependence throughout the project. Given that this was my first time ever working with REST and developing such a backend, I learned a tremendous amount and am very proud of the final result!
Discourse Engagement
Thank you to all of the TAs and Staff (especially @BarishNamazov) who answered my questions on Discourse throughout the past two weeks!
- Using Public APIs (3 posts)
- Handling Spaces in API Calls (3 posts)
- Handling Concept Modularity with Related/Dependent Concepts (18 posts)
- Implementing Synchronizations in API Actions (4 posts)
- Implementing the
GroupConcept (3 posts) - Checking Whether an Object Is In An Array of Objects (3 posts)