Able to specify a software feature using well-structured user stories following the Role, Goal, Benefit framework.
Able to define concrete definitions of done following the Given/When/Then framework.
Can implement a web server with endpoints following a REST API specification.
Able to write tests that sends HTTP requests using test framework like supertest.
Can convert the set of scenarios in a DoD into a frontend feature.
2023/03/20: Added Phase 2 specification
Up to now, and maybe without realizing it, you have been developing the server side (backend) of a web application. In this checkpoint, you will give your project a frontend (AKA - a client side implementation)! A frontend allows an end user to access your project through a user interface (UI). The previous two checkpoints (C1 and C2) built the backend of your application and although your tests can access your methods, it would be difficult for a non-technical user to make use of them. In C3, you will complete your application by building a frontend to allow easy access to your backend methods (addDataset, removeDataset, listDataset, and performQuery).
This checkpoint has two phases:
Phase 1 involves designing and writing down the user stories for your frontend, while
Phase 2 involves implementing the user stories specified in Phase 1.
Your frontend will use REST API calls to communicate with your backend, so Phase 2 includes the task of implementing a REST API server.
Note: Phase 1 and 2 have different deadlines. The details for Phase 2 will be released after the Checkpoint 2 deadline.
Frontend user story 1 + DoDs (5%)
Frontend user story 2 + DoDs (5%)
You will receive a 0, 0.5 or 1 for each user story. 0 = no effort, 0.5 = missing key element, 1 = wahoo!
We will not be accepting LATE submissions. You will not get feedback from your TA or a grade if you submit late.
In order to receive full grade on C3 Phase 1:
You must specify your choice of frontend.
You must write a minimum of two user stories.
Each of your user story must be accompanied by at least two definition of dones: one describing a successful case and one failure case.
All the above must be submitted according to the submission guideline before deadline.
There will be a PR made against your repository by 310-bot, containing a GitHub issue template file which you are required to use for Phase 1.
Merge the PR.
Go to "Issues" tab and click "New Issue". You should see a template called "User Stories" in the list of available templates.
Create an issue using the "User Stories" template.
Make sure your user stories are complete before the C3P1 deadline.
You can choose any frontend for your project! Have some fun, go a little wild!
We will be providing starter code for a basic Web frontend and a Discord frontend. If you select the Web as your frontend and choose to use our bootstrap, you will build a website using HTML, CSS and plain JavaScript which will send REST API calls to your server. If you select Discord as your frontend, your end user will be able to interact with your server via Discord! They will be able to send messages, which will be listened for by your Discord bot and then forwarded to your server.
You can install additional node packages as needed by your frontend of choice.
You can use ANY language and framework for your frontend.
Disclaimer! TAs are most likely only familiar with the Web frontend, as that has been used in previous semesters. The TAs will not be able to provide the same level of support for alternate frontends.
You should select your frontend before writing your frontend user stories, as it will provide more concrete context for how your end-user will interact with your application.
In Phase 1, you will write a minimum of two user stories that outline how your end-user can use your frontend application to achieve desired outcomes. Then, in Phase 2 you will design and implement the code to realize your user stories.
A user story should describe the type of user, what the user wants to do with your application, and for what benefit.
You are required to provide a minimum of two user stories. Though you're free to write and implement more than two user stories, you will be graded based on just the two of them.
A user story should, in general, be agnostic to your frontend choice. It should encode "what" the user can do with your application, not "how". The "how" belongs in the Definitions of Done (more about this in the next section below). Simply put, if you find yourself describing your UI in a user story, beware!
Use the Role, Goal, Benefit framework to define your stories:
As a [role], I want to [goal], so that [benefit].
[role]: Who is using this?
[goal]: What is the user trying to achieve?
[benefit]: Why does the user want to achieve this?
Included in each user story are the definitions of dones (DoD) that define the conditions your application must meet before it is accepted by the user in the user story. In other words, DoDs are the agreement between you and your end-user about when an application feature is considered “done”. For each user story, the DoDs should describe "how" your application supports the user in achieving the said goal.
For each user story, provide at least two DoDs. Please think of both the success and failure cases.
Use the Given/When/Then framework to define your DoDs:
Scenario: [Description for the behaviour that will be described]
Given: [Some initial application state (precondition)]
When: [The user do some series of action]
Then: [Some outcome state is expected (post-condition)]
As an online bank user, I want to be able to log into my account, so that I can access my banking information online.
Scenario 1: Correct credential
Given: The user is on the login page
When: The user enters a valid card number and password pair, and clicks “Log in”
Then: The application logs the user in, and presents the dashboard page
Scenario 2: Incorrect credential
Given: The user is on the login page
When: The user enters an incorrect card number and password pair, and clicks “Log in”
Then: The application remains on the login page, and shows an error in red telling the user to try again
There is no best way to get started, but a few hints may help you:
For selecting a frontend - what frontends are both yourself and your partner familiar with? If choosing a frontend other than the Web, it may be worthwhile to run through a small proof of concept to ensure that you can successfully complete C3.
Create the big picture of your project in your mind. Use pencil and paper and draw some diagrams. Where is each component and how do they interact with each other? What's on the frontend and what's on the backend?
In this phase, you will implement your web server and frontend. Since the web server is evaluated by AutoTest, we are explicit with how it should behave. However, for your frontend, you will implement what you described in your user stories.
Phase 2 involves:
The implementation of the REST server, which allows a frontend to request data from your backend via HTTP requests. This server will be graded by AutoTest.
The implementation of your frontend. For grading, you will submit a video demonstrating the behaviour of your user stories.
Similar to the previous checkpoints, C3 Phase 2 has a portion graded by the AutoTest and we will provide smoke tests. AutoTest will grade the implementation of your web server.
Frontend user story one (15%)
Frontend user story two (15%)
For the demo of each user story, you will receive a 0, 0.5, or 1. 0 = no effort, 0.5 = some DoDs not met, or a major bug, 1 = wonderful! However if you miss one of the requirements for the demo video (as listed in the Requirements section) your grade will be capped at 50%.
Note: We are not marking on the aesthetics of your frontend (rounded corners, pretty colours). The marks will be awarded for satisfying each of your DoD.
To receive full marks, your demo video must:
Be uploaded online, and be accessible via a link (URL). The link must be present in /frontend/README.md file of your project.
Be a continuous screen recording of each of your user stories' DoD scenarios (no editing!). We are not expecting a polished work of art, for example, you may need to restart your server during your demo and that is ok!
Include audio explaining what you are doing. You can easily add a microphone to the default screen recording provided by both Windows and Mac.
For each user story, you will walk through each Definition of Done. For each DoD scenario:
(i) Demonstrate the Given. For example, if your story requires an added dataset, show the dataset in your data folder on your server.
(ii) Demonstrate the When. For example, if the user must enter in values into a text box or press a button, show it!
(iii) Show the Network Request upon the user doing the action. To do so, open the developer tools in your browser and navigating to the "Network" tab. When performing the action, a network request will go to your server. Alternatively, if your frontend does not use a browser, you could show logs from the server of the request in your terminal.
(iv) Demonstrate the Then. For example, the list of data in your table or the error after entering incorrect input.
Be under 10 minutes. We expect most demos to be between 2-6 minutes.
Like C1 and C2, AutoTest will automatically grade your project each time you merge to the main branch. Your grade will be the maximum grade you've received from all submissions (merges in git terminology) made before the hard deadline.
To request the associated smoke test feedback, you can comment with @310-bot #c3 on the merge commit of interest of the main branch.
For the Demo, you will submit a video which demonstrates your two user stories. This video should be uploaded online. You are responsible for choosing a location that the TAs can access while grading. The popular solution would be a private YouTube link, but the choice is yours. The video link must be specified in the /frontend/README.md file. There are details on what must be contained in the video in the Requirements section of this document.
A Web server surfaces your InsightFacade methods such that a frontend can access those methods via HTTP requests. Your Web server will need to provide the following REST endpoints exactly as they are specified, because your C3 client (aka. AutoTest) will leverage on these endpoints to access your InsightFacade methods.
Below is a list of the REST endpoints your Web server must support.
PUT /dataset/:id/:kind allows one to submit a zip file that will be parsed and used for future queries. The zip file content will be sent 'raw' as a buffer in the PUT's body, and you will need to convert it to base64 server side.
Response Codes:
200: When InsightFacade.addDataset() resolves.
400: When InsightFacade.addDataset() rejects.
Response Body:
{result: arr}: Where arr is the array returned by a resolved addDataset.
{error: err}: Where err is a string error message from a rejected addDataset. The specific string is not tested.
DELETE /dataset/:id deletes the existing dataset stored. This will delete both disk and memory caches for the dataset for the id, meaning that subsequent queries for that id should fail unless a new PUT happens first.
Response Codes:
200: When InsightFacade.removeDataset() resolves.
400: When InsightFacade.removeDataset() rejects with InsightError.
404: When InsightFacade.removeDataset() rejects with NotFoundError.
Response Body:
{result: str}: Where str is the string returned by a resolved removeDataset.
{error: err}: Where err is a string error message from a rejected removeDataset. The specific string is not tested.
POST /query sends the query to the application. The query will be in JSON format in the POST's body.
NOTE: the server may be shutdown between the PUT and the POST. This endpoint should always check for a persisted data structure on disk before returning a missing dataset error.
Response Codes:
200: When InsightFacade.performQuery() resolves.
400: When InsightFacade.performQuery() rejects.
Response Body:
{result: arr}: Where arr is the array returned by a resolved performQuery.
{error: err}: Where err is a string error message from a rejected performQuery. The specific string is not tested.
GET /datasets returns a list of datasets that were added.
Response Codes:
200: When InsightFacade.listDatasets() resolves.
Response Body:
{result: arr}: Where arr is the array returned by a resolved listDataset
The :id and :kind portions above represent variable names that are extracted from the endpoint URL. For example, in the PUT URL http://localhost:4321/dataset/mysections/sections, mysections would be the id and sections would be the kind.
Note: Those of you paying attention in lecture may notice that this is not a very RESTful API. As an exercise, consider how you could modify one of the endpoints to make a more RESTful API! (But please don't actually modify, as AutoTest depends on this exact specification)
We will provide starter code for the Web Server as a pull request against your main branch. Once you merge this pull request from 310-bot, you'll have three new files in your project associated with the implementation of a Web server:
src/App.ts contains the source code for starting the application and initializing the server. This will be given to you for free.
src/rest/Server.ts contains the logic for your server.
test/rest/Server.spec.ts contains the tests for your server. You'll want to write your own Server tests here!
Both the Server.ts and Server.spec.ts files will contain some sample code to point you in the right direction. We will use express as our REST server library. Please refer to its documentation first whenever questions arise.
On the left, we have the general structure of your repository in C3P2, and the roles of each.
A new yarn command yarn start will be available in your project through a change to package.json (included in Web Server bootstrap PR). It will essentially run App.js as a node application. Once you have started the server, you'll be able to access the app in the browser at http://localhost:4321.
Your local tests for the endpoints you implement in Server.ts should exist in Server.spec.ts file. The same libraries and frameworks as before (Mocha, Chai) will be used for testing, with the addition of supertest. SuperTest is used to send HTTP requests to your backend endpoints within a test case. Your tests will have to send requests to your backend and check the received responses for validity. You'll want to use the debugger to inspect the received responses to determine the exact format of response and where to find the values you want to assert against.
You will implement the two user stories you have written and received feedback for in Phase 1. Please make sure to review and closely follow the corresponding DoDs for each story, as you will be expected to demo the workflows in the DoDs during your final demo video.
Important: You can add new dependencies (ie. run yarn add <new packages>) for your frontend, but these dependencies must be contained within the /frontend directory. (You'll likely have a second package.json in your frontend directory)
We will provide bootstrap code for a Web Frontend and for a Discord Frontend, both are optional to use.
There will be an optional pull request from 310-bot for the web frontend. We’ve provided a simple implementation that contains a button that when clicked that shows an alert.
You will also need to uncomment the following line in your Server.ts file:
this.express.use(express.static("./frontend/public"))
This line is what serves your frontend UI sources to the root of your application.
The subdirectory /public contains the static sources that will be hosted by your Web app:
index.html contains the starter HTML code for the UI. This file is hosted by the GET / endpoint of your REST server. This will already be implemented in the bootstrap.
style.css contains the CSS styling of the UI.
frontend.js contains the logic to listen to the button click event and show an alert.
There are two new aspects to the Web frontend that you haven't seen in early checkpoints:
Plain JavaScript. While it is theoretically possible to develop in TypeScript on the frontend as well, using plain JavaScript has the advantage that you won't have to build/compile your project when you work on the frontend.
Browser. You will dive into the world of browsers with your frontend implementation. Your frontend code will be run in the browser and will communicate with your Web server via REST/Ajax calls. This means also that you will have the global window, document and XMLHttpRequest objects from the browser available anywhere in your code.
Braxton, a former TA of 310, created a great repository called bot-starter for this course, so students could use it as a starter for their discord bots. This term we updated node, which requires bot-starter (and bot-base a dependency of bot-starter), to also have an updated node version.
If you'd like to use bot-starter, there are two options:
(Recommended) Use a new repo we created (bot-starter (2022W2)), based off of the original bot-starter which updates the node version.
(Not recommended) Install a node version manager, like nvm, to change node versions depending on if you are working on the frontend or backend.
It may also be useful to view the discord.js package: https://www.npmjs.com/package/discord.js.
You may require already loaded datasets for your UI to work. There are a couple of ways of ensuring this. You could of course implement the ability for an end user to add a dataset from the frontend UI, but this is sometimes complex (and may not be one of your user stories). You could find a way to call addDataset by hitting one of your REST endpoints from a client, or keep a cached copy of your data around and just paste it into your ./data folder so the server can load it from disk.
WARNING: Keeping a cached copy of some dataset in ./data folder can interfere with AutoTest. We recommend only doing this only for the purpose of the demo, and to remove the cached dataset once you've finished recording the demo.
There is no best way to get started, but a few hints may help you:
The two parts in this checkpoint (server, frontend) should be implemented and tested independent from each other. They are only hooked together with HTTP requests going from the frontend to the server but all parts are designed to be implemented and tested independently.
Read the examples in "Basic routing with express" to see how to build a REST server.
There are many third-party REST clients (applications to send and receive REST requests) out there, and you may find them useful for quick manual testing on your Web server. But keep in mind that they should NOT replace your own Server.spec.ts tests however. Especially so because AutoTest will use the exact setup as in Server.spec.ts (ie. using mocha, chai and supertest) to test your endpoints. It is important to confirm your endpoints behave correctly using these test frameworks.
Postman is a client for sending requests to the Web server. It could be useful to use this tool to test how your backend endpoints are behaving for different inputs. You can download Postman as a desktop application, or use the web version in the browser.
Note: If you are using the web version of Postman, you'll need to download a Postman Agent to overcome CORS.
Postman lets you configure a request with various inputs, including zipped folders. For example, if you're submitting a PUT request with pair.zip, upload the zip like so:
react-create-app provides a script to create a React project. There is an option to create a TypeScript project.
There are lots of component libraries to make your website look pretty, checkout Bootstrap, Ant Design and Material.