diff --git a/README.md b/README.md index ca4d5ab..dd8c914 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ This project is designed to be easily testable by anyone, whether they are a dev ### **2. Interactive API Testing (Swagger)** * Navigate to `http://localhost:8080/swagger-ui.html`. -* Explore all documented REST endpoints. +* Explore all documented REST endpoints with **detailed operation descriptions** and **predefined API responses**. * Click **"Try it out"** on any endpoint (like `POST /api/tasks`) to send real JSON requests and see the live responses directly in your browser. ### **3. Database Inspection (PostgreSQL)** @@ -86,7 +86,7 @@ To run the tests locally, use: * **Quick Status Toggle**: Instantly mark tasks as Done or Undone from the main list view. * **User Lifecycle**: Public registration and secure login system. * **Task Metadata**: Categorize tasks by **Status** (TODO, DONE) and **Priority** (HIGH, MEDIUM, LOW). -* **RESTful API**: Comprehensive API endpoints for programmatic task management, fully documented with Swagger. +* **RESTful API**: Comprehensive API endpoints for programmatic task management, fully documented with professional-grade OpenAPI descriptions and responses. --- diff --git a/src/main/java/com/lucc/taskmanager/controller/TaskController.java b/src/main/java/com/lucc/taskmanager/controller/TaskController.java index f19a799..5ef1a12 100644 --- a/src/main/java/com/lucc/taskmanager/controller/TaskController.java +++ b/src/main/java/com/lucc/taskmanager/controller/TaskController.java @@ -6,6 +6,10 @@ import jakarta.validation.Valid; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.web.bind.annotation.*; @@ -25,35 +29,60 @@ public TaskController(TaskService taskService) } @GetMapping - @Operation(summary = "Get all tasks for the logged-in user") + @Operation(summary = "Get all tasks for the logged-in user", description = "Retrieves a list of all tasks associated with the currently authenticated user.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully retrieved tasks"), + @ApiResponse(responseCode = "401", description = "You are not authorized to view the resource", content = @Content) + }) public List getTaskByUser(@AuthenticationPrincipal @Parameter(hidden = true) User user) { return taskService.getTasksByUser(user); } @PostMapping - @Operation(summary = "Add a new task for the logged-in user") + @Operation(summary = "Add a new task", description = "Creates a new task for the currently authenticated user.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully created the task", content = @Content(schema = @Schema(implementation = Task.class))), + @ApiResponse(responseCode = "400", description = "Invalid input data", content = @Content), + @ApiResponse(responseCode = "401", description = "You are not authorized to create a task", content = @Content) + }) public Task addTask(@Valid @RequestBody Task task, @AuthenticationPrincipal @Parameter(hidden = true) User user) { return taskService.addTask(task, user); } @PutMapping("/{taskId}") - @Operation(summary = "Update an existing task") + @Operation(summary = "Update an existing task", description = "Updates the details of an existing task identified by its ID. Users can only update their own tasks.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully updated the task", content = @Content(schema = @Schema(implementation = Task.class))), + @ApiResponse(responseCode = "400", description = "Invalid task ID or input data", content = @Content), + @ApiResponse(responseCode = "401", description = "You are not authorized to update this task", content = @Content), + @ApiResponse(responseCode = "404", description = "Task not found", content = @Content) + }) public Task updateTask(@PathVariable int taskId, @Valid @RequestBody Task task, @AuthenticationPrincipal @Parameter(hidden = true) User user) { return taskService.updateTask(taskId, task, user); } @DeleteMapping("/{taskId}") - @Operation(summary = "Delete a task by ID") + @Operation(summary = "Delete a task by ID", description = "Removes a task from the system identified by its ID. Users can only delete their own tasks.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully deleted the task"), + @ApiResponse(responseCode = "401", description = "You are not authorized to delete this task", content = @Content), + @ApiResponse(responseCode = "404", description = "Task not found", content = @Content) + }) public void deleteTask(@PathVariable int taskId, @AuthenticationPrincipal @Parameter(hidden = true) User user) { taskService.deleteTask(taskId, user); } @PatchMapping("/{taskId}/toggle") - @Operation(summary = "Toggle task status between TODO and DONE") + @Operation(summary = "Toggle task status", description = "Toggles the status of a task between 'TODO' and 'DONE'. Also manages the 'completionDate' automatically.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully toggled task status", content = @Content(schema = @Schema(implementation = Task.class))), + @ApiResponse(responseCode = "401", description = "You are not authorized to toggle this task", content = @Content), + @ApiResponse(responseCode = "404", description = "Task not found", content = @Content) + }) public Task toggleTaskStatus(@PathVariable int taskId, @AuthenticationPrincipal @Parameter(hidden = true) User user) { return taskService.toggleTaskStatus(taskId, user); diff --git a/src/main/java/com/lucc/taskmanager/controller/UserController.java b/src/main/java/com/lucc/taskmanager/controller/UserController.java index 9fb18ec..9101056 100644 --- a/src/main/java/com/lucc/taskmanager/controller/UserController.java +++ b/src/main/java/com/lucc/taskmanager/controller/UserController.java @@ -4,6 +4,11 @@ import com.lucc.taskmanager.service.UserService; import jakarta.validation.Valid; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.ArraySchema; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -24,14 +29,23 @@ public UserController(UserService userService) } @GetMapping - @Operation(summary = "Get all users (Admin only)") + @Operation(summary = "Get all users", description = "Retrieves a comprehensive list of all registered users in the system. This endpoint is restricted to users with the ADMIN role.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully retrieved users", content = @Content(array = @ArraySchema(schema = @Schema(implementation = User.class)))), + @ApiResponse(responseCode = "403", description = "Access denied - Admin role required", content = @Content) + }) public List getUsers() { return userService.getUsers(); } @PostMapping - @Operation(summary = "Add a new user (Admin only)") + @Operation(summary = "Add a new user", description = "Creates a new user account. This endpoint is restricted to users with the ADMIN role.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "Successfully created the user", content = @Content(schema = @Schema(implementation = User.class))), + @ApiResponse(responseCode = "400", description = "Invalid user data provided", content = @Content), + @ApiResponse(responseCode = "403", description = "Access denied - Admin role required", content = @Content) + }) public User addUser(@Valid @RequestBody User user) { return userService.addUser(user);