Assignment 1: Nodes
Released: September 16th, 6:00pm ET
Due: September 27th 11:59pm ET
Introduction
Having collected all the necessary ingredients by completing the setup assignment, and all the donut know-how in the lab, you are finally ready to make the dough - the most important step of all!
In this assignment, you will be building upon your Lab 1 code to create complete a node file system - a standard way of managing and navigating between Hypertext nodes. At the end, you will have built a full-stack application that will allow users to create, read, update, delete, and move Hypertext nodes via the frontend. You will be graded on the functionality of your frontend and the backend via a test suite.
You will make the node file system using the full-stack technologies that you installed in Assignment 0: MongoDB, Express.js, React.js, and Node.js. This programming assignment contains two parts: backend and frontend. We will start with an overview of the assignment specifications and the general design features of the file system you are creating. Then, we will delve into how to work with each part of the MERN stack to get the whole file system working. Keep in mind the 30-minute rule – if you can’t get something that appears straightforward to work in 30 minutes, it may not be your problem. Don’t be afraid to send a message in Slack if something unexpected comes up.
Lab 1 is an important precursor to this assignment!
This assignment builds directly upon the end result of Lab 1. Therefore it is crucial that you go through Lab 1 in its entirety before starting Assignment 1.
If you have not done so already, accept the GitHub Assignment, used for both Lab 1 and Assignment 1, here.
Checklist
Demo
You can find a demo of the MyHypermedia application here.
Note: It is entirely possible that there will be some unexpected behavior in this application as it is not set up to handle concurrency properly. This means that the application might behave weirdly if multiple users are interacting with the demo at the same time.
Database
In lab we provided you with a URI for a database that the TAs had made for the class to share. But now that you are working on you own Hypertext System, it’s time to create your own database!
Step 1: Creating a MongoDB account
Create/log into your MongoDB account here. If you already have your own account and are familiar with MongoDB, skip steps 2 & 3.
Step 2: Creating a free shared cluster
Select the free shared option and click Create
.
Step 3: Configuring a new cluster
Ensure that the following options are selected:
- Cloud Provider & Region:
AWS, N. Virginia (us-east-1)
- Cluster Tier:
M0 Sandbox (Shared RAM, 512 MB Storage)
- Additional Settings:
MongoDB 4.4, No Backup
- Cluster Name:
cs1951v
(technically, this field can be named whatever you want)
Step 4: Connecting your cluster to our app via URI

Click Connect
, a modal should appear prompting you to configure the firewall and security preferences.
Fill in this modal such that:
- Add a connection IP adress: select
Access from anywhere
and accept the default 0.0.0.0
IP address as your whitelist.
- Create a Database User: create a username and password that you will remember. This username and password is what will be used in your MongoDB URI to connect to this new cluster.
Your modal should now look like this:

Click Choose a connection method

Click Connect your application

Ensure that the modal is configured such that we are using Node.js
and version 4.0 or later
.
Copy the URI starting with mongodb+srv...
. We will need it for later.
Step 5: Creating a new database within your cluster
Go back to your MongoDB dashboard and click Browse Collections
:

Click Add My Own Data
:

Fill in the modal as shown and click Create
:
You should now see your collections dashboard show a new database called cs1951v-database
:

Step 6: Adding the URI to your .env
file
Navigate to the .env
file you made in Lab 1: cd server/.env
. Update the URI with the new URI we just copied from Step 4.
Remember to:
- replace
<password>
in the URI with the password you created in Step 4.
- replace
myFirstDatabase
with cs1951v-database
.
- add single quotes
''
around your new URI
Great! You successfully connected your backend to your own MongoDB cluster!
Step 7: Whitelist your IP in “Network Access”
Navigate to “Network Access” via the left menu:

Then, click “Add IP Address”, and then click “Allow access from anywhere”. You should now see a screen that looks like this:

