The team project for this class is designed to mirror the experiences of a software engineer: by virtue of your individual projects, you have been onboarded to our codebase, made several individual contributions, and have formed a team to propose, develop and implement new features. The codebase that we’ll be developing on is a Fake Stack Overflow project (let’s call it HuskyFlow). You will get an opportunity to work with the starter code which provides basic skeleton for the app and then additional features will be proposed and implemented by you! All implementation will take place in the TypeScript programming language, using React for the user interface.
-
Run
npm installin the root directory to install all dependencies for theclient,server, andsharedfolders. -
Create
server/.envcontaining:
MONGODB_URI=mongodb+srv://meganrivard21_db_user:0a7CXpIhei1sviIC@db-cs4530-fall25-211.8bwrf6f.mongodb.net
CLIENT_URL=http://localhost:4530
PORT=8000
AGORA_APP_CERTIFICATE=7032c8307f1442a7bd57a15b13da6ba5
AGORA_APP_ID=8ed4ad1354614d1aab38c64276cc38eb
JUDGE0_API_URL=https://judge0-ce.p.rapidapi.com
JUDGE0_API_KEY=b081a7993bmsh1e5f601228ec69cp14c588jsn5c0a01f85bc4 -
Create
client/.envcontaining:
REACT_APP_SERVER_URL=http://localhost:8000
AGORA_APP_CERTIFICATE=7032c8307f1442a7bd57a15b13da6ba5
VITE_AGORA_APP_ID=8ed4ad1354614d1aab38c64276cc38eb -
Run
npm run devin both theserverandclientfolders. -
Open with
http://localhost:4530.
Note
Refer to IP1 and IP2 for further instructions related to setting up MongoDB, setting environment variables, and running the client and server.
client: Contains the frontend application code, responsible for the user interface and interacting with the backend. This directory includes all React components and related assets.server: Contains the backend application code, handling the logic, APIs, and database interactions. It serves requests from the client and processes data accordingly.shared: Contains all shared type definitions that are used by both the client and server. This helps maintain consistency and reduces duplication of code between the two folders. The type definitions are imported and shared within each folder'stypes/types.tsfile.
The schemas for the database are documented in the directory server/models/schema.
A class diagram for the schema definition is shown below:
| Endpoint | Method | Description |
|---|---|---|
/addAnswer |
POST | Add a new answer |
| Endpoint | Method | Description |
|---|---|---|
/addComment |
POST | Add a new comment |
| Endpoint | Method | Description |
|---|---|---|
/addMessage |
POST | Add a new message |
/getMessages |
GET | Retrieve all messages |
| Endpoint | Method | Description |
|---|---|---|
/getQuestion |
GET | Fetch questions by filter |
/getQuestionById/ |
GET | Fetch a specific question by ID |
/addQuestion |
POST | Add a new question |
/upvoteQuestion |
POST | Upvote a question |
/downvoteQuestion |
POST | Downvote a question |
| Endpoint | Method | Description |
|---|---|---|
/getTagsWithQuestionNumber |
GET | Fetch tags along with the number of questions |
/getTagByName/ |
GET | Fetch a specific tag by name |
| Endpoint | Method | Description |
|---|---|---|
/signup |
POST | Create a new user account |
/login |
POST | Log in as a user |
/resetPassword |
PATCH | Reset user password |
/getUser/ |
GET | Fetch user details by username |
/getUsers |
GET | Fetch all users |
/deleteUser/ |
DELETE | Delete a user by username |
/updateBiography |
PATCH | Update user biography |
| Endpoint | Method | Description |
|---|---|---|
/createChat |
POST | Create a new chat. |
/:chatId/addMessage |
POST | Add a new message to an existing chat. |
/:chatId |
GET | Retrieve a chat by its ID, optionally populating participants and messages. |
/:chatId/addParticipant |
POST | Add a new participant to an existing chat. |
/getChatsByUser/:username |
GET | Retrieve all chats for a specific user based on their username. |
| Endpoint | Method | Description |
|---|---|---|
/create |
POST | Create a new game |
/join |
POST | Join an existing game |
/leave |
POST | Leave a game |
/games |
GET | Retrieve all games |
| Endpoint | Method | Description |
|---|---|---|
/create |
POST | Create a new collection |
/delete/:collectionId |
DELETE | Delete a collection |
/toggleSaveQuestion |
PATCH | Add/remove question from collection |
/getCollectionsByUsername/:username |
GET | Get collections by username |
/getCollectionById/:collectionId |
GET | Get collection by ID |
| Endpoint | Method | Description |
|---|---|---|
/getCommunity/:communityId |
GET | Get a specific community |
/getAllCommunities |
GET | Get all communities |
/toggleMembership |
POST | Join/leave a community |
/create |
POST | Create a new community |
/delete/:communityId |
DELETE | Delete a community |
| Endpoint | Method | Description |
|---|---|---|
/getCommunity/:communityId |
GET | Get a specific community |
/getAllCommunities |
GET | Get all communities |
/toggleMembership |
POST | Join/leave a community |
/create |
POST | Create a new community |
/delete/:communityId |
DELETE | Delete a community |
| Endpoint | Method | Description |
|---|---|---|
/getSubmissions/:challengeId |
GET | Get all submissions for a specific challenge |
/getUserSubmissions/:username |
GET | Get all submissions by a specific user |
| Endpoint | Method | Description |
|---|---|---|
/create/:timerId |
POST | Create a new timer |
/getTimer/:timerId |
GET | Get timer by ID |
/delete/:timerId |
DELETE | Delete timer by ID |
/start/:timerId |
POST | Start a timer |
/pause/:timerId |
POST | Pause a timer |
/reset/:timerId |
POST | Reset a timer |
/switchType/:timerId |
POST | Switch timer type (focus ↔ break) |
| Endpoint | Method | Description |
|---|---|---|
/send |
POST | Send a friend request |
/accept |
POST | Accept a friend request |
/reject |
POST | Reject a friend request |
/cancel |
POST | Cancel a friend request |
/remove |
POST | Remove a friend |
| Endpoint | Method | Description |
|---|---|---|
/create |
POST | Create a new challenge |
/update/:challengeId |
PUT | Update an existing challenge |
/delete/:challengeId |
DELETE | Delete a challenge |
/toggleSubmission |
POST | Toggle submission for a challenge |
| Endpoint | Method | Description |
|---|---|---|
/create |
POST | Create a new space |
/join |
POST | Join a space |
/leave |
POST | Leave a space |
/delete/:spaceId |
DELETE | Delete a space |
/update/:spaceId |
PUT | Update a space (name, description, settings) |
| Endpoint | Method | Description |
|---|---|---|
/login |
GET | Redirect to Spotify authentication |
/callback |
GET | Spotify callback with authorization code |
/saveRefreshToken |
POST | Store a Spotify refresh token for a user |
/getToken |
GET | Get a Spotify access token using stored refresh token |
| Endpoint | Method | Description |
|---|---|---|
/getSubmissions/:challengeId |
GET | Get all submissions for a specific challenge |
/getUserSubmissions/:username |
GET | Get all submissions by a specific user |
/toggleSubmission |
POST | Toggle a submission for a challenge (add/remove) |
OpenAPI specifications as given in the server/openapi.yaml file should give you an idea about the overall structure of the API endpoints, the request format and the various path/query parameters required as well as the expected response formats. To see a detailed explanation of the schemas and to test the endpoint in a sandboxed environment, you can use the Swagger UI page as follows:
- Start the server as specified earlier (
cd server && npm run dev). - Visit
http://localhost:8000/api/docsto see the complete API specification in a user friendly manner. - You should be able to see and test out individual endpoints using the Try it out button associated with each endpoint.
The specification itself is coupled with an OpenAPI validator (present as a middleware) that validates every request and response against the provided spec document.
Cypress tests are end-to-end tests that can help verify your implementation.
-
Navigate to the
testingdirectory:cd testing -
Install dependencies:
npm install
-
Create a
.envfile in thetesting/directory with the following content:MONGODB_URI=mongodb://127.0.0.1:27017 -
Make sure that both the server and client are already running
-
Run Cypress tests:
npx cypress open
-
In the Cypress UI that opens:
- Select E2E Testing
- Choose your browser (Chrome is preferred)
- Click on any of the test files to run it
- If any of the tests fail, you should be able to see the exact sequence of steps that led to the failure.
Note
Running Cypress tests is optional. Cypress tests require significant system resources, and without them, the tests may be flaky. We will use these tests for grading.
