Released: September 13th, 2023
Due: September 27th, 2023 at 11:59 PM ET
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 a complete 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 via manual review and your backend via an automatic 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 three parts: the database, the backend, and the 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 or go to TA hours if something unexpected comes up.
Lab 1 is an important precursor to this assignment!
This assignment builds directly on the work in Lab 1. It's crucial that you go through Lab 1 in its entirety before starting Assignment 1!
Note: Assignment 1 uses the same codebase as Lab 1
Database:
Backend (BackendNodeGateway):
Lab 1
]Frontend (NodeView):
Lab 1
]Lab 1
]Deployment:
Note: The demo may take up to 30 seconds to load due to the free backend we used for hosting. Additionally, you might notice some strange behavior if there are multiple students interacting with the demo at the same time.
You can find a demo of the MyHypermedia application here.
You'll be working with several languages and libraries in this assignment. Here are some syntax guides to serve as a reference:
In the first 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!
Create/log into your MongoDB account here.
Create a new organization and project if necessary, then proceed to create a new database deployment.
Select the M0 free shared option.
Ensure that the following options are selected:
AWS, N. Virginia (us-east-1)
cs1951v
(technically, this field can be named whatever you want)Click Create
.
After clicking Create
, you should see a page like this:
For the section: How would you like to authenticate your connection?:
Username and Password
.Create User
.Scroll down to the next section which should look like this:
For the section: Where would you like to connect from?
My Local Environment
and enter in 0.0.0.0
IP address as your whitelist.Add Entry
.Now Click Finish and Close
.
You should now be redirected to the overview page of your new database deployment!
Connect
button beside the cluster name.Connect to your application
choose the Drivers
option..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 5.
Remember to:
<password>
in the URI with the password you created in Step 4.cs1951v-database
.""
around your new URIThis is an example of what the line should look like in your .env
:
Great! You successfully connected your backend to your own MongoDB cluster!
TODO:
cd server
and npm install
(or npm i
) and npm run dev
cd client
and npm install
(or npm i
) and npm run dev
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 the TAs via Slack or in Hours!Note: We could send 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.
BackendNodeGateway.ts
:In this assignment you will be tasked with writing methods in BackendNodeGateway.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 findNodeById
function allows users to retrieve a node given the ID.
getNodesById - We want to retrieve all nodes from the database that have an ID that is in the input list of ID's.
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 particular 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 in a way 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.
NodeCollectionConnection.ts
& BackendNodeGateway.ts
The methods in NodeCollectionConnection.ts
and BackendNodeGateway.ts
that we have already implemented for you should help you implement the methods above. For more practice with MongoDB queries, you can also use Mongo playground.
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
, etc. These files also include type-checking functions such as isINode()
which will be very helpful for error-checking in this assignment.
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 have a pretty liberal stance on what you can and cannot do!
Note: Because 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.
To test that your backend functions work as intended, you can run the test suite by running npm test
(or npm run test
) from the server
folder.
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.
Your create node modal functionality should be working from the lab. One thing to note is that when creating an image node, the "Choose file" browse option will not work until after you deploy your site (Imgur doesn't work on localhost). Once you deploy, Imgur uploading should work automatically. In the meantime, you should paste an image url into the textbox.
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! Or, use the "Todo Tree" extension's panel in VSCode to see a tree view of all the TODOs.
It should clearly display the title
of the node
It should clearly display the content
of the node
It should include a "breadcrumb"
Coursework > Fall 2021 > CS1951v > Assignment 1
NodeBreadcrumb.tsx
to see which data you will have access to as props
Note: Clicking on a part of the breadcrumb does NOT need to take the user to that node like in the demo.
It should include a delete button that deletes the node when clicked
onDeleteButtonClick
in MainView.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) 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).
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 #assignments 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!
We highly recommend having your webpage running in your browser as you're working on the frontend, and incrementally checking that each feature you add appears and works as intended. Below we have some debugging options you may consider using.
Print Statements
console.log('Insert message')
is a Javascript function that prints a message to the web console. To open the web console, double click/right click on the webpage, click "Inspect Element", and go to the console tab.
VSCode Debugger (Frontend)
You can debug with breakpoints directly in VSCode!
Debuggers for Chrome and Edge are built in, and you can find an extension in the store for Firefox.
Select the Run and Debug
tab on the left side of the editor. The first time you setup debugging for your repository, you will need to create a launch.json file
. On the dropdown list that opens, select Web App (Chrome)
or whichever other browser you prefer to debug with.
To start debugging, go to the "Run and Debug" sidebar (Shortcut: Ctrl + Shift + D
) and click the play button beside Launch chrome against localhost
.
This will open localhost:3000
in Chrome, where you have access to all of the Chrome debugging tools as well.
Now, the useful part of using the VSCode debugger, adding breakpoints
to your code! Let us say that we are in ImageContent.tsx
and we are having issues accessing the anchors that we should render on our node. We want to know what startAnchor
is and what anchor
is in the following snippet of code for displayImageAnchors
.
Spot the 🔴 next to line 106
. What that means is that we have set a breakpoint at that line in our code. You can add new breakpoints by click next to the line number. Now when we run our code in the debugger and go to an image, your web app will freeze at that point.
You can see that it has frozen at line 108
. The menu at the top of the following screenshot (next to the ImageContent.tsx
tab) can be used to Continue
, Step to next line
, Stop
, Restart
, etc. When we are frozen at a breakpoint we can open the Debug Terminal
and get really valuable insights as to what the variables are.
VSCode Debugger (Backend)
You can also debug backend Node.js applications in VSCode. To do this, you will create a "JavaScript Debug Terminal", and you will run your backend from this debug terminal instead of your traditional terminal.
There are two methods for launching a JavaScript Debug Terminal:
+
icon to add a new terminal. In the dropdown, select "JavaScript Debug Terminal".Control + Shfit + P
(or Command + Shift + P
) to open the command palette, and select "Debug: JavaScript Debug Terminal".Then you can run npm run dev
from this debug terminal, and you will be able to add breakpoints to your backend code in the same way as shown above.
Once you have finished implementing all the steps of this assignment, follow the instructions linked here to deploy your project!
These questions are required for students taking the course as graduate-level or capstone. For non-capstone 1000-level students, you can complete these questions for a maximum of 15 extra credit points (5 per question).
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, 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 BackendNodeGateway 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).
Please ensure that all the sections in the README.md
are filled out.
You'll be submitting all your assignments for CSCI1951V through Gradescope, and you'll receive all your grades and feedback through Gradescope too. Once you have successfully created a Gradescope account using your Brown email address you can enroll in our Gradescope course by clicking the "Gradescope" tab on Canvas. You should submit your project to the Assignment 1: Nodes
assignment in Gradescope by linking your GitHub repository as follows:
For students taking this course as a capstone or graduate level course, the assignment is out of 125 points. For students not taking this course as a capstone or graduate level course, the assignment is out of 110 points.
Task | Grade |
---|---|
No ESLint or Prettier warnings | 5 Pts |
Run npm run lint
on the server/
and client/
directories to run the linter locally and fix any issues before you submit!
Task | Grade |
---|---|
Implement src/nodes/BackendNodeGateway.ts | 45 Pts |
Run npm test
on the server/
directroy to run the test suite locally and fix any issues before you submit!
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 |
Task | Grade |
---|---|
Backend deployed successfully | 5 Pts |
Frontend deployed successfully | 5 Pts |
Task | Grade |
---|---|
Question 1 | 5 Pts |
Question 2 | 5 Pts |
Question 3 | 5 Pts |