diff --git a/docs/openapi.yaml b/docs/openapi.yaml index af6af31..a3bdace 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -8,11 +8,13 @@ info: description: This is a documentation of Task Pro tags: - name: Auth - description: Auth operations. + description: Auth Endpoint. - name: Board - description: Board operations. + description: Board Endpoint. - name: Task - description: Task operations. + description: Task Endpoint. + - name: Column + description: Column Endpoint. servers: - url: http://localhost:3000 description: Local Server @@ -46,17 +48,28 @@ paths: $ref: ../swagger/paths/board/deleteBoard.yaml # Tasks Paths /tasks/{board_id}: - post: + post: $ref: ../swagger/paths/task/addTaskByBoardId.yaml get: - $ref: ../swagger/paths/task/GetTasksByBoardId.yaml - /tasks/{board_id}/{task_id}: + $ref: ../swagger/paths/task/getTasksByBoardId.yaml + /tasks/{task_id}: + delete: + $ref: ../swagger/paths/task/deleteTaskByBoardIdAndTaskId.yaml + /tasks/{task_id}/move: + patch: + $ref: ../swagger/paths/task/moveTaskByBoardIdAndTaskId.yaml + # Columns Paths + /column: + post: + $ref: ../swagger/paths/column/addColumn.yaml + /column/{board_id}: + get: + $ref: ../swagger/paths/column/getColumnsByBoardId.yaml + /column/{column_id}: delete: - $ref: ../swagger/paths/task/DeleteTaskByBoardIdAndTaskId.yaml - /tasks/{board_id}/{task_id}/move: - patch: - $ref: ../swagger/paths/task/MoveTaskByBoardIdAndTaskId.yaml - + $ref: ../swagger/paths/column/deleteColumnById.yaml + patch: + $ref: ../swagger/paths/column/updateColumnById.yaml components: securitySchemes: bearerAuth: diff --git a/docs/swagger.json b/docs/swagger.json index 377b964..32bbd32 100644 --- a/docs/swagger.json +++ b/docs/swagger.json @@ -22,15 +22,19 @@ "tags": [ { "name": "Auth", - "description": "Auth operations." + "description": "Auth Endpoint." }, { "name": "Board", - "description": "Board operations." + "description": "Board Endpoint." }, { "name": "Task", - "description": "Task operations." + "description": "Task Endpoint." + }, + { + "name": "Column", + "description": "Column Endpoint." } ], "paths": { @@ -407,14 +411,14 @@ } } }, - "/tasks/{board_id}/{task_id}": { + "/tasks/{task_id}": { "delete": { "tags": [ "Task" ], - "summary": "Delete Task by Board ID and Task ID", - "operationId": "deleteTaskByBoardIdAndTaskId", - "description": "Delete a specific task associated with a specific board by their IDs.", + "summary": "Delete Task by Task ID", + "operationId": "deleteTaskByTaskId", + "description": "Delete a specific task by its ID.", "security": [ { "bearerAuth": [] @@ -422,14 +426,39 @@ ], "parameters": [ { - "name": "board_id", + "name": "task_id", "in": "path", - "description": "ID of the board to delete the task from", + "description": "ID of the task to delete", "required": true, "schema": { "type": "string" } + } + ], + "responses": { + "204": { + "description": "Task deleted successfully." }, + "401": { + "$ref": "#/components/responses/401" + } + } + } + }, + "/tasks/{task_id}/move": { + "patch": { + "tags": [ + "Task" + ], + "summary": "Move Task by Task ID", + "operationId": "moveTaskByTaskId", + "description": "Move a specific task by its ID.", + "security": [ + { + "bearerAuth": [] + } + ], + "parameters": [ { "name": "task_id", "in": "path", @@ -440,9 +469,35 @@ } } ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/moveTask" + } + } + } + }, "responses": { - "204": { - "description": "Task deleted successfully." + "200": { + "description": "Task moved successfully.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Success message.", + "example": "Task moved successfully." + }, + "data": { + "$ref": "#/components/schemas/taskItem" + } + } + } + } + } }, "401": { "$ref": "#/components/responses/401" @@ -450,14 +505,63 @@ } } }, - "/tasks/{board_id}/{task_id}/move": { - "patch": { + "/column": { + "post": { "tags": [ - "Task" + "Column" + ], + "summary": "Add Column", + "operationId": "addColumn", + "description": "Add a new column to a specific board.", + "security": [ + { + "bearerAuth": [] + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/addColumn" + } + } + } + }, + "responses": { + "201": { + "description": "Column added successfully.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Success message.", + "example": "Column added successfully." + }, + "data": { + "$ref": "#/components/schemas/columnItem" + } + } + } + } + } + }, + "401": { + "$ref": "#/components/responses/401" + } + } + } + }, + "/column/{board_id}": { + "get": { + "tags": [ + "Column" ], - "summary": "Move Task by Board ID and Task ID", - "operationId": "moveTaskByBoardIdAndTaskId", - "description": "Move a specific task associated with a specific board by their IDs.", + "summary": "Get Columns by Board ID", + "operationId": "getColumnsByBoardId", + "description": "Retrieve all columns associated with a specific board by its ID.", "security": [ { "bearerAuth": [] @@ -467,34 +571,111 @@ { "name": "board_id", "in": "path", - "description": "ID of the board to delete the task from", + "description": "ID of the board to retrieve columns for", "required": true, "schema": { "type": "string" } + } + ], + "responses": { + "200": { + "description": "A list of columns associated with the specified board ID.", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "message": { + "type": "string", + "description": "Success message.", + "example": "Columns retrieved successfully." + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/columnItem" + } + } + } + } + } + } }, + "401": { + "$ref": "#/components/responses/401" + } + } + } + }, + "/column/{column_id}": { + "delete": { + "tags": [ + "Column" + ], + "summary": "Delete Column by ID", + "operationId": "deleteColumnById", + "description": "Delete a specific column by its ID.", + "security": [ { - "name": "task_id", + "bearerAuth": [] + } + ], + "parameters": [ + { + "name": "column_id", "in": "path", - "description": "ID of the task to delete", + "description": "ID of the column to delete", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Column deleted successfully." + }, + "401": { + "$ref": "#/components/responses/401" + } + } + }, + "patch": { + "tags": [ + "Column" + ], + "summary": "Update Column by ID", + "operationId": "updateColumnById", + "description": "Update the details of a specific column by its ID.", + "parameters": [ + { + "name": "column_id", + "in": "path", + "description": "column by id", "required": true, "schema": { "type": "string" } } ], + "security": [ + { + "bearerAuth": [] + } + ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/moveTask" + "$ref": "#/components/schemas/updateColumn" } } } }, "responses": { "200": { - "description": "Task moved successfully.", + "description": "Column updated successfully.", "content": { "application/json": { "schema": { @@ -503,10 +684,10 @@ "message": { "type": "string", "description": "Success message.", - "example": "Task moved successfully." + "example": "Column updated successfully." }, "data": { - "$ref": "#/components/schemas/taskItem" + "$ref": "#/components/schemas/columnItem" } } } @@ -590,10 +771,7 @@ }, "BadRequestError": { "type": "object", - "title": "Auth Error | Bad Request ", - "x-tags": [ - "Auth" - ], + "title": "Error | Bad Request ", "properties": { "message": { "type": "string", @@ -633,10 +811,7 @@ }, "UnauthorizedError": { "type": "object", - "title": "Auth Error | Unauthorized ", - "x-tags": [ - "Auth" - ], + "title": "Error | Unauthorized ", "properties": { "message": { "type": "string", @@ -899,6 +1074,65 @@ "required": [ "column_id" ] + }, + "addColumn": { + "type": "object", + "title": "Columns | Add Column ", + "properties": { + "title": { + "type": "string", + "example": "Design Homepage" + }, + "board_id": { + "type": "number", + "example": 5 + } + }, + "required": [ + "title", + "board_id" + ] + }, + "columnItem": { + "type": "object", + "title": "Columns | Item", + "properties": { + "id": { + "type": "number", + "example": 1 + }, + "title": { + "type": "string", + "example": "To Do" + }, + "board_id": { + "type": "number", + "example": 5 + }, + "position": { + "type": "number", + "example": 1 + }, + "created_at": { + "type": "string", + "format": "date-time", + "example": "2024-01-10T14:30:00Z" + } + }, + "readOnly": true + }, + "updateColumn": { + "type": "object", + "title": "Columns | Update Column", + "properties": { + "title": { + "type": "string", + "example": "Updated Column Title" + } + }, + "required": [ + "title" + ] } }, "responses": { diff --git a/src/controller/task.js b/src/controller/task.js index 66a0547..efac080 100644 --- a/src/controller/task.js +++ b/src/controller/task.js @@ -35,7 +35,6 @@ export const deleteTaskByIdController = async (req, res) => { res.status(204).send(); }; - export const moveTaskByIdController = async (req, res) => { const { taskId, boardId } = req.params; const updatedTask = await moveTaskByIdService(taskId, boardId, req.body); diff --git a/src/routers/task.js b/src/routers/task.js index aad1f34..765342d 100644 --- a/src/routers/task.js +++ b/src/routers/task.js @@ -20,17 +20,19 @@ router.use(authenticate); // Get all tasks for a specific board router.get("/:boardId", ctrlWrapper(fetchTasksByBoardIdController)); +// Add a Task By Board ID router.post( "/:boardId", validateBody(addTaskSchema), ctrlWrapper(addTaskByBoardIdController), ); + // Delete a Task By Board ID -router.delete("/:boardId/:taskId", ctrlWrapper(deleteTaskByIdController)); +router.delete("/:taskId", ctrlWrapper(deleteTaskByIdController)); // Move Task to another new column router.patch( - "/:boardId/:taskId/move", + "/:taskId/move", validateBody(moveTaskColumnSchema), ctrlWrapper(moveTaskByIdController), ); diff --git a/src/services/task.js b/src/services/task.js index b9d743b..462f934 100644 --- a/src/services/task.js +++ b/src/services/task.js @@ -70,10 +70,10 @@ export const createTaskByBoardIdService = async (boardId, payload) => { * @example * const deletedTask = await deleteTaskByIdService(123); */ -export const deleteTaskByIdService = async (taskId, boardId) => { +export const deleteTaskByIdService = async (taskId) => { const result = await sql` DELETE FROM task - WHERE id = ${taskId} AND board_id = ${boardId} + WHERE id = ${taskId} RETURNING * `; diff --git a/src/validation/task.js b/src/validation/task.js index d6f3af8..4a5fdd3 100644 --- a/src/validation/task.js +++ b/src/validation/task.js @@ -28,5 +28,5 @@ export const addTaskSchema = Joi.object({ */ export const moveTaskColumnSchema = Joi.object({ column_id: Joi.number().required("New Column ID is required"), - position: Joi.number().optional() + position: Joi.number().optional(), }); diff --git a/swagger/components/schemas/auth/BadRequestError.yaml b/swagger/components/schemas/auth/BadRequestError.yaml index 39ab4c7..69822cf 100644 --- a/swagger/components/schemas/auth/BadRequestError.yaml +++ b/swagger/components/schemas/auth/BadRequestError.yaml @@ -1,7 +1,5 @@ type: object -title: "Auth Error | Bad Request " -x-tags: - - Auth +title: "Error | Bad Request " properties: message: type: string @@ -27,4 +25,4 @@ properties: "key": "email", }, } -readOnly: true \ No newline at end of file +readOnly: true diff --git a/swagger/components/schemas/auth/UnauthorizedError.yaml b/swagger/components/schemas/auth/UnauthorizedError.yaml index 54991f2..3e4dff4 100644 --- a/swagger/components/schemas/auth/UnauthorizedError.yaml +++ b/swagger/components/schemas/auth/UnauthorizedError.yaml @@ -1,7 +1,5 @@ type: object -title: "Auth Error | Unauthorized " -x-tags: - - Auth +title: "Error | Unauthorized " properties: message: type: string diff --git a/swagger/components/schemas/column/addColumn.yaml b/swagger/components/schemas/column/addColumn.yaml new file mode 100644 index 0000000..632f30d --- /dev/null +++ b/swagger/components/schemas/column/addColumn.yaml @@ -0,0 +1,12 @@ +type: object +title: "Columns | Add Column " +properties: + title: + type: string + example: "Design Homepage" + board_id: + type: number + example: 5 +required: + - title + - board_id diff --git a/swagger/components/schemas/column/columnItem.yaml b/swagger/components/schemas/column/columnItem.yaml new file mode 100644 index 0000000..dfad502 --- /dev/null +++ b/swagger/components/schemas/column/columnItem.yaml @@ -0,0 +1,20 @@ +type: object +title: "Columns | Item" +properties: + id: + type: number + example: 1 + title: + type: string + example: "To Do" + board_id: + type: number + example: 5 + position: + type: number + example: 1 + created_at: + type: string + format: date-time + example: "2024-01-10T14:30:00Z" +readOnly: true diff --git a/swagger/components/schemas/column/updateColumn.yaml b/swagger/components/schemas/column/updateColumn.yaml new file mode 100644 index 0000000..c30952b --- /dev/null +++ b/swagger/components/schemas/column/updateColumn.yaml @@ -0,0 +1,8 @@ +type: object +title: "Columns | Update Column" +properties: + title: + type: string + example: "Updated Column Title" +required: + - title diff --git a/swagger/paths/column/addColumn.yaml b/swagger/paths/column/addColumn.yaml new file mode 100644 index 0000000..0043f10 --- /dev/null +++ b/swagger/paths/column/addColumn.yaml @@ -0,0 +1,28 @@ +tags: + - Column +summary: Add Column +operationId: addColumn +description: Add a new column to a specific board. +security: + - bearerAuth: [] +requestBody: + content: + application/json: + schema: + $ref: ../../components/schemas/column/addColumn.yaml +responses: + 201: + description: Column added successfully. + content: + application/json: + schema: + type: object + properties: + message: + type: string + description: Success message. + example: "Column added successfully." + data: + $ref: ../../components/schemas/column/columnItem.yaml + 401: + $ref: ../../components/responses/auth/401.yaml diff --git a/swagger/paths/column/deleteColumnById.yaml b/swagger/paths/column/deleteColumnById.yaml new file mode 100644 index 0000000..b66e09f --- /dev/null +++ b/swagger/paths/column/deleteColumnById.yaml @@ -0,0 +1,19 @@ +tags: + - Column +summary: Delete Column by ID +operationId: deleteColumnById +description: Delete a specific column by its ID. +security: + - bearerAuth: [] +parameters: + - name: column_id + in: path + description: ID of the column to delete + required: true + schema: + type: string +responses: + 204: + description: Column deleted successfully. + 401: + $ref: ../../components/responses/auth/401.yaml diff --git a/swagger/paths/column/getColumnsByBoardId.yaml b/swagger/paths/column/getColumnsByBoardId.yaml new file mode 100644 index 0000000..d9d5f07 --- /dev/null +++ b/swagger/paths/column/getColumnsByBoardId.yaml @@ -0,0 +1,32 @@ +tags: + - Column +summary: Get Columns by Board ID +operationId: getColumnsByBoardId +description: Retrieve all columns associated with a specific board by its ID. +security: + - bearerAuth: [] +parameters: + - name: board_id + in: path + description: ID of the board to retrieve columns for + required: true + schema: + type: string +responses: + 200: + description: A list of columns associated with the specified board ID. + content: + application/json: + schema: + type: object + properties: + message: + type: string + description: Success message. + example: "Columns retrieved successfully." + data: + type: array + items: + $ref: ../../components/schemas/column/columnItem.yaml + 401: + $ref: ../../components/responses/auth/401.yaml diff --git a/swagger/paths/column/updateColumnById.yaml b/swagger/paths/column/updateColumnById.yaml new file mode 100644 index 0000000..e789da6 --- /dev/null +++ b/swagger/paths/column/updateColumnById.yaml @@ -0,0 +1,35 @@ +tags: + - Column +summary: Update Column by ID +operationId: updateColumnById +description: Update the details of a specific column by its ID. +parameters: + - name: column_id + in: path + description: column by id + required: true + schema: + type: string +security: + - bearerAuth: [] +requestBody: + content: + application/json: + schema: + $ref: ../../components/schemas/column/updateColumn.yaml +responses: + 200: + description: Column updated successfully. + content: + application/json: + schema: + type: object + properties: + message: + type: string + description: Success message. + example: "Column updated successfully." + data: + $ref: ../../components/schemas/column/columnItem.yaml + 401: + $ref: ../../components/responses/auth/401.yaml diff --git a/swagger/paths/task/DeleteTaskByBoardIdAndTaskId.yaml b/swagger/paths/task/DeleteTaskByBoardIdAndTaskId.yaml index 1851f9f..1acddc5 100644 --- a/swagger/paths/task/DeleteTaskByBoardIdAndTaskId.yaml +++ b/swagger/paths/task/DeleteTaskByBoardIdAndTaskId.yaml @@ -1,17 +1,17 @@ tags: - Task -summary: Delete Task by Board ID and Task ID -operationId: deleteTaskByBoardIdAndTaskId -description: Delete a specific task associated with a specific board by their IDs. +summary: Delete Task by Task ID +operationId: deleteTaskByTaskId +description: Delete a specific task by its ID. security: - bearerAuth: [] parameters: - - name: board_id - in: path - description: ID of the board to delete the task from - required: true - schema: - type: string + # - name: board_id + # in: path + # description: ID of the board to delete the task from + # required: true + # schema: + # type: string - name: task_id in: path description: ID of the task to delete diff --git a/swagger/paths/task/MoveTaskByBoardIdAndTaskId.yaml b/swagger/paths/task/MoveTaskByBoardIdAndTaskId.yaml index d784763..fd18725 100644 --- a/swagger/paths/task/MoveTaskByBoardIdAndTaskId.yaml +++ b/swagger/paths/task/MoveTaskByBoardIdAndTaskId.yaml @@ -1,17 +1,17 @@ tags: - Task -summary: Move Task by Board ID and Task ID -operationId: moveTaskByBoardIdAndTaskId -description: Move a specific task associated with a specific board by their IDs. +summary: Move Task by Task ID +operationId: moveTaskByTaskId +description: Move a specific task by its ID. security: - bearerAuth: [] parameters: - - name: board_id - in: path - description: ID of the board to delete the task from - required: true - schema: - type: string + # - name: board_id + # in: path + # description: ID of the board to delete the task from + # required: true + # schema: + # type: string - name: task_id in: path description: ID of the task to delete