From 192ded1e8cd0dd27f3d1560e7e5694a093b32fcc Mon Sep 17 00:00:00 2001 From: timmi Date: Sun, 23 Mar 2025 20:00:09 -0700 Subject: [PATCH 1/5] Updated API documentation and fixed formatting issues. --- API_DOCUMENTATION.md | 1042 ++++++++--------- .../task_manager/service/TeamService.java | 9 +- 2 files changed, 527 insertions(+), 524 deletions(-) diff --git a/API_DOCUMENTATION.md b/API_DOCUMENTATION.md index b13d065b..4d54bdf2 100644 --- a/API_DOCUMENTATION.md +++ b/API_DOCUMENTATION.md @@ -41,273 +41,273 @@ All API requests should be made to the following base URL (Spring Boot's default - **Create Admin:** `POST /` - - **Description:** Creates a new admin in the system. - - **Request Body:** - - ```json - { - "name": "Admin Name", - "email": "admin@example.com", - "password": "securepassword" - } - ``` + - **Description:** Creates a new admin in the system. + - **Request Body:** - - **Response Body:** + ```json + { + "name": "Admin Name", + "email": "admin@example.com", + "password": "securepassword" + } + ``` - ```json - { - "accountId": 1, - "userName": "Admin Name", - "userEmail": "admin@example.com" - } - ``` + - **Response Body:** + + ```json + { + "accountId": 1, + "userName": "Admin Name", + "userEmail": "admin@example.com" + } + ``` - **Delete Admin:** `DELETE /{adminId}` - - **Parameters:** - - `adminId` (integer, required): The unique ID of the admin to be deleted. - - **Description:** Removes an admin from the system permanently. + - **Parameters:** + - `adminId` (integer, required): The unique ID of the admin to be deleted. + - **Description:** Removes an admin from the system permanently. - **Modify Admin Name:** `PUT /{adminId}/update-name` - - **Request Body:** + - **Request Body:** - ```json - { - "newName": "Updated Admin Name" - } - ``` + ```json + { + "newName": "Updated Admin Name" + } + ``` - - **Response Body:** + - **Response Body:** - ```json - { - "accountId": 1, - "userName": "Updated Admin Name", - "userEmail": "admin@example.com" - } - ``` + ```json + { + "accountId": 1, + "userName": "Updated Admin Name", + "userEmail": "admin@example.com" + } + ``` - - **Description:** Updates the admin's **name** field in the database. + - **Description:** Updates the admin's **name** field in the database. - **Modify Admin Email:** `PUT /{adminId}/update-email` - - **Request Body:** + - **Request Body:** - ```json - { - "newEmail": "updated.admin@example.com" - } - ``` + ```json + { + "newEmail": "updated.admin@example.com" + } + ``` - - **Response Body:** + - **Response Body:** - ```json - { - "accountId": 1, - "userName": "Admin Name", - "userEmail": "updated.admin@example.com" - } - ``` + ```json + { + "accountId": 1, + "userName": "Admin Name", + "userEmail": "updated.admin@example.com" + } + ``` - - **Description:** Updates the admin's **email** field in the database. + - **Description:** Updates the admin's **email** field in the database. - **Create Team Member:** `POST /team-member` - - **Request Body:** + - **Request Body:** - ```json - { - "name": "Team Member", - "email": "teammember@example.com", - "password": "securepassword" - } - ``` + ```json + { + "name": "Team Member", + "email": "teammember@example.com", + "password": "securepassword" + } + ``` - - **Response Body:** + - **Response Body:** - ```json - { - "accountId": 2, - "userName": "Team Member", - "userEmail": "teammember@example.com" - } - ``` + ```json + { + "accountId": 2, + "userName": "Team Member", + "userEmail": "teammember@example.com" + } + ``` - - **Description:** Adds a new team member to the system. + - **Description:** Adds a new team member to the system. - **Modify Team Member Name:** `PUT /team-member/{teamMemberId}/update-name` - - **Request Body:** + - **Request Body:** - ```json - { - "newName": "Updated Team Member" - } - ``` + ```json + { + "newName": "Updated Team Member" + } + ``` - - **Response Body:** + - **Response Body:** - ```json - { - "accountId": 2, - "userName": "Updated Team Member", - "userEmail": "teammember@example.com" - } - ``` + ```json + { + "accountId": 2, + "userName": "Updated Team Member", + "userEmail": "teammember@example.com" + } + ``` - - **Description:** Updates the **name** field of the specified team member in the database. + - **Description:** Updates the **name** field of the specified team member in the database. - **Modify Team Member Email:** `PUT /team-member/{teamMemberId}/update-email` - - **Request Body:** + - **Request Body:** - ```json - { - "newEmail": "updated.tm@example.com" - } - ``` + ```json + { + "newEmail": "updated.tm@example.com" + } + ``` - - **Response Body:** + - **Response Body:** - ```json - { - "accountId": 2, - "userName": "Team Member", - "userEmail": "updated.tm@example.com" - } - ``` + ```json + { + "accountId": 2, + "userName": "Team Member", + "userEmail": "updated.tm@example.com" + } + ``` - - **Description:** Updates the **email** field of the specified team member in the database. + - **Description:** Updates the **email** field of the specified team member in the database. - **Delete Team Member:** `DELETE /team-member/{teamMemberId}` - - **Parameters:** - - `teamMemberId` (integer, required): The unique ID of the team member to be deleted. - - **Description:** Removes a team member from the system permanently. + - **Parameters:** + - `teamMemberId` (integer, required): The unique ID of the team member to be deleted. + - **Description:** Removes a team member from the system permanently. - **Assign Team Member to a Team:** `POST /team-member/{teamMemberId}/assign-to-team/{teamId}` - - **Parameters:** - - `teamMemberId` (integer, required): The ID of the team member to assign. - - `teamId` (integer, required): The ID of the team to assign them to. - - **Description:** Assigns a team member to a specified team. + - **Parameters:** + - `teamMemberId` (integer, required): The ID of the team member to assign. + - `teamId` (integer, required): The ID of the team to assign them to. + - **Description:** Assigns a team member to a specified team. - **Promote Team Member to Admin:** `POST /team-member/{teamMemberId}/promote` - - **Parameters:** - - `teamMemberId` (integer, required): The ID of the team member to be promoted. - - **Description:** Upgrades a team member to an admin role, granting them full administrative privileges. + - **Parameters:** + - `teamMemberId` (integer, required): The ID of the team member to be promoted. + - **Description:** Upgrades a team member to an admin role, granting them full administrative privileges. - **Lock a Task:** `PUT /tasks/{taskId}/lock` - - **Parameters:** - - `taskId` (integer, required): The ID of the task to lock. - - **Description:** Locks a task to prevent any modifications. Once locked, updates and deletions are restricted. + - **Parameters:** + - `taskId` (integer, required): The ID of the task to lock. + - **Description:** Locks a task to prevent any modifications. Once locked, updates and deletions are restricted. - **Unlock a Task:** `PUT /tasks/{taskId}/unlock` - - **Parameters:** - - `taskId` (integer, required): The ID of the task to unlock. - - **Description:** Unlocks a task, allowing updates and modifications. + - **Parameters:** + - `taskId` (integer, required): The ID of the task to unlock. + - **Description:** Unlocks a task, allowing updates and modifications. - **Get All Admins:** `GET /admins` - - **Response Body:** + - **Response Body:** - ```json - [ - { - "accountId": 1, - "userName": "Admin Name", - "userEmail": "admin@example.com" - }, - { - "accountId": 2, - "userName": "Admin 2", - "userEmail": "admin_2@example.com" - } - ] - ``` + ```json + [ + { + "accountId": 1, + "userName": "Admin Name", + "userEmail": "admin@example.com" + }, + { + "accountId": 2, + "userName": "Admin 2", + "userEmail": "admin_2@example.com" + } + ] + ``` - **Description:** Returns a list of every admin in the database. - **Get All Team Members:** `GET /team-members` - - **Response Body:** - - ```json - [ - { - "accountId": 2, - "userName": "Team Member", - "userEmail": "teammember@example.com", - "role": "TEAM_MEMBER", - "teamLead": true, - "teamLeadOfId": [1, 2], - "teamLeadOfName": ["Team One", "Team Two"] - }, - { - "accountId": 3, - "userName": "Team Member3", - "userEmail": "teammember3@example.com", - "role": "ADMIN", - "teamLead": false, - "teamLeadOfId": [], - "teamLeadOfName": [] - } - ] + - **Response Body:** + + ```json + [ + { + "accountId": 2, + "userName": "Team Member", + "userEmail": "teammember@example.com", + "role": "TEAM_MEMBER", + "teamLead": true, + "teamLeadOfId": [1, 2], + "teamLeadOfName": ["Team One", "Team Two"] + }, + { + "accountId": 3, + "userName": "Team Member3", + "userEmail": "teammember3@example.com", + "role": "ADMIN", + "teamLead": false, + "teamLeadOfId": [], + "teamLeadOfName": [] + } + ] ``` - **Description:** Returns a list of every team member in the database. - **Get All Teams:** `GET /all-teams` - - **Response Body:** + - **Response Body:** - ```json - [ - { - "teamId": 1, - "teamName": "Development Team" - }, - { - "teamId": 2, - "teamName": "Marketing Team" - } - ] - ``` + ```json + [ + { + "teamId": 1, + "teamName": "Development Team" + }, + { + "teamId": 2, + "teamName": "Marketing Team" + } + ] + ``` - - **Description:** Returns a list of every team in the database. + - **Description:** Returns a list of every team in the database. - **Get Admin by ID** `GET /{adminId}` - - **Parameters:** - - `adminId` (integer, required): The ID of the admin being retrieved. - - **Response Body:** + - **Parameters:** + - `adminId` (integer, required): The ID of the admin being retrieved. + - **Response Body:** - ```json - { - "accountId": 1, - "userName": "Admin Name", - "userEmail": "admin@example.com" - } - ``` + ```json + { + "accountId": 1, + "userName": "Admin Name", + "userEmail": "admin@example.com" + } + ``` - - **Description:** Returns the id, name, and email of the requested admin. + - **Description:** Returns the id, name, and email of the requested admin. - **Get Team Member by ID** `GET /team-member/{teamMemberId}` - - **Parameters:** - - `teamMemberId` (integer, required): The ID of the team member being retrieved. - - **Response Body:** - ```json - { - "accountId": 1, - "userName": "Team Member Name", - "userEmail": "teamMember@example.com" - } - ``` - - **Description:** Returns the id, name, and email of the requested team member. + - **Parameters:** + - `teamMemberId` (integer, required): The ID of the team member being retrieved. + - **Response Body:** + ```json + { + "accountId": 1, + "userName": "Team Member Name", + "userEmail": "teamMember@example.com" + } + ``` + - **Description:** Returns the id, name, and email of the requested team member. --- @@ -319,52 +319,52 @@ All API requests should be made to the following base URL (Spring Boot's default - **Login:** `POST /login` - - **Description:** Logs a user in. - - **Request Body:** + - **Description:** Logs a user in. + - **Request Body:** - ```json - { - "teamMemberId": 1, - "password": "password" - } - ``` + ```json + { + "teamMemberId": 1, + "password": "password" + } + ``` - - **Response Body:** + - **Response Body:** - ```json - { - "id": 1, - "name": "Test User", - "role": "TEAM_MEMBER" - } - ``` + ```json + { + "id": 1, + "name": "Test User", + "role": "TEAM_MEMBER" + } + ``` - **IsAdmin:** `POST /is-admin` - - **Description:** Checks if a user is an admin. - - **Request Body:** - ```json - { - "teamMemberId": 1 - } - ``` - - **Response Body:\*** - ```json - { - "role": "TEAM_MEMBER" - } - ``` - - **Response Body:** - ```json - { - "adminId": 2 - } - ``` - - **Response Body:\*** - ```json - { - "role": "ADMIN" - } - ``` + - **Description:** Checks if a user is an admin. + - **Request Body:** + ```json + { + "teamMemberId": 1 + } + ``` + - **Response Body:** + ```json + { + "role": "TEAM_MEMBER" + } + ``` + - **Response Body:** + ```json + { + "adminId": 2 + } + ``` + - **Response Body:** + ```json + { + "role": "ADMIN" + } + ``` --- @@ -375,15 +375,13 @@ All API requests should be made to the following base URL (Spring Boot's default ### Endpoints - **Assign a Team Member to a Task:** `POST /{teamMemberId}/task/{taskId}` - - - **Description:** Assigns a team member to a task. + - **Description:** Assigns a team member to a task. - **Unassign a Team Member from a Task:** `DELETE /{teamMemberId}/task/{taskId}` - - - **Description:** Unassigns a team member from a task. + - **Description:** Unassigns a team member from a task. - **Check if Assigned:** `GET /{teamMemberId}/task/{taskId}` - - **Description:** Returns a boolean of whether a team member is currently assigned to a task. + - **Description:** Returns a boolean of whether a team member is currently assigned to a task. --- @@ -394,12 +392,10 @@ All API requests should be made to the following base URL (Spring Boot's default ### Endpoints - **Add a Member to a Team:** `POST /{teamMemberId}/team/{teamId}` - - - **Description:** Adds a team member to a team. + - **Description:** Adds a team member to a team. - **Remove a Member from a Team:** `DELETE /{teamMemberId}/team/{teamId}` - - - **Description:** Removes a team member from a team. + - **Description:** Removes a team member from a team. - **Check if a Member is assigned to a Team:** `GET /{teamMemberId}/team/{teamId}` - **Description:** Returns a boolean of whether a team member is assigned to a team. @@ -424,71 +420,73 @@ All API requests should be made to the following base URL (Spring Boot's default - **Create a Team:** `POST` - - **Request Body:** + - **Request Body:** - ```json - { + ```json + { "teamId": 1, "teamName": "Development Team", "teamLeadId": 1001 - } - ``` + } + ``` - - **Response Body:** + - **Response Body:** - ```json - { + ```json + { "teamId": 1, "teamName": "Development Team", "teamLeadId": 1001 - } - ``` + } + ``` - - **Description:** Creates a team in the database. + - **Description:** Creates a team in the database. - **Delete a Team:** `DELETE /{teamId}` - **Description:** Deletes a team from the database. -- **Change Team Lead:** `PUT /{teamId}/change-lead` - - **Request Body:** +- **Change Team Lead:** `PUT /{teamId}/change-lead` + - **Request Body:** - ```json - { - "teamId": 1, - "teamName": "Updated Team Name", - "teamLeadId": 1002 - } - ``` + ```json + { + "teamId": 1, + "teamName": "Updated Team Name", + "teamLeadId": 1002 + } + ``` - - **Response Body:** + - **Response Body:** - ```json - { - "teamId": 1, - "teamName": "Updated Team Name", - "teamLeadId": 1002 - } - ``` + ```json + { + "teamId": 1, + "teamName": "Updated Team Name", + "teamLeadId": 1002 + } + ``` - - **Description:** Updates the team lead for a specified team by assigning a different team member. + - **Description:** Updates the team lead for a specified team by assigning a different team member. - **Get Team Members:** `GET /{teamId}/members` - - **Response Body:** - ```json - [ - { - "accountId": 1, - "userName": "John Doe", - "userEmail": "john@example.com" - }, - { - "accountId": 2, - "userName": "Jane Smith", - "userEmail": "jane@example.com" - } - ] - ``` - - **Description:** Returns a list of every team member in a team. Each list item contains the team member's ID, name, and email. + - **Response Body:** + ```json + [ + { + "accountId": 1, + "userName": "John Doe", + "userEmail": "john@example.com", + "role": "ADMIN" + }, + { + "accountId": 2, + "userName": "Jane Smith", + "userEmail": "jane@example.com", + "role": "TEAM_MEMBER" + } + ] + ``` + - **Description:** Returns a list of every team member in a team. Each list item contains the team member's ID, name, and email. --- @@ -527,7 +525,6 @@ All API requests should be made to the following base URL (Spring Boot's default - **Description:** Creates a task in the database. - **Delete a Task:** `DELETE /{taskId}` - - **Description:** Deletes a task from the database. - **Edit a Task:** `PUT /{taskId}` @@ -559,65 +556,55 @@ All API requests should be made to the following base URL (Spring Boot's default - **Assign Member to a Task:** `POST /{taskId}/assign/{teamMemberId}` - - **Response Body:** + - **Response Body:** - ```json - { - "isAssignedId": 1, - "taskId": 4, - "teamMemberId": 2, - "teamId": 3 - } - ``` + ```json + { + "isAssignedId": 1, + "taskId": 4, + "teamMemberId": 2, + "teamId": 3 + } + ``` - - **Description:** Assigns a member (admin or team member) to a task. + - **Description:** Assigns a member (admin or team member) to a task. - **Change Password:** `POST /team-members/{teamMemberId}/change-password` - - **Request Body:** + - **Request Body:** - ```json - { - "oldPassword": "oldPass123", - "newPassword": "newPass456" - } - ``` + ```json + { + "oldPassword": "oldPass123", + "newPassword": "newPass456" + } + ``` - - **Description:** Updates the password field for a team member. + - **Description:** Updates the password field for a team member. - **Get All Teams for a Team Member:** `GET /{teamMemberId}/teams` - - **Response Body:** + - **Response Body:** - ```json - [ - { - "teamId": 1, - "teamName": "Development Team" - }, - { - "teamId": 2, - "teamName": "Marketing Team" - } - ] - ``` + ```json + [ + { + "teamId": 1, + "teamName": "Development Team" + }, + { + "teamId": 2, + "teamName": "Marketing Team" + } + ] + ``` - - **Description:** Returns a list of all the teams a team member is a part of. + - **Description:** Returns a list of all the teams a team member is a part of. - **Get Assigned Tasks For a Team Member:** `GET /{teamMemberId}/tasks` - - **Response Body:** - ```json - [ - { - "taskId": 101, - "title": "Implement Login API", - "description": "Develop the login functionality for the app", - "isLocked": false, - "status": "In Progress", - "dateCreated": "2024-03-04", - "dueDate": "2024-04-01", - "teamId": 1, - "assignedMembers": [ + - **Response Body:** + ```json + [ { "taskId": 101, "title": "Implement Login API", @@ -627,18 +614,42 @@ All API requests should be made to the following base URL (Spring Boot's default "dateCreated": "2024-03-04", "dueDate": "2024-04-01", "teamId": 1, - "priority": "HIGH", "assignedMembers": [ { - "accountId": 1, - "userName": "Name", - "userEmail": "email@ex.com" + "taskId": 101, + "title": "Implement Login API", + "description": "Develop the login functionality for the app", + "isLocked": false, + "status": "In Progress", + "dateCreated": "2024-03-04", + "dueDate": "2024-04-01", + "teamId": 1, + "priority": "HIGH", + "assignedMembers": + [ + { + "accountId": 1, + "userName": "Name", + "userEmail": "email@ex.com" + }, + { + "accountId": 2, + "userName": "Name2", + "userEmail": "email_2@ex.com" + } + ] }, { - "accountId": 2, - "userName": "Name2", - "userEmail": "email_2@ex.com" + "taskId": 102, + "title": "Design Homepage", + "description": "Create a wireframe for the homepage", + "isLocked": true, + "status": "Pending", + "dueDate": null, + "teamId": 2, + "priority": "MEDIUM", + "assignedMembers": [] } ] }, @@ -650,24 +661,11 @@ All API requests should be made to the following base URL (Spring Boot's default "status": "Pending", "dueDate": null, "teamId": 2, - "priority": "MEDIUM", "assignedMembers": [] } - ] - }, - { - "taskId": 102, - "title": "Design Homepage", - "description": "Create a wireframe for the homepage", - "isLocked": true, - "status": "Pending", - "dueDate": null, - "teamId": 2, - "assignedMembers": [] - } - ] - ``` - - **Description:** Returns a list of every task a team member is assigned to. + ] + ``` + - **Description:** Returns a list of every task a team member is assigned to. ## **NotificationController** @@ -677,119 +675,119 @@ All API requests should be made to the following base URL (Spring Boot's default - **Get Read Notifications:** `GET /{teamMemberId}/read-notifs` - - **Response Body:** - - ```json - { - [ - { - "notificationId": 1, - "message": "Task Updated", - "type": "TASK_EDITED", - "isRead": true, - "createdAt": "2024-03-15T10:30:00", - "teamMemberId": 101, - "taskId": 5 - }, - { - "notificationId": 4, - "message": "Project Deadline Extended", - "type": "TASK_DUE_DATE_EDITED", - "isRead": true, - "createdAt": "2024-03-16T14:45:00", - "teamMemberId": 101, - "taskId": 8 - } - ] - } - ``` + - **Response Body:** - - **Description:** Returns a list of all read notifications for a specific team member. + ```json + { + [ + { + "notificationId": 1, + "message": "Task Updated", + "type": "TASK_EDITED", + "isRead": true, + "createdAt": "2024-03-15T10:30:00", + "teamMemberId": 101, + "taskId": 5 + }, + { + "notificationId": 4, + "message": "Project Deadline Extended", + "type": "TASK_DUE_DATE_EDITED", + "isRead": true, + "createdAt": "2024-03-16T14:45:00", + "teamMemberId": 101, + "taskId": 8 + } + ] + } + ``` + + - **Description:** Returns a list of all read notifications for a specific team member. - **Get Unread Notifications:** `GET /{teamMemberId}/unread-notifs` - - **Response Body:** - - ```json - { - [ - { - "notificationId": 1, - "message": "Task Updated", - "type": "TASK_EDITED", - "isRead": true, - "createdAt": "2024-03-15T10:30:00", - "teamMemberId": 101, - "taskId": 5 - }, - { - "notificationId": 4, - "message": "Project Deadline Extended", - "type": "TASK_DUE_DATE_EDITED", - "isRead": true, - "createdAt": "2024-03-16T14:45:00", - "teamMemberId": 101, - "taskId": 8 - } - ] - } - ``` + - **Response Body:** + + ```json + { + [ + { + "notificationId": 1, + "message": "Task Updated", + "type": "TASK_EDITED", + "isRead": true, + "createdAt": "2024-03-15T10:30:00", + "teamMemberId": 101, + "taskId": 5 + }, + { + "notificationId": 4, + "message": "Project Deadline Extended", + "type": "TASK_DUE_DATE_EDITED", + "isRead": true, + "createdAt": "2024-03-16T14:45:00", + "teamMemberId": 101, + "taskId": 8 + } + ] + } + ``` - - **Description:** Returns a list of all unread notifications for a specific team member. + - **Description:** Returns a list of all unread notifications for a specific team member. - **Mark Notification as Read:** `GET /{notificationId}/mark-as-read` - - **Response Body:** + - **Response Body:** - ```json - { - "message": "Notification marked as read." - } - ``` + ```json + { + "message": "Notification marked as read." + } + ``` - - **Description:** Marks a notification as read. + - **Description:** Marks a notification as read. - **Mark Notification as Unread:** `GET /{notificationId}/mark-as-unread` - - **Response Body:** + - **Response Body:** - ```json - { - "message": "Notification marked as unread." - } - ``` + ```json + { + "message": "Notification marked as unread." + } + ``` - - **Description:** Marks a notification as unread. + - **Description:** Marks a notification as unread. -- **Delete Notification:** `DELETE /{notificationId}` - - **Response Status:** - ``` - HTTP/1.1 204 No Content - ``` - - **Description:** Deletes a notification from the database. + - **Delete Notification:** `DELETE /{notificationId}` + - **Response Status:** + ``` + HTTP/1.1 204 No Content + ``` + - **Description:** Deletes a notification from the database. --- ## **Path Variables** - **AdminController** - - `{adminId}` (integer, required): The ID of the admin - - `{teamMemberId}` (integer, required): The ID of the team member - - `{teamId}` (integer, required): The ID of the team - - `{taskId}` (integer, required): The ID of the task + - `{adminId}` (integer, required): The ID of the admin + - `{teamMemberId}` (integer, required): The ID of the team member + - `{teamId}` (integer, required): The ID of the team + - `{taskId}` (integer, required): The ID of the task - **IsAssigned Controller** - - `{teamMemberId}` (integer, required): The ID of the team member - - `{taskId}` (integer, required): The ID of the task + - `{teamMemberId}` (integer, required): The ID of the team member + - `{taskId}` (integer, required): The ID of the task - **IsMemberOfController** - - `{teamMemberId}` (integer, required): The ID of the team member - - `{teamId}` (integer, required): The ID of the team + - `{teamMemberId}` (integer, required): The ID of the team member + - `{teamId}` (integer, required): The ID of the team - **TaskController** - - `{taskId}` (integer, required): The ID of the task + - `{taskId}` (integer, required): The ID of the task - **TeamController** - - `{teamId}` (integer, required): The ID of the team + - `{teamId}` (integer, required): The ID of the team - **TeamMemberController** - - `{taskId}` (integer, required): The ID of the task - - `{teamMemberId}` (integer, required): The ID of the team member + - `{taskId}` (integer, required): The ID of the task + - `{teamMemberId}` (integer, required): The ID of the team member --- @@ -819,18 +817,18 @@ POST /api/admin?name=John Doe&email=john.doe@example.com - **Request Parameters** - - `name` (string, required): The name of the new admin. - - `email` (string, required): The email of the new admin. + - `name` (string, required): The name of the new admin. + - `email` (string, required): The email of the new admin. - **Request Response** -```json -{ - "id": 1, - "name": "John Doe", - "email": "john.doe@example.com" -} -``` + ```json + { + "id": 1, + "name": "John Doe", + "email": "john.doe@example.com" + } + ``` #### **ModifyAdminName** @@ -840,18 +838,18 @@ PUT /api/admin/1/update-name?newName=Jane Doe - **Request Parameters** - - `adminId` (integer, required): The ID of the admin changing the members name. - - `newName` (string, required): The new name of the member. + - `adminId` (integer, required): The ID of the admin changing the members name. + - `newName` (string, required): The new name of the member. - **Response Body** -```json -{ - "id": 1, - "name": "Jane Doe", - "email": "john.doe@example.com" -} -``` + ```json + { + "id": 1, + "name": "Jane Doe", + "email": "john.doe@example.com" + } + ``` #### **DeleteAdmin** @@ -860,8 +858,8 @@ DELETE /api/admin/1 ``` - **Notes:** - - No request body required. - - No response body returned. + - No request body required. + - No response body returned. #### **CreateTask** @@ -871,24 +869,24 @@ POST /api/tasks?title=The Task Title&description=This is the description, it cou - **Request Parameters** - - `title` (string, required): The title of the new task. - - `description` (string, required): The description of the new task. - - `isLocked` (boolean, required): A boolean of whether the new task is locked or not. - - `status` (string, required): A string of the current status of the task. - - `teamId` (integer, required): The ID of the team being assigned to the task. + - `title` (string, required): The title of the new task. + - `description` (string, required): The description of the new task. + - `isLocked` (boolean, required): A boolean of whether the new task is locked or not. + - `status` (string, required): A string of the current status of the task. + - `teamId` (integer, required): The ID of the team being assigned to the task. - **Response Body** -```json -{ - "taskId": 4, - "title": "Design Database Schema", - "description": "Create the database structure.", - "isLocked": false, - "status": "To-Do", - "teamId": 3 -} -``` + ```json + { + "taskId": 4, + "title": "Design Database Schema", + "description": "Create the database structure.", + "isLocked": false, + "status": "To-Do", + "teamId": 3 + } + ``` --- @@ -900,53 +898,53 @@ Below are examples of some API requests and responses using Cypress. - **AdminController** - - **CreateAdmin** - - ```javascript - cy.request({ - method: "POST", - url: "http://localhost:8080/api/admin", - qs: { - name: "John Doe", - email: "john@example.com", - }, - }).then((response) => { - expect(response.status).to.eq(200); - expect(response.body.name).to.eq("John Doe"); - }); - ``` + - **CreateAdmin** - - **DeleteAdmin** - - ```javascript - cy.request({ - method: "DELETE", - url: "http://localhost:8080/api", - qs: { - adminId: 1, - }, - }).then((response) => { - expect(response.status).to.eq(204); - }); - ``` + ```javascript + cy.request({ + method: "POST", + url: "http://localhost:8080/api/admin", + qs: { + name: "John Doe", + email: "john@example.com", + }, + }).then((response) => { + expect(response.status).to.eq(200); + expect(response.body.name).to.eq("John Doe"); + }); + ``` -- **TeamMemberController** + - **DeleteAdmin** - - **Assign Member To Task** + ```javascript + cy.request({ + method: "DELETE", + url: "http://localhost:8080/api", + qs: { + adminId: 1, + }, + }).then((response) => { + expect(response.status).to.eq(204); + }); + ``` - ```javascript - const taskId = 5; - const teamMemberId = 7; + - **TeamMemberController** - cy.request({ - method: "POST", - url: "http://localhost:8080/api/tasks/${taskId}/assign/${teamMemberId}", - }).then((response) => { - expect(response.status).to.eq(200); - expect(response.body).to.have.property("taskId", taskId); - expect(response.body).to.have.property("teamMemberId", teamMemberId); - }); - ``` + - **Assign Member To Task** + + ```javascript + const taskId = 5; + const teamMemberId = 7; + + cy.request({ + method: "POST", + url: "http://localhost:8080/api/tasks/${taskId}/assign/${teamMemberId}", + }).then((response) => { + expect(response.status).to.eq(200); + expect(response.body).to.have.property("taskId", taskId); + expect(response.body).to.have.property("teamMemberId", teamMemberId); + }); + ``` --- @@ -985,10 +983,10 @@ Follow these practices to ensure efficiency and accuracy with all API requests. ## Example Error Response -```json -{ - "message": "Resource not found", - "error": "NotFoundException", - "statusCode": 404 -} -``` + ```json + { + "message": "Resource not found", + "error": "NotFoundException", + "statusCode": 404 + } + ``` \ No newline at end of file diff --git a/backend/task-manager/src/main/java/com/example/task_manager/service/TeamService.java b/backend/task-manager/src/main/java/com/example/task_manager/service/TeamService.java index e94ac9b2..72ea5aec 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/service/TeamService.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/service/TeamService.java @@ -96,7 +96,8 @@ public TeamDTO changeTeamLead(int teamId, String teamName, int teamLeadId) { */ public List getTeamMembers(int teamId) { Team team = teamRepository.findById(teamId) - .orElseThrow(() -> new RuntimeException("Team not found with ID: " + teamId)); + .orElseThrow(() -> new RuntimeException("Team not found with ID: " + teamId)); + return isMemberOfRepository.findMembersByTeamId(teamId).stream() .map(IsMemberOf::getTeamMember) .map(this::convertToDTO) @@ -118,7 +119,11 @@ private TeamDTO convertToDTO(Team team) { * Converts a TeamMember entity to a TeamMemberDTO. */ private TeamMemberDTO convertToDTO(TeamMember teamMember) { - return new TeamMemberDTO(teamMember.getAccountId(), teamMember.getUserName(), teamMember.getUserEmail(), teamMember.getRole()); + return new TeamMemberDTO( + teamMember.getAccountId(), + teamMember.getUserName(), + teamMember.getUserEmail(), + teamMember.getRole()); } } From 5dce14153c18a02fda5309c21c91e35656863aeb Mon Sep 17 00:00:00 2001 From: timmi Date: Wed, 26 Mar 2025 13:10:43 -0700 Subject: [PATCH 2/5] Adding whether the team member is the teamLead or not. --- .../task_manager/DTO/TeamMemberInTeamDTO.java | 60 +++++++++++++++++++ .../task_manager/service/TeamService.java | 42 ++++++++++--- 2 files changed, 93 insertions(+), 9 deletions(-) create mode 100644 backend/task-manager/src/main/java/com/example/task_manager/DTO/TeamMemberInTeamDTO.java diff --git a/backend/task-manager/src/main/java/com/example/task_manager/DTO/TeamMemberInTeamDTO.java b/backend/task-manager/src/main/java/com/example/task_manager/DTO/TeamMemberInTeamDTO.java new file mode 100644 index 00000000..ad0c7458 --- /dev/null +++ b/backend/task-manager/src/main/java/com/example/task_manager/DTO/TeamMemberInTeamDTO.java @@ -0,0 +1,60 @@ +package com.example.task_manager.DTO; + +import com.example.task_manager.enums.RoleType; + +public class TeamMemberInTeamDTO { + private int accountId; + private String userName; + private String userEmail; + private RoleType role; + private boolean isTeamLead; + + public TeamMemberInTeamDTO(int accountId, String userName, String userEmail, RoleType role, boolean isTeamLead) { + this.accountId = accountId; + this.userName = userName; + this.userEmail = userEmail; + this.role = role; + this.isTeamLead = isTeamLead; + } + + //getters and setters + public int getAccountId() { + return accountId; + } + + public void setAccountId(int accountId) { + this.accountId = accountId; + } + + public String getUserName() { + return userName; + } + + public void setUserName(String userName) { + this.userName = userName; + } + + public String getUserEmail() { + return userEmail; + } + + public void setUserEmail(String userEmail) { + this.userEmail = userEmail; + } + + public RoleType getRole() { + return role; + } + + public void setRole(RoleType role) { + this.role = role; + } + + public boolean isIsTeamLead() { + return isTeamLead; + } + + public void setIsTeamLead(boolean isTeamLead) { + this.isTeamLead = isTeamLead; + } +} diff --git a/backend/task-manager/src/main/java/com/example/task_manager/service/TeamService.java b/backend/task-manager/src/main/java/com/example/task_manager/service/TeamService.java index a8def1cd..3983715c 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/service/TeamService.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/service/TeamService.java @@ -8,6 +8,7 @@ import com.example.task_manager.DTO.TaskDTO; import com.example.task_manager.DTO.TeamDTO; import com.example.task_manager.DTO.TeamMemberDTO; +import com.example.task_manager.DTO.TeamMemberInTeamDTO; import com.example.task_manager.entity.IsAssigned; import com.example.task_manager.entity.IsMemberOf; import com.example.task_manager.entity.Task; @@ -105,14 +106,27 @@ public TeamDTO changeTeamLead(int teamId, String teamName, int teamLeadId) { * @param teamId The ID of the team. * @return A list of TeamMembers belonging to the team. */ - public List getTeamMembers(int teamId) { + public List getTeamMembers(int teamId) { Team team = teamRepository.findById(teamId) .orElseThrow(() -> new RuntimeException("Team not found with ID: " + teamId)); - + + int teamLeadId = team.getTeamLead().getAccountId(); + return isMemberOfRepository.findMembersByTeamId(teamId).stream() - .map(IsMemberOf::getTeamMember) - .map(this::convertToDTO) - .collect(Collectors.toList()); + .map(isMember -> { + TeamMember teamMember = isMember.getTeamMember(); + boolean isTeamLead; + + if (teamMember.getAccountId() == teamLeadId) { + isTeamLead = true; + } + else { + isTeamLead = false; + } + + return convertToDTO(teamMember, isTeamLead); + }) + .collect(Collectors.toList()); } /* @@ -168,11 +182,21 @@ private TeamDTO convertToDTO(Team team) { /** * Converts a TeamMember entity to a TeamMemberDTO. */ - private TeamMemberDTO convertToDTO(TeamMember teamMember) { + private TeamMemberDTO convertToDTO(TeamMember teamMember) { return new TeamMemberDTO( - teamMember.getAccountId(), - teamMember.getUserName(), + teamMember.getAccountId(), + teamMember.getUserName(), + teamMember.getUserEmail(), + teamMember.getRole()); + } + + private TeamMemberInTeamDTO convertToDTO(TeamMember teamMember, boolean isTeamLead) { + return new TeamMemberInTeamDTO( + teamMember.getAccountId(), + teamMember.getUserName(), teamMember.getUserEmail(), - teamMember.getRole()); + teamMember.getRole(), + isTeamLead + ); } } From cfa1c2b338b26d6e62c824c7f5e80976ab26e5ec Mon Sep 17 00:00:00 2001 From: timmi Date: Wed, 26 Mar 2025 13:24:10 -0700 Subject: [PATCH 3/5] Updating tests to use TeamMemberInTeamDTO, which returns a boolean of whether they are a team lead or not. Added new DTO class tests. --- .../controller/TeamController.java | 4 +- .../DTO_tests/TeamMemberInTeamDTOTest.java | 37 +++++++++++++++++++ .../controller_tests/TeamControllerTest.java | 6 ++- .../service_tests/TeamServiceTest.java | 8 ++-- 4 files changed, 48 insertions(+), 7 deletions(-) create mode 100644 backend/task-manager/src/test/java/com/example/task_manager/DTO_tests/TeamMemberInTeamDTOTest.java diff --git a/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamController.java b/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamController.java index 65b2b2b9..cdf8d419 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamController.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/controller/TeamController.java @@ -1,7 +1,6 @@ package com.example.task_manager.controller; import com.example.task_manager.DTO.TeamDTO; -import com.example.task_manager.DTO.TeamMemberDTO; import com.example.task_manager.DTO.TeamRequestDTO; import com.example.task_manager.service.TeamService; @@ -11,6 +10,7 @@ import java.util.List; import com.example.task_manager.DTO.TaskDTO; +import com.example.task_manager.DTO.TeamMemberInTeamDTO; @RestController @RequestMapping("/api/teams") @@ -57,7 +57,7 @@ public ResponseEntity changeTeamLead(@PathVariable int teamId, @RequestBody T // Get Team Members @GetMapping("/{teamId}/members") - public ResponseEntity> getTeamMembers(@PathVariable int teamId) { + public ResponseEntity> getTeamMembers(@PathVariable int teamId) { try { return ResponseEntity.ok(teamService.getTeamMembers(teamId)); } catch (RuntimeException e) { diff --git a/backend/task-manager/src/test/java/com/example/task_manager/DTO_tests/TeamMemberInTeamDTOTest.java b/backend/task-manager/src/test/java/com/example/task_manager/DTO_tests/TeamMemberInTeamDTOTest.java new file mode 100644 index 00000000..64e096ee --- /dev/null +++ b/backend/task-manager/src/test/java/com/example/task_manager/DTO_tests/TeamMemberInTeamDTOTest.java @@ -0,0 +1,37 @@ +package com.example.task_manager.DTO_tests; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import org.junit.jupiter.api.Test; + +import com.example.task_manager.DTO.TeamMemberInTeamDTO; +import com.example.task_manager.enums.RoleType; + +public class TeamMemberInTeamDTOTest { + @Test + void testDTOConstructorAndGetters() { + TeamMemberInTeamDTO dto = new TeamMemberInTeamDTO(1, "Alice Johnson", "alice@example.com", RoleType.TEAM_MEMBER, + true); + + assertEquals(1, dto.getAccountId()); + assertEquals("Alice Johnson", dto.getUserName()); + assertEquals("alice@example.com", dto.getUserEmail()); + assertTrue(dto.isIsTeamLead()); + } + + @Test + void testDTOSetters() { + TeamMemberInTeamDTO dto = new TeamMemberInTeamDTO(1, "Alice Johnson", "alice@example.com", RoleType.TEAM_MEMBER, false); + + dto.setAccountId(2); + dto.setUserName("Updated Name"); + dto.setUserEmail("updated@example.com"); + dto.setIsTeamLead(true); + + assertEquals(2, dto.getAccountId()); + assertEquals("Updated Name", dto.getUserName()); + assertEquals("updated@example.com", dto.getUserEmail()); + assertTrue(dto.isIsTeamLead()); + } +} diff --git a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamControllerTest.java b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamControllerTest.java index 7ae2c18e..8b2ef5d2 100644 --- a/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamControllerTest.java +++ b/backend/task-manager/src/test/java/com/example/task_manager/controller_tests/TeamControllerTest.java @@ -31,6 +31,7 @@ import java.util.Collections; import java.util.List; +import com.example.task_manager.DTO.TeamMemberInTeamDTO; import com.example.task_manager.entity.TeamMember; @WebMvcTest(TeamController.class) @@ -116,9 +117,10 @@ void testGetTeamMembers() throws Exception { String memberName = "John Doe " + teamId; String memberEmail = "john" + teamId + "@example.com"; RoleType role = RoleType.TEAM_MEMBER; + boolean isTeamLead = false; - TeamMemberDTO mockTeamMember = new TeamMemberDTO(teamMemberId, memberName, memberEmail, role); - List teamMembers = Collections.singletonList(mockTeamMember); + TeamMemberInTeamDTO mockTeamMember = new TeamMemberInTeamDTO(teamMemberId, memberName, memberEmail, role, isTeamLead); + List teamMembers = Collections.singletonList(mockTeamMember); when(teamService.getTeamMembers(teamId)).thenReturn(teamMembers); diff --git a/backend/task-manager/src/test/java/com/example/task_manager/service_tests/TeamServiceTest.java b/backend/task-manager/src/test/java/com/example/task_manager/service_tests/TeamServiceTest.java index 2997d601..efac7f92 100644 --- a/backend/task-manager/src/test/java/com/example/task_manager/service_tests/TeamServiceTest.java +++ b/backend/task-manager/src/test/java/com/example/task_manager/service_tests/TeamServiceTest.java @@ -13,12 +13,14 @@ import org.springframework.boot.test.context.SpringBootTest; import com.example.task_manager.DTO.TaskDTO; + import org.springframework.test.context.ActiveProfiles; import jakarta.transaction.Transactional; import com.example.task_manager.DTO.TeamDTO; import com.example.task_manager.DTO.TeamMemberDTO; +import com.example.task_manager.DTO.TeamMemberInTeamDTO; import com.example.task_manager.entity.IsAssigned; import com.example.task_manager.entity.Task; import com.example.task_manager.entity.Team; @@ -89,7 +91,7 @@ void testCreateTeam() { TeamDTO newTeam = teamService.createTeam(teamName, teamLead.getAccountId()); - List members = teamService.getTeamMembers(newTeam.getTeamId()); + List members = teamService.getTeamMembers(newTeam.getTeamId()); assertTrue(members.stream().anyMatch(member -> member.getAccountId() == teamLead.getAccountId()), "Team lead should be included in the team's member list." @@ -177,7 +179,7 @@ void testGetTeamMembers() { isMemberOfService.addMemberToTeam(member.getAccountId(), team.getTeamId()); - List teamMembers = teamService.getTeamMembers(team.getTeamId()); + List teamMembers = teamService.getTeamMembers(team.getTeamId()); assertNotNull(teamMembers); assertFalse(teamMembers.isEmpty()); @@ -209,7 +211,7 @@ void testGetMembersOfTeamWithNoMembers() { TeamMember teamLead = createUniqueTeamMember("Lead"); Team team = createUniqueTeam(teamLead); - List members = teamService.getTeamMembers(team.getTeamId()); + List members = teamService.getTeamMembers(team.getTeamId()); assertTrue(members.isEmpty()); } From 4b27a06e29d66f6d2bac0f0016d7539ed03d9b60 Mon Sep 17 00:00:00 2001 From: timmi Date: Wed, 26 Mar 2025 13:49:55 -0700 Subject: [PATCH 4/5] Updating API documentation to include the isTeamLead field. --- API_DOCUMENTATION.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/API_DOCUMENTATION.md b/API_DOCUMENTATION.md index dd55a327..4326619b 100644 --- a/API_DOCUMENTATION.md +++ b/API_DOCUMENTATION.md @@ -433,9 +433,7 @@ All API requests should be made to the following base URL (Spring Boot's default ### Endpoints - **Create a Team:** `POST` - - **Request Body:** - ```json { "teamId": 1, @@ -443,9 +441,7 @@ All API requests should be made to the following base URL (Spring Boot's default "teamLeadId": 1001 } ``` - - **Response Body:** - ```json { "teamId": 1, @@ -453,7 +449,6 @@ All API requests should be made to the following base URL (Spring Boot's default "teamLeadId": 1001 } ``` - - **Description:** Creates a team in the database. - **Delete a Team:** `DELETE /{teamId}` @@ -490,17 +485,19 @@ All API requests should be made to the following base URL (Spring Boot's default "accountId": 1, "userName": "John Doe", "userEmail": "john@example.com", - "role": "ADMIN" + "role": "ADMIN", + "isTeamLead": true }, { "accountId": 2, "userName": "Jane Smith", "userEmail": "jane@example.com", - "role": "TEAM_MEMBER" + "role": "TEAM_MEMBER", + "isTeamLead": false } ] ``` - - **Description:** Returns a list of every team member in a team. Each list item contains the team member's ID, name, and email. + - **Description:** Returns a list of every team member in a team. Each list item contains the team member's ID, name, email, role, and a boolean of whether they are the team lead. - **Get Team Tasks:** `GET /{teamId}/tasks` - **Response Body:** From a9c3a197538b0696b019175e486f7ac56fa59148 Mon Sep 17 00:00:00 2001 From: timmi Date: Thu, 27 Mar 2025 18:32:19 -0700 Subject: [PATCH 5/5] Making teamLead allowed to be null. --- .../task_manager/service/TeamMemberService.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/backend/task-manager/src/main/java/com/example/task_manager/service/TeamMemberService.java b/backend/task-manager/src/main/java/com/example/task_manager/service/TeamMemberService.java index 0aace4d9..fa16184f 100644 --- a/backend/task-manager/src/main/java/com/example/task_manager/service/TeamMemberService.java +++ b/backend/task-manager/src/main/java/com/example/task_manager/service/TeamMemberService.java @@ -316,10 +316,12 @@ public List getTeamsForMember(int teamMemberId) { .orElseThrow(() -> new RuntimeException("Team Member not found with ID: " + teamMemberId)); return teamMember.getTeams().stream() - .map(isMemberOf -> new TeamDTO( - isMemberOf.getTeam().getTeamId(), - isMemberOf.getTeam().getTeamName(), - isMemberOf.getTeam().getTeamLead().getAccountId())) + .map(isMemberOf -> { + Team team = isMemberOf.getTeam(); + TeamMember lead = team.getTeamLead(); + int leadId = (lead != null) ? lead.getAccountId() : -1; // 👈 sentinel for no lead + return new TeamDTO(team.getTeamId(), team.getTeamName(), leadId); + }) .collect(Collectors.toList()); }