Step 8: Testing your database connection
TODO:
- Start your server using
cd server
and yarn install && yarn start
- Start your React service using
cd client
and yarn install && yarn start
- Go to http://localhost:3000/ and create a node.
- Check your
cs1951v-database
dashboard (nodes
collection) - you should see a new entry. If you don’t see any new entries in your nodes
collection, please reach out to a TA via Slack or in Hours!
Note, we could sent a POST request at /node/create
via Postman to simulate our frontend actions here.
Awesome! Now that we have verified that our database is properly connected, let’s move onto the backend portion of this assignment.
Backend
NodeGateway.ts
:
In this assignment you will be tasked with writing methods in NodeGateway.ts
to reach full functionality of our node file system.
You will need to implement the following methods:
createNode [Already implemented in lab] - One of the core functionalities that we are expecting you to have is the ability to create nodes. This method should create a node in the database.
getNodeById - We want to retrieve nodes from the database. The getNode function allows users to retrieve a node given the id.
deleteAll - This method should delete all documents in the MongoDB nodes
collection. This method won’t be needed much for production use but rather use for testing.
deleteNode - Now that we can create and retrieve nodes, we want to allow users to delete nodes. This method should allow users to delete a node and its children from the database given a nodeId
.
moveNode - In order to have a fully functioning file system, we must be able to move nodes around. You need to implement a function which takes in two nodeId
s, nodeToMove
’s nodeId
and newParent
’s nodeId
. The function should then verify if the move is valid and move the node to such that nodeToMove
becomes a child of newParent
.
addChild - This method takes in a childId
and parentId
and update’s a parent’s filePath.children
array with a new child nodeId
. This is mainly used as a helper method for other functions.
removeChild - This method takes in a childId
and parentId
and remove’s childId
from the parent’s filePath.children
array. This is mainly used as a helper method for other functions.
Helper Methods:
NodeCollectionConnection.ts
& NodeGateway.ts
The methods in NodeCollectionConnection.ts
and NodeGateway.ts
that we have already implemented for you should help you implement the methods above.
server/src/types
We also recommend looking at server/src/types
as this folder includes important information on how we have set up the schema of INode
, IServiceResponse
, TreeWrapper
etc. These files also include type-checking functions such as isINode()
which will be very helpful in this assignment.
Custom helper methods:
Of course, you can write as many of your own helper functions and are not required to use the ones we provide. As long as you pass our tests, we the TA’s have a pretty liberal stance on what you can and cannot do! Note, that because the next assignment’s stencil code will use the same server/src/types
defined in Assignment 1, it would be wise to not add custom code to server/src/types
just yet.
Frontend
For the frontend portion of this assignment, you will be building a React component (NodeView.tsx
) that renders a node’s data in a user-friendly UI. We will start with just image
and text
nodes, and will add more types of nodes as the course progresses.
This a chance to exercise your design skills and creativity: your NodeView can look however you want it to! However, there are some functional requirements that your NodeView must fulfill.
Use Cmd + Shift + F and search for “TODO” to find all the places you need to edit code! Feel free to make additional changes as well, you can reuse all of this in later assignments!
Requirements for your NodeView:
-
It should clearly display the title
of the node
-
It should clearly display the content
of the node
- I.e. the image for an image node, and the text for a text node
-
It should include a “breadcrumb”
- A breadcrumb is a UI element that shows the user where they currently are in a hierarchical structure, like a website or file system
- For instance:
Coursework > Fall 2021 > CS1951v > Assignment 1
- See
Breadcrumb.tsx
to see which data you will have access to as props
-
It should include a delete button that deletes the node when clicked
- We have provided a stub for
handleDeleteButtonClick
in MainView.tsx
, which we call an event handler since it handles the user clicking on the delete button
- You will then want to pass this event handler to the
onClick
field of a <button />
(We provide a simple <Button />
React component that you should feel free to edit)
- Here’s an example of this pattern:
function HelloWorldButton() {
const handleClick = () => {
console.log('Hello, world!');
}
return (
<button onClick={handleClick}>
Click me to log Hello, world!
</button>
)
}
-
It should include a move button that opens the MoveNodeModal
when clicked, allowing a user to move a node to a different parent node.
- Use the
onMoveButtonClick
prop that is passed in to open the moveNodeModal!
The specification on this document is very broad! The TODOs in the code provide more detail. In general, when implementing a React component, think about how you can go from the input (props
) to the output (what you want to render). Ping in the #react channel if you’re stuck!
Design
In addition the functionality of your NodeView, it is important that it is well designed. This will be true for the rest of the assignments in this course, and any software you build after the course concludes.
What does “well designed” mean? In short, a potential user should feel that the interface is intuitive, clear, and enjoyable to use. For instance, buttons should do what they seem like they do, and important information should be presented prominently.
Essentially, we want to see that you have given significant thought to the usability and styling of your UI. Feel free to check out The Basic Principles of User Interface Design or other online resources, or ping in the #design channel if you have questions!
Check out the globalCssVariables.scss
file, where you can change some of the global colors that are used throughout the system. Feel free to change this as much as you would like to!
Conceptual Questions
These questions are required for graduate and capstone students. For undergraduates who are not capstone you can complete these questions for a maximum of 15 extra credit points (5 per question).
With every project we will also have 2-3 design questions that you must submit your responses to through the handin google form. These questions are supposed to help you make good design decisions and get you to consider how we will be expanding this assignment to build a hypertext application over the course of the semester.
Answer these questions in the repositories README.md
file
-
Suppose that in addition to storing nodes in a file system you want to store nodes on an unbounded 2D-canvas (similar to what you’ve seen in dash demos during class). Explain how this feature would be implemented across each component of the MERN stack. Specifically:
a. Write a MongoDB database schema that could support this. Justify your design.
b. Identify at least one potential npm React library that you could use to avoid building the entire 2D canvas UI component from scratch.
-
Imagine you want to implement an authentication and authorization workflow to protect access to certain nodes. Specifically each node should specify access level for every user and group, with access levels being: read, write, augment (annotate), and admin. Assume for each user session that you have secure access to an accurate user-identifier and an array of group-identifiers that that user belongs to. Explain in 3-5 sentences how you would add support to the Node Gateway backend so that it returns the node only if the current user has proper access to the requested node.
-
Finally, imagine you want to persist user trails. Specifically, you want to track the path that a user takes through the hypertext corpus. In this case, since each node has a unique url, each path can be represented as an array (of linked list) of urls. Explain in 3-5 sentences how you might add support for storing and then effectively accessing old trails. In your response, you may choose to focus on the frontend (around how you would make trails into a compelling user experience) or on the backend (around how you would make this data persistent as well as how you would query it).
Handin
You’ll be submitting all your assignments for CSCI1951V through Gradescope, and you’ll receive all your grades and feedback through Gradescope too. To ensure anonymous grading, you’ll need to create a NEW email address specifically for Gradescope.
TODO: Set up an anonymous grading for the rest of the course by filling out this Google form.
Note that doing this is MANDATORY. Instructions for this process are contained below. If you run into any trouble while doing this, please email the HTAs at cs1951vheadtas@lists.brown.edu!
Once you have successfully created a Gradescope account and enrolled in CS1951V, you should submit your project to the Nodes | Assignment 1
assigment in Gradescope by linking your GitHub repository as follow:
Grading Breakdown
Backend
Task |
Grade |
Implement src/gateway/NodeGateway.ts |
45 Pts - all tests pass |
Code is well formatted |
5 Pts - ESLint does not complain |
Total = 50 Pts
Frontend
Task |
Grade |
Clearly display the title and content of the node |
10 Pts |
Includes a breadcrumb |
10 Pts |
Includes a delete button that deletes the node |
10 Pts |
Includes a move button that opens the moveNodeModal |
10 Pts |
Design: usability and style |
10 Pts |
Total = 50 Pts
Design Questions
Task |
Grade |
Design Questions |
15 Pts |
Total = 15 Pts
⬅️ Return to course website
Assignment 1: Nodes
Released: September 16th, 6:00pm ET
Due: September 27th 11:59pm ET
Introduction
Having collected all the necessary ingredients by completing the setup assignment, and all the donut know-how in the lab, you are finally ready to make the dough - the most important step of all!
In this assignment, you will be building upon your Lab 1 code to create complete a node file system - a standard way of managing and navigating between Hypertext nodes. At the end, you will have built a full-stack application that will allow users to create, read, update, delete, and move Hypertext nodes via the frontend. You will be graded on the functionality of your frontend and the backend via a test suite.
You will make the node file system using the full-stack technologies that you installed in Assignment 0: MongoDB, Express.js, React.js, and Node.js. This programming assignment contains two parts: backend and frontend. We will start with an overview of the assignment specifications and the general design features of the file system you are creating. Then, we will delve into how to work with each part of the MERN stack to get the whole file system working. Keep in mind the 30-minute rule – if you can’t get something that appears straightforward to work in 30 minutes, it may not be your problem. Don’t be afraid to send a message in Slack if something unexpected comes up.
Lab 1 is an important precursor to this assignment!
This assignment builds directly upon the end result of Lab 1. Therefore it is crucial that you go through Lab 1 in its entirety before starting Assignment 1.
If you have not done so already, accept the GitHub Assignment, used for both Lab 1 and Assignment 1, here.
Checklist
Lab 1
]Demo
You can find a demo of the MyHypermedia application here.
Note: It is entirely possible that there will be some unexpected behavior in this application as it is not set up to handle concurrency properly. This means that the application might behave weirdly if multiple users are interacting with the demo at the same time.
Database
In lab we provided you with a URI for a database that the TAs had made for the class to share. But now that you are working on you own Hypertext System, it’s time to create your own database!
Step 1: Creating a MongoDB account
Create/log into your MongoDB account here. If you already have your own account and are familiar with MongoDB, skip steps 2 & 3.
Step 2: Creating a free shared cluster
Select the free shared option and click
Create
.Step 3: Configuring a new cluster
Ensure that the following options are selected:
AWS, N. Virginia (us-east-1)
M0 Sandbox (Shared RAM, 512 MB Storage)
MongoDB 4.4, No Backup
cs1951v
(technically, this field can be named whatever you want)Step 4: Connecting your cluster to our app via URI
Click
Connect
, a modal should appear prompting you to configure the firewall and security preferences.Fill in this modal such that:
Access from anywhere
and accept the default0.0.0.0
IP address as your whitelist.Your modal should now look like this:

