We receive a vast amount of information about the COVID-19 daily. This information overload makes it difficult to find reliable and relevant information, especially for seniors and other vulnerable groups in our community who are not well versed with querying the search engine and fact checking. The goal of this project is to create a question and answer web application for reliable dissemination of information and knowledge [related to the pandemic] among members of the community.
Name | GitHub Username |
---|---|
Behrad Ghadiri Bashardoost | burtonrider |
Tongzhou Li | greysky10 |
Zhifei Song | soso-song |
Nicole Xin Yue Wang | niconicolii |
There are two ways to use this web application:
-
Visit our website by going to https://csc309-loqal-team11.herokuapp.com/
-
These instructions will help you get a copy of our completed assignment up and running on your local machine.
- Clone this repository on your local machine
git clone https://github.com/csc309-summer-2020/team11.git
- Navigate to the cloned folder
cd team11
- Run MongoDB
npm install mkdir mongo-data mongod --dbpath ./mongo-data
- Open a new terminal window to start server
cd team11 node server.js
- Visit
localhost:5000/
in your browser
Below we have listed the main functionalities associated with each page for regular users. In addition to these functionalities, Admin users have access to additional functionalities through Admin Dashboard which are described further down below in the Admin Users section.
This page serves as a welcome page. To get started, scroll down to the bottom of the page and click on the Get Started button.
-
Register by entering all required fields in the left side bar and press the "Register" button to create a new account.
-
Validation is performed to check if the input information are valid
-
Furthermore, backend validation is performed to make sure username and email are unique
-
If successfully registered, it will lead you to a page showing some popular tags that you can subscribe to.
-
Alternatively, use one of the login credentials provided below to log in.
Email Password Type of Account user@user.com user Regular User user2@user2.com user2 Regular User admin@admin.com admin Admin User -
By logging in, you will be lead to your user dashboard
🌟 New features:
- Backend validation for verifying unique username and email
- Password is encrypted using bcrypt for security reasons
-
Subscribing to a tag will allow questions related to this tag to be shown on your webpage.
-
Most popular tags and the tags you are currently following are shown
- Most popular tags are the tags most followed by other users or most mentioned in questions (:star2: New Feature)
-
Follow/unfollow a tag by clicking on them
-
Type in any tag name to subscribe, a non-existing tag name will be created as a new tag.
🌟 New Feature: Validation is performed to avoid following/unfollowing the same tag more than once
-
All tags are stored in lowercase, and spaces in any tag will be replaced by dashes(-).
-
Clicking on the "Continue" button will lead you to your user dashboard. If you are editing your tags from profile edit, you will be redirected back to that page.
-
Users user will be able to see the newest questions, under the three tabs (:star2: New Feature):
- Everyone: newest question from everyone
- 🌟 New Feature: Pagination: the number of questions displayed per page is currently set to 5 for demonstration purposes
- Tags: newest questions with the tags you are following
- 🌟 New Feature: Based on Phase 1 feedback, you can now filter the questions by selecting or deselecting tags
- Click on "Edit your tags" button to redirect to Subscribe page to modify tags you are following
- Following: newest questions posted by people you are following.
- Everyone: newest question from everyone
-
Sidebar displays your username and has some nice greetings.
-
Users will be able to see the latest notice posted by the admins.
-
Bottom of the sidebar contains buttons which allow users to ask a new question, or go to their profile page.
-
The horizontal navigation bar allows searching for questions by keyword, go to user dashboard, ask a question, go to profile page, or logout of their account
⭐ Improvements:
- Based on Phase 1 feedback: Removed the questions and answers posted by the current user from User Dashboard as User Profile already contains that information
- Sidebar shows user's display name, username, profile picture, and tags this user subscribes to.
- If you are visiting your own profile page, you will see the "Edit Profile" button which leads you to the edit page for your basic account information.
- If you are visiting someone else's profile page, you will be able to follow or unfollow other users by clicking on the "Follow" or "Unfollow" button.
- Notice how the follower list and its count is dynamically updated upon following a user
- Click on the "Report This User" button to report any suspicious activity of this user account.
- Under "Activity", the questions and answers posted by this user account are listed.
- The list of followers and followings of this profile are listed under "Followers" and "Following".
- Users can edit their username, display name and email
- Users can upload or replace their current profile picture by selecting an image and clicking Upload
- The old profile picture will be deleted on the server
- Clicking on "Edit Your Tags" will redirect you to a page where you can follow some popular tags, unfollow current tags, or add a custom tag.
- Clicking on "Change Password" will redirect you to a page (
edit/password
) where you can change your password by entering the new password twice to confirm.- Passwords will be encrypted.
- Users can see their status (normal or flagged) and account type (admin or regular user), but they cannot edit it.
- Validation check is performed to check if information inputted is valid and no duplicating username and email.
- Post a new question by clicking on the "Ask a New Question" button on the user dashboard or "Ask" on the main navigation bar.
- Provide a title, description and at least one related tag and preview your question before posting.
- Separate tags with commas.
- Submitting a question will redirect the user to the newly created question page which will show this new posted question and all its corresponding answers.
- There will be a "Edit Question" button on this redirected page which clicking on it will lead to an edit page for this question.
- Edit page for the question is very similar to the question posting page.
- Contains a single question, showing the title and content of the question, the tags this question is related to, the user who posted this question, and the time this question is posted.
- The user posting this question can edit this question's title, content, and related tags.
- Right upper corner of the question information block shows if this question is resolved. Only the user posting this question can see a "Mark Solved" button to mark the question as resolved.
- Any user can post a reply to questions, and most recent posted answers will be added to the top of the stack of answers, with each answer block showing the content of the answer, the user account posting this answer, and the time this answer was posted.
- Users can edit their answers' content by clicking on the "Edit Answer" button.
- The user posting this question can select the best answer by clicking on the "Pick as Best Answer" button. A best answer will be shown in green and only one best answer is allowed.
- Clicking on the display name or username shown on the question block or any answer block will redirect to that user's profile page.
- Users can report a question or answer.
- Submit a query from any page in the search field provided in the navigation bar.
- Questions and Answers related to this keyword will be displayed on this page in the following three categories:
- Question Results: questions with keyword included in the title or content, click on the search result to jump to corresponding question page
- Answer Results: answers with keyword included in the content
- 🌟 New Feature: Clicking on the answer result will redirect to the corresponding question page and jump to the answer location.
- Tag Results: questions with a tag which keyword is the exact name of the tag, click on the search result to jump to corresponding question page
🌟 New Feature: Clicking on a Tag from anywhere (such as the question page) would redirect to the search results page with that tag name as search keyword.
- Buttons for reporting questions or answers are provided in the individual question page.
- Buttons for reporting a user are provided in the user's profile page.
- Clicking on the report button will direct to a page for giving a reason of reporting this user, question, or answer.
- Will be redirected back to previous page after submitting the report.
In addition to functionalities above, admin users have access to a variety of other features listed below through Admin Dashboard.
- A user can only become an admin user by changing the admin status by another admin user.
- A regular user attempting to visit an admin webpage will be alerted and redirected back to his/her regular dashboard.
- An admin user also have access to all the features a regular user has.
- An admin user can visit the admin dashboard by clicking on the "Admin Dashboard" button, showed only for admin users, in the sidebar of their regular dashboard.
- View all reported users
- Shows the user being reported, the user submitting this report, the reason for the report, and the time this report was submitted.
- Click "View User" to see reported user's profile
- Flag users or deny this report.
- View all reported questions
- Shows the question being reported, the user submitting this report, the reason for the report, and the time this report was submitted.
- Click "View Question" to jump to the question page.
- Flag questions or deny this report.
- View all reported answers
- Shows the question being reported, the user submitting this report, the reason for the report, and the time this report was submitted.
- Click "View Question" to jump to the question page with this answer.
- Flag answer or deny this report.
- Admin's sidebar
- Option to go back to the admin's dashboard.
- Option to go back to the regular dashboard.
- Options for jumping to bookmarks on admin's dashboard to the list of reported users, reported questions or reported answers.
- Options to redirect to a page for posting new notices, to view past reports, or to look at all existing users, questions, answers or tags.
- An admin user could post important notices that are to be pinned on the sidebar of a regular user dashboard.
- A notice contains a title and its content.
- All notices will be shown at the bottom of this page.
- Admin can edit any notice's title, description, and active status.
🌟 New Feature: Only a notice with an active status will be shown on the regular user dashboard. A newly created notice will set the active status of previous notices to false and will be the only active notice
🌟 New Feature:
- Any reviewed reports, which can be both accepted or rejected reports, will be listed in this page.
- An admin user can delete a report by clicking the "Remove Report" button
- An admin could see a list of all registered users.
- Search a user by his/her exact username or email to see his/her complete account information.
- Searching a non-existing user will show "No user found".
- Searching with no keyword input will show all users.
- An admin user could edit any account's information except for the password and profile photo.
- An admin user could mark a user as flagged or unflagged, and make the user to become an admin or regular user.
- The "See Profile" button will lead to this user's profile page.
- Clicking on the "save" button for editing the user profile will check validation of information inputs and check for duplicate username and email.
- Admin could see a list of existing questions in a table showing the title, content, posting user, tags, and the time the question is posted, also the admin could see if the question is flagged and if the question is resolved.
- Admin could edit any question's title, content, and tags, and also could mark questions as flagged or unflagged, resolved or not resolved.
- Editing a question with an empty title, an empty content, or no tag is invalid.
- Admin could see a list of all answers in a table showing the which question it is answering to, the user posting the answer, content of the answer, whether it is the best answer, whether it is flagged, and the time posted.
- Admin could edit any answer's content, whether it is the best answer, and whether it is flagged.
- Editing an answer's content to be empty is invalid.
- Admin could see a list of all existing tags in a table showing the name of the tags and the number of usage of the tags..
- Admin could edit the name of any tag.
- Editing a tag with an empty name is invalid.
This application uses Express server to handle requests, and Mongoose to model application data with schema-based objects.
We have a server.js file where the main express app is implemented. Routes are separated into smaller files under /routes
for a modular implementation of routes. Each of these files, which we refer to as mini-apps, creates an express Router instance as a module to be required in the main app. Each mini-app handles queries on a specific data type while the main app contains methods to serve HTML pages. Below you can see an overview of our main and mini-apps routes:
Routes in server.js
serve HTML pages to the client.
- sessionCheck - checks for existence of an active user on the session, and redirects to user dashboard if it exists.
- authenticate - checks for logged in user, will redirect to register/login page otherwise.
- adminAuthenticate - checks if logged in user is an admin user, will redirect to regular user dashboard otherwise.
Path | Middleware | Redirects to | Required Parameter(s) |
---|---|---|---|
/ | sessionChecker | Landing page | |
/login | sessionChecker | Register/Login page | |
/dashboard | User dashboard if a user is logged in, otherwise redirects to register/login page | ||
/profile | authenticate | Current user profile page if no parameter given; redirects to other user profile page if given parameter user_id . - Redirects to /404 page if can't find the user with given ID. |
user_id |
/edit/profile | authenticate | Page for editing current user’s profile | |
/answer | authenticate | Single question page - Redirects to /404 page if can't find the question with given ID. |
question_id |
/edit/answer | authenticate | Editing answer page - Redirects to /404 page if can't find the answer with given ID. |
question_id and answer_id |
/ask | authenticate | Asking a new question page | |
/edit/question | authenticate | Editing question page - Redirects to /404 page if can't find the question- Redirects to /403 if user attempt to edit someone else's question. |
question_id |
/subscribe | authenticate | Subscribe page | |
/report | authenticate | Report page - Redirects to /404 page if one of the parameters is missing. |
type (=either 'u'(user),'q'(question), or 'a'(answer)), taget_id , user_id , back_url |
/search | authenticate | Search page | search_key |
/admin/dashboard | adminAuthenticate | Admin’s dashboard | |
/admin/editquestion | adminAuthenticate | Admin's edit question page | |
/admin/editanswer | adminAuthenticate | Admin's edit answer page | |
/admin/edituser | adminAuthenticate | Admin's edit user page | |
/admin/edittag | adminAuthenticate | Admin's edit tag page | |
/admin/notice | adminAuthenticate | Admin's post important notices page | |
/admin/editnotice | adminAuthenticate | Admin's edit notice page | notice_id |
/admin/pastreport | adminAuthenticate | Admin's listing past reports page | |
/404 | authenticate | 404 error page | |
/403 | authenticate | 403 error page | |
/500 | authenticate | 500 error page |
Middleware checkers used in mini-apps:
- mongoChecker - checks for mongo connection errors, this is implemented in basically every route therefore will not be listed in the table below
- authenticateAPI - checks for logged in users, will send an error with status code 401 "Unauthorized" otherwise. This will be indicated as "authAPI" in the method tables below.
- adminAuthenticateAPI - checks if a logged in user is an admin user, will send an error with status code 401 "Unauthorized" otherwise. This will be indicated as "adminAPI" in the method tables below.
User Scheme contains user information including
displayname
,username
, andemail
are Strings and requires the minimum length of 1password
requires the minimum length of 3 and are stores as encrypted StringsisFlagged
,isAdmin
are Booleansfollowing
,followers
are list of User IDstags
are list of Tag IDsimage_id
,image_url
are Strings, default being empty Strings
Path | Method [middleware] |
Parameters | Body | Respond | Explanations |
---|---|---|---|---|---|
/users | POST | { email, password, username, displayname } |
- redirect to /subscribe - status 400: Bad request - status 500: Internal server error |
Add a new User to the User collection. |
|
/users/login | POST | { email, password } |
- redirect to /dashboard - status 400: Bad request - status 404: Resource not found - status 500: Internal server error |
Login user by adding info to session. |
|
/users/logout | GET | - redirection to / - status 500: Internal server error |
Log users out by removing the session. |
||
/users /current |
GET [authAPI] |
- (json) User - status 401: Unauthorized |
Get User object re- presenting current logged in user |
||
/users/:id | GET [authAPI] |
User ID | - (json) User - status 401: Unauthorized - status 404: Resource not found - status 500: Internal server error |
Get the User object with the given User ID. |
|
/users | GET [adminAPI] |
- (json) array of Users - status 401: Unauthorized - status 500: Internal server error |
Get a list of all existing User from User collection. |
||
/users /mapping |
POST [authAPI] |
{ids :<ID array>} |
- (json) object mapping ids to Users - status 404: Can't find Users - status 500: Internal server error |
Given a list of User IDs, return an object that maps User IDs to Users Objects. |
|
/users | PATCH [authAPI] |
{ displayname, username, email } |
- redirect to /profile - status 400: Bad Request - status 401: Unauthorized - status 404: User not found - status 500: Internal server error |
Modify current user's displayname, username, and email; will check to avoid user changing other's profiles. |
|
/users/:id | PATCH [adminAPI] |
User ID | { displayname, username, email, tags, isFlagged, isAdmin } |
- redirect to /profile - status 400: Bad Request - status 401: Unauthorized - status 404: ID not valid - status 404: User not found - status 500: Internal server error |
Edit profile of user (with given UserID) by admin user. |
/users /password |
PATCH [authAPI] |
{ password } | - redirect to /profile - status 400: Bad Request - status 401: Unauthorized - status 404: User not found - status 500: Internal server error |
Modify current user's password. |
|
/users /flag/:id |
PATCH [adminAPI] |
User ID | { flag : Boolean } |
- (json) flagged User - status 400: Bad Request - status 401: Unauthorized - status 404: ID not valid -status 404: User not found - status 500: Internal server error |
Flag user with given User ID if flag is true, otherwise unflag user. |
/users/picture | POST [authAPI] [multipart * ] |
- (json) current User - status 400: Bad Request - status 401: Unauthorized -status 404: User not found - status 500: Internal server error |
Upload a new profile photo. |
||
/users /follow/:id |
POST [authAPI] |
User ID | - (json) current User -status 400: Already following - status 400: Bad Request - status 401: Unauthorized - status 404: ID not valid - status 404: User not found - status 500: Internal server error |
Add user ID to fol- lowing list of current user, will check to avoid following twice. |
|
/users /unfollow/:id |
POST [authAPI] |
User ID | - (json) current User -status 400: Already not following - status 400: Bad Request - status 401: Unauthorized - status 404: ID not valid - status 404: User not found - status 500: Internal server error |
Remove the User ID from the following list of current user, will check to avoid un- following twice. |
* multipart meaning the multipart middleware that allows you to access uploaded file from req.file
Ex. Testing a post /user
route:
- Set method as POST
- Type in
http://localhost:5000/users
for request URL - In Body text area, choose JSON and input some data. By looking at the table above, we can see that a POST '/users' route requires a body object providing variables
email
,password
,username
, anddisplayname
. By looking at the User Schema Explanation, we know that these four variables are all Strings:
{
"email": "someuser@someuser.com",
"password": "someuser",
"username": "someuser",
"displayname": "displaydisplay"
}
- After sending the request, subscribe.html should be returned
Tag Schema contains two attributes:
name
which is name of the tag, with minimum length of 1count
with default number 0, this is an indicator of how popular the tag is
Path | Method [middleware] |
Parameters | Body | Respond | Explanations |
---|---|---|---|---|---|
/tag | GET [authAPI] |
- (json) array of Tags - status 401: Unauthorized - status 500: Internal Server Error |
Get all existing Tags. | ||
/tag /popular |
GET [authAPI] |
- (json) array of Tags - status 401: Unauthorized - status 500: Internal Server Error |
Get all existing Tags sorted by number of usage. |
||
/tag/names | POST [authAPI] |
{ ids: <ID array> } |
- (json) array of Strings - status 401: Unauthorized - status 404: Can't find all tags - status 500: Internal Server Error |
Input an array of Tag IDs, return the corresponding array of tag names. |
|
/tag/info | POST [authAPI] |
{ ids: <ID array> } |
- (json) array of Tags - status 401: Unauthorized - status 404: Can't find all tags - status 500: Internal Server Error |
Input an array of Tag IDs, return the corresponding array of Tags. |
|
/tag | POST [authAPI] |
{ name } | - (json) new created Tag - status 400: Bad Request - status 401: Unauthorized - status 500: Internal Server Error |
Adding a new Tag to collection, will check to avoid duplicate tag names. |
|
/tag/:id | PATCH [adminAPI] |
Tag ID | { name } | - (json) updated Tag - status 400: Bad Request - status 401: Unauthorized - status 404: Resource not found - status 404: Tag not found - status 500: Internal Server Error |
Edit name of tag with given id, will check to avoid duplicate tag names. |
/tag | DELETE [adminAPI] |
Tag ID | - (json) deleted Tag - status 401: Unauthorized - status 404: Resource not found - status 404: Tag not found - status 500: Internal Server Error |
Delete Tag with given ID from collection. |
|
/tag /follow /:id |
PATCH [authAPI] |
Tag ID | - (json) followed Tag - status 400: Bad Request - status 401: Unauthorized - status 404: Invalid Tag ID - status 404: Tag not found - status 409: Already following Tag - status 500: Internal Server Error |
Add Tag ID to current user’s list of following tags, will check to avoid following twice. |
|
/tag /unfollow /:id |
PATCH [authAPI] |
Tag ID | - (json) unfollowed Tag - status 400: Bad Request - status 401: Unauthorized - status 404: Invalid Tag ID - status 404: Tag not found - status 500: Internal Server Error |
Remove Tag ID from current user’s list of following tags, will check to avoid unfollowing twice. |
|
/tag /increment /:id |
PATCH [authAPI] |
Tag ID | - (json) updated Tag - status 400: Bad Request - status 401: Unauthorized - status 404: Invalid Tag ID - status 404: Tag not found - status 500: Internal Server Error |
Count one more the usage of Tag with given Tag ID. |
|
/tag/:id | GET [authAPI] |
Tag ID | - (json) Tag - status 400: Bad Request - status 401: Unauthorized - status 404: Invalid Tag ID - status 404: Tag not found - status 500: Internal Server Error |
Get Tag with given Tag ID |
Ex. Testing a get /tag
route:
- By looking at the Method[middleware] column, we can see that all routes are running with either authenticateAPI or adminAuthenticateAPI middleware, so we need to log in before testing, or else you will receive status 401 Unauthorized error.
- If you are not logged in, you can login using Postman by setting method to POST, with request URL:
http://localhost:5000/users/login
, with the account we just created in previous example in body and send request.
{
"email": "someuser@someuser.com",
"password": "someuser"
}
- This will return
user_dashboard.html
to indicate you are logged in. - To test a get
/tag
routes, set method to GET, enterhttp://localhost:5000/tag
, since we can see from the table above that we don't need any other inputs, simply send request. - A list of Tag Objects should be returned.
Question Schema includes:
title
,content
are Strings requiring minimum length of 1user
is the User ID of user who posted this questiontags
is a list of Tag IDsanswers
is a list of subdocument AnswerSchemaisResolved
,is Flagged
are Booleanstime
is Date object with default being Date.now at initializationlastUpdated
is Date objects that is Date.now for each question update
Path | Method [middleware] |
Parameters | Body | Respond | Explanations |
---|---|---|---|---|---|
/questions | POST [authAPI] |
{ title, content, tags } |
- redirects to /answer -status 400 : Bad Request - status 401: Unauthorized -status 500: Internal server error |
Add a new Question to the collection. |
|
/questions | GET [authAPI] |
-(json) array of Questions -status 500: Internal Server Error - status 401: Unauthorized |
Get all existing questions from the Question collection |
||
/questions /users/:user |
GET [authAPI] |
User ID | -(json) array of Questions - status 401: Unauthorized -status 500: Internal Server Error |
Get all Questions posted by user with given User ID |
|
/questions /following |
GET [authAPI] |
-(json) array of Questions - status 401: Unauthorized -status 500: Internal Server Error |
Get all Questions posted by users which the current user is following. |
||
/questions/tags | POST [authAPI] |
{ tag_ids: <ID array> } |
-(json) array of Questions - status 401: Unauthorized -status 500: Internal Server Error |
Given an array of Tag IDs, get all the questions that each contain at least one tag from the Tag ID array. |
|
questions /tags/:tagname |
GET [authAPI] |
tagname | -(json) array of Questions - status 401: Unauthorized -status 404: Tag name not found -status 500: Internal Server Error |
Get all questions containing a tag with given tag name. |
|
/question /search/:keyword |
GET [authAPI] |
keyword | -(json)array of Question - status 401: Unauthorized -status 500: Internal Server Error |
Get all questions con- taining the given keyword in either the title or the content |
|
/questions/:id | GET [authAPI] |
Question ID | -(json) Question - status 401: Unauthorized -status 404: Question not found -status 500: Internal Server Error |
Get the question with given ID |
|
/questions /flag/:id |
PATCH [adminAPI] |
Question ID | { flag : Boolean } |
-(json) Question -status 400: Bad request -status 404: ID not valid -status 404: Question not found -status 500: Internal Server Error |
Flag the Question with given Question ID if flag is true, otherwise unflag it. |
/questions/:id | PATCH [authAPI] |
Question ID | { title, content, tags, isResolved } |
- redirect to /answer -status 400: Bad request - status 401: Unauthorized -status 403: No permission to edit question -404: Question not found -status 500: Internal Server Error |
Update information of the question with given Question ID, will check to avoid user with no per- mission to edit question. |
/questions /admin/:id |
PATCH [adminAPI] |
Question ID | { title, content, tags, isResolved, isFlagged } |
-(json) updated Question -status 400: Bad request - status 401: Unauthorized -status 404: Question not found -status 404: Invalid question ID -status 500: INternal Server Error |
Edit a question with given Question ID by an admin user. |
Ex. Testing a POST /questions
route:
- Same as all the Tag routes, calling a question route requires you to log in from Postman first.
- To test a
POST /question
route, according to the table above, we need a body withtitle
,content
,tags
. By lookin gat the Question Schema Explanation, we know thattitle
andcontent
are Strings, andtags
is a list of Tag IDs.- You can get a Tag ID by using the
POST /tag
route to create a new Tag, and the Tag object will be returned so you can get the ID of this Tag under the_id
field. Also, you can get a list of Tags by using theGET /tag
route if you already have Tags in the database.
- You can get a Tag ID by using the
- Set the method to
POST
, type inhttp://localhost:5000/questions
for request URL, and enter in the body text area something such as:
{
"title": "Some title for this question",
"content": "Some content for this question",
"tags": ["<Tag ID>", "<Tag ID>", "<Tag ID>"]
}
- After sending the request,
answer.html
should be returned with paramaterquestion_id
being the ID of this new created question.
Answer Schema includes:
content
is a String requiring minimum length of 1user
is a User IDisFlagged
,isBest
are Booleanstime
is Date object with default being Date.now at initializationlastUpdated
is Date objects that is Date.now for each answer update
Path | Method [middleware] |
Parameters | Body | Respond | Explanations |
---|---|---|---|---|---|
/answers /users /:users |
GET [authAPI] |
User ID | - (json) array of Questions - status 401: Unauthorize - status 500: Internal Server Error |
Get a list of Questions containing Answer(s) posted by user with given User ID |
|
/answers /search /:keyword |
GET [authAPI] |
String | - (json) array of Questions - status 401: Unauthorize - status 500: Internal Server Error |
Get a list of Questions containing Answer(s) containing the given keyword |
|
/answers /:question_id /:answer_id |
GET [authAPI] |
Question ID, Answer ID |
- (json) Answer - status 401: Unauthorize - status 404: Invalid ID - status 404: Question not found - status 500: Internal Server Error |
Get the answer with given Answer ID that could be found in the question with given Question ID |
|
/answers /:answer_id |
GET [authAPI] |
Answer ID | - (json) Question, Answer - status 401: Unauthorize - status 404: Invalid ID - status 404: Question not found - status 404: Answer not found - status 500: Internal Server Error |
Find answer using given Answer ID only. This is different from previous route because this needs more steps to search into all questions since Answer is subdocument of Question |
|
/answers /flag/:id |
PATCH [adminAPI] |
Answer ID | { flag : Boolean } |
- (json) Question - status 400: Bad request - status 401: Unauthorize - status 404: ID not valid - status 404: Answer not found - status 500: Internal Server Error |
Flag the answer with given Answer ID if flag in bodyis true, otherwise unflag it |
/answers /:question_id /:answer_id |
PATCH [authAPI] |
Question ID, Answer ID |
{ content } | - redirect to /answer - status 400: Bad request - status 401: Unauthorize - status 403: No permission to edit - status 404: Invalid ID - status 404: Question not found - status 404: Answer not found - status 500: Internal Server Error |
Edit the content of the answer with given Answer ID that could be found in the question with given Question ID |
/answers /admin /:question_id /:answer_id |
PATCH [adminAPI] |
Question ID, Answer ID |
{ content, isBest, isFlagged } |
- (json) Question - status 400: Bad request - status 401: Unauthorize - status 404: Invalid ID - status 404: Question not found - status 404: Answer not found - status 500: Internal Server Error |
Edit the information of the answer with given Answer ID that could be found in the question with given Question ID, by an admin user. |
/answers /best /:question_id /:answer_id |
POST [authAPI] |
Question ID, Answer ID |
- status 200: Selected as best answer - status 400: Bad request - status 401: Unauthorize - status 403: No permission to edit - status 404: Invalid ID - status 404: Question not found - status 404: Answer not found - status 500: Internal Server Error |
Edit the answer with given Answer ID to be the best answer in the question with given Question ID, will check to avoid unrelated user to edit this question |
|
/answers /:id |
POST [authAPI] |
Question ID | { content } | - (json) Answer - status 400: Bad request - status 401: Unauthorize - status 404: question not valid - status 404: question not found - status 500: Internal Server Error |
Create a new Answer to be stored in the array of answers in the question with given Question ID |
Ex. Testing a POST /answers
route:
- We can see from the table above that calling an answers route requires you to log in from Postman first.
- To test a
POST /answers
route, according to the table above, we need a body with acontent
field, and we need a Question ID as parameter. By lookin gat the Answer Schema Explanation, we know thatcontent
is a Strings.- You can get Question IDs by querying as list of questions by using the
GET /questions
route if you already have Questions in the database and look at the_id
field.
- You can get Question IDs by querying as list of questions by using the
- Set the method to
POST
, type inhttp://localhost:5000/answers/<Quesiton ID>
for request URL, and enter in the body text area something such as:
{
"content": "Some content of this answer"
}
- After sending the request, a new created Answer object with the given
content
will be returned to you.
type
: String belongs to [u
,q
,a
] representing User, Question and AnswertargetId
is ObjectId, could be ID of User, Questions, or Answerreason
: Stringuser
is User ID of user submitting reportreviewer
is User ID of admin reviewing reporttime
is Date object with default being Date.now at initializationlastUpdated
is Date objects that is Date.now for each report update
Path | Method [middleware] |
Parameters | Body | Respond | Explanations |
---|---|---|---|---|---|
/reports | POST [authAPI] |
{type, targetId, reason, user} |
- (json)Report - status 400: Bad Request - status 401: Unauthorized - status 500: Internal Server Error |
Creating a new report | |
/reports | GET [adminAPI] |
- (json)array of Report - status 401: Unauthorized -status 500: Internal Server Error |
Getting all existing reports | ||
/reports /type/user |
GET [adminAPI] |
- (json)array of Report - status 401: Unauthorized - status 404: Reported user not found - status 500: Internal Server Error |
Get all reports with the type of 'u'. | ||
/reports /type/question |
GET [adminAPI] |
- (json)array of Report - status 401: Unauthorized - status 404: Reported user not found - status 500: Internal Server Error |
Get all reports with type 'q'. | ||
/reports /type/answer |
GET [adminAPI] |
- (json)array of Report - status 401: Unauthorized - status 404: Reported user not found - status 500: Internal Server Error |
Get all reports with type 'a'. | ||
/reports/:id | GET [adminAPI] |
Report ID | - (json)Report - status 401: Unauthorized - status 404: Invalid Report ID - status 404: Report not found - status 500: Internal Server Error |
Get report by given report id. | |
/reports/:id | PATCH [adminAPI] |
Report ID | {reviewer, isReviewed} |
- (json) updated Report - status 400: Bed Request - status 401: Unauthorized - status 404: Invalid Report ID - status 404: Report not found - status 500: Internal Server Error |
Edit state of report with given report id. |
Ex. Testing a get /reports
route:
- By looking at the Method[middleware] column, we can see that most
/reports
routes runs with the adminAuthenticateAPI middleware, so we need to log in with an admin account before testing, or else you will receive status 401 Unauthorized error.- The very first admin user is setted by changing the
isAdmin
field of a User from the database.
- The very first admin user is setted by changing the
- To test a get
/reports
routes, set method to GET, enterhttp://localhost:5000/reports
, since we can see from the table above that we don't need any other inputs, simply send request. - A list of Report Objects will be returned.
Notice Schema includes attributes:
title
andcontent
are Strings requiring minimum length of 1time
is Date object of posted timeuser
is User ID of user who posted this noticeisShowing
is a Boolean states whether to show notice or not
Path | Method [middleware] |
Parameters | Body | Respond | Explanations |
---|---|---|---|---|---|
/notice | POST [adminAPI] |
{title, content, user} |
- (json)Notice - status 400: Bad Request - status 401: Unauthorized - status 500: Internal Server Error |
Creating a notice | |
/notice /current |
GET [authAPI] |
- (json)Notice - status 401: Unauthorized - status 404: Bad Request - status 500: Internal Server Error |
Get an notice with isShowing set to true | ||
/notice | GET [adminAPI] |
- (json)array of Notice - status 401: Unauthorized - status 500: Internal Server Error |
Get all notice | ||
/notice/:id | GET [adminAPI] |
Notice ID | - (json)Notice - status 401: Unauthorized - status 404: Invalid Notice ID - status 404: Notice not found - status 500: Internal Server Error |
Get the notice by given notice id | |
/notice/:id | PATCH [adminAPI] |
Notice ID | {title, content, isShowing(opt)} |
- (json)updated Notice - status 400: Bad request. - status 401: Unauthorized - status 404: Invalid Notice ID - status 404: Notice not found - status 500: Internal Server Error |
Manually edit notice from admin dashboard |
* An example of testing a /notice
route would be similar to the previous examples.