diff --git a/README.md b/README.md index 1b5b081..6f3edd0 100644 --- a/README.md +++ b/README.md @@ -100,3 +100,4 @@ base url: `http://localhost:3000` - Create a new task: `POST /api/organization/:organizationId/team/:teamId/project/:projectId/task/create` - Update a task: `PUT /api/organization/:organizationId/team/:teamId/project/:projectId/task/:taskId` +- Update the task priority: `PATCH /api/organization/:organizationId/team/:teamId/project/:projectId/task/:taskId/priority` diff --git a/src/controllers/task.controller.js b/src/controllers/task.controller.js index 2ee2373..5dc93b7 100644 --- a/src/controllers/task.controller.js +++ b/src/controllers/task.controller.js @@ -545,3 +545,102 @@ export const updateTask = async (req, res, next) => { next(error); } }; + +/** + * @desc Update the task priority + * @route /api/organization/:organizationId/team/:teamId/project/:projectId/task/:taskId/priority + * @method PATCH + * @access private + */ +export const updateTaskPriority = async (req, res, next) => { + try { + const { organizationId, teamId, projectId, taskId } = req.params; + const { priority } = req.body; + const user = req.user; + + // Validate priority + if (!priority || !['HIGH', 'MEDIUM', 'LOW'].includes(priority)) { + return res.status(400).json({ + success: false, + message: 'Valid priority (HIGH, MEDIUM, LOW) is required', + }); + } + + // Check if organization exists + const orgCheck = await checkOrganization(organizationId); + if (!orgCheck.success) { + return res.status(404).json({ + success: false, + message: orgCheck.message, + }); + } + + // Check if team exists + const teamCheck = await checkTeam(teamId, organizationId); + if (!teamCheck.success) { + return res.status(404).json({ + success: false, + message: teamCheck.message, + }); + } + + // Check if project exists + const projectCheck = await checkProject(projectId, teamId, organizationId); + if (!projectCheck.success) { + return res.status(404).json({ + success: false, + message: projectCheck.message, + }); + } + + // Check if task exists and belongs to the project + const task = await prisma.task.findFirst({ + where: { + id: taskId, + projectId, + deletedAt: null, + }, + }); + + if (!task) { + return res.status(404).json({ + success: false, + message: 'Task not found or does not belong to the specified project', + }); + } + + // Check task permissions + const permissionsCheck = checkTaskPermissions( + user, + orgCheck.organization, + teamCheck.team, + projectCheck.project, + 'update priority', + ); + + if (!permissionsCheck.success) { + return res.status(403).json({ + success: false, + message: permissionsCheck.message, + }); + } + + // Update task priority + const updatedTask = await prisma.task.update({ + where: { id: taskId }, + data: { + priority, + updatedAt: new Date(), + lastModifiedBy: user.id, + }, + }); + + return res.status(200).json({ + success: true, + message: 'Task priority updated successfully', + task: updatedTask, + }); + } catch (error) { + next(error); + } +}; diff --git a/src/docs/swagger.json b/src/docs/swagger.json index 322d3b3..c92e8fd 100644 --- a/src/docs/swagger.json +++ b/src/docs/swagger.json @@ -4883,6 +4883,161 @@ } } } + }, + "/api/organization/{organizationId}/team/{teamId}/project/{projectId}/task/{taskId}/priority": { + "patch": { + "tags": ["Task"], + "summary": "Update task priority", + "description": "Updates the priority of an existing task within a specific project, team, and organization. Requires appropriate permissions.", + "security": [{ "BearerAuth": [] }], + "parameters": [ + { + "name": "organizationId", + "in": "path", + "required": true, + "description": "ID of the organization", + "schema": { "type": "string" } + }, + { + "name": "teamId", + "in": "path", + "required": true, + "description": "ID of the team", + "schema": { "type": "string" } + }, + { + "name": "projectId", + "in": "path", + "required": true, + "description": "ID of the project", + "schema": { "type": "string" } + }, + { + "name": "taskId", + "in": "path", + "required": true, + "description": "ID of the task to update", + "schema": { "type": "string" } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "type": "object", + "required": ["priority"], + "properties": { + "priority": { + "type": "string", + "enum": ["HIGH", "MEDIUM", "LOW"], + "description": "New priority level for the task", + "example": "MEDIUM" + } + } + } + } + } + }, + "responses": { + "200": { + "description": "Task priority updated successfully", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { "type": "boolean", "example": true }, + "message": { + "type": "string", + "example": "Task priority updated successfully" + }, + "task": { "$ref": "#/components/schemas/Task" } + } + } + } + } + }, + "400": { + "description": "Invalid priority value", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { "type": "boolean", "example": false }, + "message": { + "type": "string", + "example": "Valid priority (HIGH, MEDIUM, LOW) is required" + } + } + } + } + } + }, + "403": { + "description": "Forbidden - insufficient permissions", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { "type": "boolean", "example": false }, + "message": { + "type": "string", + "example": "You don't have permission to update task priorities in this project" + } + } + } + } + } + }, + "404": { + "description": "Not found - organization, team, project or task not found", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { "type": "boolean", "example": false }, + "message": { + "oneOf": [ + { + "type": "string", + "example": "Organization not found" + }, + { "type": "string", "example": "Team not found" }, + { "type": "string", "example": "Project not found" }, + { + "type": "string", + "example": "Task not found or does not belong to the specified project" + } + ] + } + } + } + } + } + }, + "500": { + "description": "Internal server error", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "success": { "type": "boolean", "example": false }, + "message": { + "type": "string", + "example": "Internal server error" + } + } + } + } + } + } + } + } } }, diff --git a/src/routes/task.routes.js b/src/routes/task.routes.js index 8e283f3..43c501f 100644 --- a/src/routes/task.routes.js +++ b/src/routes/task.routes.js @@ -1,6 +1,10 @@ import { Router } from 'express'; import { verifyAccessToken } from '../middlewares/auth.middleware.js'; -import { createTask, updateTask } from '../controllers/task.controller.js'; +import { + createTask, + updateTask, + updateTaskPriority, +} from '../controllers/task.controller.js'; const router = Router(); @@ -16,4 +20,10 @@ router.put( updateTask, ); +router.patch( + '/api/organization/:organizationId/team/:teamId/project/:projectId/task/:taskId/priority', + verifyAccessToken, + updateTaskPriority, +); + export default router;