DevExchange is a collaborative developer Q&A and knowledge‑sharing platform focused on helping engineers ask technical questions, discover answers, and curate useful content. The platform supports:
- Question and answer threads with voting and sorting
- Rich tagging and search to surface related content
- Public and private communities for topic-focused discussion
- Personal collections for saving and organizing useful posts
- Direct messaging and global notifications
- Gamification: achievements, leaderboards, and moderation actions
This repository contains the full-stack implementation used for the CS4530 team project (internally referred to as "HuskyFlow"). It includes a TypeScript + React frontend, an Express/Node backend, shared TypeScript types, seed data and tests so you can run, extend, and evaluate the platform.
The website is: https://cs4530-f25-207.onrender.com/
-
Please create a .env file in the client folder with the following properties:
-
VITE_SERVER_URL=http://localhost:8000
-
Please create a .env file in the server folder with the following properties: MONGODB_URI=mongodb+srv://kapadiaket_db_user:FOs17swh1ahl8SIm@db-cs4530-fall25-207.rok6aqu.mongodb.net CLIENT_URL=http://localhost:4530 PORT=8000
JWT_SECRET=0dcb7f77c9b647c459392ccaed9770a45d92f1b54a11e2529aae435d06bb237f
GOOGLE_CLIENT_ID = 274742781462-tdr2f9us2q1k0n0gesb1hs21a5p80td3.apps.googleusercontent.com GOOGLE_CLIENT_SECRET = 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
GITHUB_CLIENT_ID = Ov23lizfLwXjfhdmU310 GITHUB_CLIENT_SECRET = 3f48bc3dac18a2ca01e1c767406bf928133b8627
GOOGLE_CALLBACK_URL=https://localhost:8000/auth/google/callback GITHUB_CALLBACK_URL=https://localhost:8000/auth/github/callback
Please create a .env file in the testing folder with the following properties: MONGODB_URI=mongodb+srv://kapadiaket_db_user:FOs17swh1ahl8SIm@db-cs4530-fall25-207.rok6aqu.mongodb.net
Run npm install in the root directory to install all dependencies for the client, server, and shared folders.
Note
Refer to IP1 and IP2 for further instructions related to setting up MongoDB, setting environment variables, and running the client and server.
Seed data
- Server seed scripts: The server contains scripts to populate and clear the local MongoDB instance. From the
serverdirectory you can run:
npm run populate-db # populate the DB from server/seedData/data
npm run delete-db # clear the DBEnsure MONGODB_URI is set (see server/seedData/README.md for details on data order and collection dependencies).
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 |
/upvoteAnswer |
POST | Upvote an answer |
/downvoteAnswer |
POST | Downvote an answer |
/deleteAnswer/:aid |
DELETE | Soft-delete an answer (moderator only) |
/flagAnswer/:answerId |
PATCH | Toggle flag on an answer |
/getFlaggedAnswers |
GET | Retrieve flagged answers for moderator review |
/changeAnswerType |
POST | Change answer type |
| Endpoint | Method | Description |
|---|---|---|
/addComment |
POST | Add a new comment |
/upvoteComment |
POST | Upvote a comment |
/downvoteComment |
POST | Downvote a comment |
/deleteComment/:cid |
DELETE | Soft-delete a comment (moderator only) |
/flagComment/:commentId |
PATCH | Toggle flag on a comment |
/getFlaggedComments |
GET | Retrieve flagged comments for moderator review |
| 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 |
/flagQuestion/:questionId |
PATCH | Toggle flag on a question |
/getFlaggedQuestions |
GET | Retrieve flagged questions for moderator review |
/addTagToQuestion |
PUT | Add a tag to a question |
/removeTagFromQuestion |
PUT | Remove a tag from a question |
/deleteQuestion/:qid |
DELETE | Soft-delete a question (moderator only) |
/closeQuestion/:qid |
POST | Close a question (moderator only) |
/reopenQuestion/:qid |
POST | Reopen a question (moderator only) |
| Endpoint | Method | Description |
|---|---|---|
/getTagsWithQuestionNumber |
GET | Fetch tags along with the number of questions |
/getTagByName/ |
GET | Fetch a specific tag by name |
/getAllTags |
GET | Retrieve all tags |
/addTag |
POST | Create a new tag |
| Endpoint | Method | Description |
|---|---|---|
/suspend |
POST | Issue a suspension to a user (moderator only) |
/lift-suspension/:username |
PATCH | Life a suspension from a user (moderator only) |
| Endpoint | Method | Description |
|---|---|---|
/getModeratorActions/:moderatorUsername |
GET | Fetch all actions performed by a specific moderator |
| Endpoint | Method | Description |
|---|---|---|
/getAchievements/:targetUsername |
GET | Fetch all achievements awarded to a specific user |
| 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 |
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.