Click

Choose a connection method
Click

Connect your application
Ensure that the modal is configured such that we are using
Node.js
and version4.0 or later
.Copy the URI starting with
mongodb+srv...
. We will need it for later.Step 5: Creating a new database within your cluster
Go back to your MongoDB dashboard and click

Browse Collections
:Click

Add My Own Data
:Fill in the modal as shown and click
Create
:You should now see your collections dashboard show a new database called

cs1951v-database
:Step 6: Adding the URI to your
.env
fileNavigate to the
.env
file you made in Lab 1:cd server/.env
. Update the URI with the new URI we just copied from Step 4.Remember to:
<password>
in the URI with the password you created in Step 4.myFirstDatabase
withcs1951v-database
.''
around your new URIGreat! You successfully connected your backend to your own MongoDB cluster!
Step 7: Whitelist your IP in “Network Access”
Navigate to “Network Access” via the left menu:

Then, click “Add IP Address”, and then click “Allow access from anywhere”. You should now see a screen that looks like this:
Step 8: Testing your database connection
TODO:
cd server
andyarn install && yarn start
cd client
andyarn install && yarn start
cs1951v-database
dashboard (nodes
collection) - you should see a new entry. If you don’t see any new entries in yournodes
collection, please reach out to a TA via Slack or in Hours!Note, we could sent a POST request at
/node/create
via Postman to simulate our frontend actions here.Awesome! Now that we have verified that our database is properly connected, let’s move onto the backend portion of this assignment.
Backend
NodeGateway.ts
:In this assignment you will be tasked with writing methods in
NodeGateway.ts
to reach full functionality of our node file system.You will need to implement the following methods:
createNode [Already implemented in lab] - One of the core functionalities that we are expecting you to have is the ability to create nodes. This method should create a node in the database.
getNodeById - We want to retrieve nodes from the database. The getNode function allows users to retrieve a node given the id.
deleteAll - This method should delete all documents in the MongoDB
nodes
collection. This method won’t be needed much for production use but rather use for testing.deleteNode - Now that we can create and retrieve nodes, we want to allow users to delete nodes. This method should allow users to delete a node and its children from the database given a
nodeId
.moveNode - In order to have a fully functioning file system, we must be able to move nodes around. You need to implement a function which takes in two
nodeId
s,nodeToMove
’snodeId
andnewParent
’snodeId
. The function should then verify if the move is valid and move the node to such thatnodeToMove
becomes a child ofnewParent
.addChild - This method takes in a
childId
andparentId
and update’s a parent’sfilePath.children
array with a new childnodeId
. This is mainly used as a helper method for other functions.removeChild - This method takes in a
childId
andparentId
and remove’schildId
from the parent’sfilePath.children
array. This is mainly used as a helper method for other functions.Helper Methods:
NodeCollectionConnection.ts
&NodeGateway.ts
The methods in
NodeCollectionConnection.ts
andNodeGateway.ts
that we have already implemented for you should help you implement the methods above.server/src/types
We also recommend looking at
server/src/types
as this folder includes important information on how we have set up the schema ofINode
,IServiceResponse
,TreeWrapper
etc. These files also include type-checking functions such asisINode()
which will be very helpful in this assignment.Custom helper methods:
Of course, you can write as many of your own helper functions and are not required to use the ones we provide. As long as you pass our tests, we the TA’s have a pretty liberal stance on what you can and cannot do! Note, that because the next assignment’s stencil code will use the same
server/src/types
defined in Assignment 1, it would be wise to not add custom code toserver/src/types
just yet.Frontend
For the frontend portion of this assignment, you will be building a React component (
NodeView.tsx
) that renders a node’s data in a user-friendly UI. We will start with justimage
andtext
nodes, and will add more types of nodes as the course progresses.This a chance to exercise your design skills and creativity: your NodeView can look however you want it to! However, there are some functional requirements that your NodeView must fulfill.
Use Cmd + Shift + F and search for “TODO” to find all the places you need to edit code! Feel free to make additional changes as well, you can reuse all of this in later assignments!
Requirements for your NodeView:
It should clearly display the
title
of the nodeIt should clearly display the
content
of the nodeIt should include a “breadcrumb”
Coursework > Fall 2021 > CS1951v > Assignment 1
Breadcrumb.tsx
to see which data you will have access to asprops
It should include a delete button that deletes the node when clicked
handleDeleteButtonClick
inMainView.tsx
, which we call an event handler since it handles the user clicking on the delete buttononClick
field of a<button />
(We provide a simple<Button />
React component that you should feel free to edit)/** * This React component renders a button that logs "Hello, world!" * to the console when clicked */ function HelloWorldButton() { const handleClick = () => { console.log('Hello, world!'); } return ( <button onClick={handleClick}> Click me to log Hello, world! </button> ) }
It should include a move button that opens the
MoveNodeModal
when clicked, allowing a user to move a node to a different parent node.onMoveButtonClick
prop that is passed in to open the moveNodeModal!The specification on this document is very broad! The TODOs in the code provide more detail. In general, when implementing a React component, think about how you can go from the input (
props
) to the output (what you want to render). Ping in the #react channel if you’re stuck!Design
In addition the functionality of your NodeView, it is important that it is well designed. This will be true for the rest of the assignments in this course, and any software you build after the course concludes.
What does “well designed” mean? In short, a potential user should feel that the interface is intuitive, clear, and enjoyable to use. For instance, buttons should do what they seem like they do, and important information should be presented prominently.
Essentially, we want to see that you have given significant thought to the usability and styling of your UI. Feel free to check out The Basic Principles of User Interface Design or other online resources, or ping in the #design channel if you have questions!
Check out the
globalCssVariables.scss
file, where you can change some of the global colors that are used throughout the system. Feel free to change this as much as you would like to!Conceptual Questions
These questions are required for graduate and capstone students. For undergraduates who are not capstone you can complete these questions for a maximum of 15 extra credit points (5 per question).
With every project we will also have 2-3 design questions that you must submit your responses to through the handin google form. These questions are supposed to help you make good design decisions and get you to consider how we will be expanding this assignment to build a hypertext application over the course of the semester.
Answer these questions in the repositories
README.md
fileSuppose that in addition to storing nodes in a file system you want to store nodes on an unbounded 2D-canvas (similar to what you’ve seen in dash demos during class). Explain how this feature would be implemented across each component of the MERN stack. Specifically:
a. Write a MongoDB database schema that could support this. Justify your design.
b. Identify at least one potential npm React library that you could use to avoid building the entire 2D canvas UI component from scratch.
Imagine you want to implement an authentication and authorization workflow to protect access to certain nodes. Specifically each node should specify access level for every user and group, with access levels being: read, write, augment (annotate), and admin. Assume for each user session that you have secure access to an accurate user-identifier and an array of group-identifiers that that user belongs to. Explain in 3-5 sentences how you would add support to the Node Gateway backend so that it returns the node only if the current user has proper access to the requested node.
Finally, imagine you want to persist user trails. Specifically, you want to track the path that a user takes through the hypertext corpus. In this case, since each node has a unique url, each path can be represented as an array (of linked list) of urls. Explain in 3-5 sentences how you might add support for storing and then effectively accessing old trails. In your response, you may choose to focus on the frontend (around how you would make trails into a compelling user experience) or on the backend (around how you would make this data persistent as well as how you would query it).
Handin
You’ll be submitting all your assignments for CSCI1951V through Gradescope, and you’ll receive all your grades and feedback through Gradescope too. To ensure anonymous grading, you’ll need to create a NEW email address specifically for Gradescope.
TODO: Set up an anonymous grading for the rest of the course by filling out this Google form.
Note that doing this is MANDATORY. Instructions for this process are contained below. If you run into any trouble while doing this, please email the HTAs at cs1951vheadtas@lists.brown.edu!
Once you have successfully created a Gradescope account and enrolled in CS1951V, you should submit your project to the
Nodes | Assignment 1
assigment in Gradescope by linking your GitHub repository as follow:Grading Breakdown
Backend
Total = 50 Pts
Frontend
title
andcontent
of the nodeTotal = 50 Pts
Design Questions
Total = 15 Pts