diff --git a/src/main/java/clap/server/adapter/inbound/web/admin/FindLabelAdminController.java b/src/main/java/clap/server/adapter/inbound/web/admin/FindLabelAdminController.java new file mode 100644 index 00000000..a0079492 --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/admin/FindLabelAdminController.java @@ -0,0 +1,34 @@ +package clap.server.adapter.inbound.web.admin; + +import clap.server.adapter.inbound.security.SecurityUserDetails; +import clap.server.adapter.inbound.web.dto.common.SliceResponse; +import clap.server.adapter.inbound.web.dto.label.FindLabelListResponse; +import clap.server.application.port.inbound.label.FindLabelListUsecase; +import clap.server.common.annotation.architecture.WebAdapter; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.annotation.Secured; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; + +import java.util.List; + +@Tag(name = "05. Admin") +@WebAdapter +@RequiredArgsConstructor +@RequestMapping("/api/managements/label") +public class FindLabelAdminController { + + private final FindLabelListUsecase findLabelListUsecase; + + @Operation(summary = "구분 목록 조회 API") + @Secured({"ROLE_ADMIN"}) + @GetMapping + public ResponseEntity> findLabelList( + @AuthenticationPrincipal SecurityUserDetails userInfo) { + return ResponseEntity.ok(findLabelListUsecase.findLabelListAdmin(userInfo.getUserId())); + } +} diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/label/FindLabelListResponse.java b/src/main/java/clap/server/adapter/inbound/web/dto/label/FindLabelListResponse.java new file mode 100644 index 00000000..4bb0024f --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/dto/label/FindLabelListResponse.java @@ -0,0 +1,10 @@ +package clap.server.adapter.inbound.web.dto.label; + +import clap.server.adapter.outbound.persistense.entity.task.constant.LabelColor; + +public record FindLabelListResponse( + Long labelId, + String labelName, + LabelColor labelColor +) { +} diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/notification/CountNotificationResponse.java b/src/main/java/clap/server/adapter/inbound/web/dto/notification/CountNotificationResponse.java new file mode 100644 index 00000000..0c9eba0b --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/dto/notification/CountNotificationResponse.java @@ -0,0 +1,7 @@ +package clap.server.adapter.inbound.web.dto.notification; + +public record CountNotificationResponse( + Long memberId, + Integer count +) { +} diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/task/UpdateTaskLabelRequest.java b/src/main/java/clap/server/adapter/inbound/web/dto/task/UpdateTaskLabelRequest.java new file mode 100644 index 00000000..46e6bab5 --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/dto/task/UpdateTaskLabelRequest.java @@ -0,0 +1,6 @@ +package clap.server.adapter.inbound.web.dto.task; + +public record UpdateTaskLabelRequest( + Long labelId +) { +} diff --git a/src/main/java/clap/server/adapter/inbound/web/label/FindLabelController.java b/src/main/java/clap/server/adapter/inbound/web/label/FindLabelController.java new file mode 100644 index 00000000..809de982 --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/label/FindLabelController.java @@ -0,0 +1,48 @@ +package clap.server.adapter.inbound.web.label; + +import clap.server.adapter.inbound.security.SecurityUserDetails; +import clap.server.adapter.inbound.web.dto.common.SliceResponse; +import clap.server.adapter.inbound.web.dto.label.FindLabelListResponse; +import clap.server.application.port.inbound.label.FindLabelListUsecase; +import clap.server.common.annotation.architecture.WebAdapter; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.Parameters; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.annotation.Secured; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@Tag(name = "02. Task[검토자]") +@WebAdapter +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/labels") +public class FindLabelController { + + private final FindLabelListUsecase findLabelListUsecase; + + @Operation(summary = "구분 목록 조회 API") + @Parameters({ + @Parameter(name = "page", description = "조회할 목록 페이지 번호(0부터 시작)", example = "0", required = false), + @Parameter(name = "size", description = "조회할 목록 페이지 당 개수", example = "5", required = false) + }) + @Secured({"ROLE_MANAGER"}) + @GetMapping + public ResponseEntity> findLabelList( + @AuthenticationPrincipal SecurityUserDetails userInfo, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "5") int size) { + Pageable pageable = PageRequest.of(page, size); + return ResponseEntity.ok(findLabelListUsecase.findLabelList(userInfo.getUserId(), pageable)); + } +} diff --git a/src/main/java/clap/server/adapter/inbound/web/notification/FindNotificationController.java b/src/main/java/clap/server/adapter/inbound/web/notification/FindNotificationController.java index 5dfc9b59..1feb38ed 100644 --- a/src/main/java/clap/server/adapter/inbound/web/notification/FindNotificationController.java +++ b/src/main/java/clap/server/adapter/inbound/web/notification/FindNotificationController.java @@ -2,7 +2,9 @@ import clap.server.adapter.inbound.security.SecurityUserDetails; import clap.server.adapter.inbound.web.dto.common.SliceResponse; +import clap.server.adapter.inbound.web.dto.notification.CountNotificationResponse; import clap.server.adapter.inbound.web.dto.notification.FindNotificationListResponse; +import clap.server.application.port.inbound.notification.CountNotificationUseCase; import clap.server.application.port.inbound.notification.FindNotificationListUsecase; import clap.server.common.annotation.architecture.WebAdapter; import io.swagger.v3.oas.annotations.Operation; @@ -27,6 +29,7 @@ public class FindNotificationController { private final FindNotificationListUsecase findNotificationListUsecase; + private final CountNotificationUseCase countNotificationUseCase; @Operation(summary = "알림 목록 조회 API") @Parameters({ @@ -41,4 +44,11 @@ public ResponseEntity> findNotificat Pageable pageable = PageRequest.of(page, size); return ResponseEntity.ok(findNotificationListUsecase.findNotificationList(securityUserDetails.getUserId(), pageable)); } + + @Operation(summary = "미확인 알림 개수 조회 API") + @GetMapping("/count") + public ResponseEntity countNotification( + @AuthenticationPrincipal SecurityUserDetails userInfo) { + return ResponseEntity.ok(countNotificationUseCase.countNotification(userInfo.getUserId())); + } } diff --git a/src/main/java/clap/server/adapter/inbound/web/task/ChangeTaskController.java b/src/main/java/clap/server/adapter/inbound/web/task/ChangeTaskController.java new file mode 100644 index 00000000..9ec8bd7a --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/task/ChangeTaskController.java @@ -0,0 +1,73 @@ +package clap.server.adapter.inbound.web.task; + +import clap.server.adapter.inbound.security.SecurityUserDetails; +import clap.server.adapter.inbound.web.dto.task.*; +import clap.server.application.port.inbound.task.ApprovalTaskUsecase; +import clap.server.application.port.inbound.task.UpdateTaskLabelUsecase; +import clap.server.application.port.inbound.task.UpdateTaskProcessorUsecase; +import clap.server.application.port.inbound.task.UpdateTaskStatusUsecase; +import clap.server.common.annotation.architecture.WebAdapter; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotNull; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.security.access.annotation.Secured; +import org.springframework.security.core.annotation.AuthenticationPrincipal; +import org.springframework.web.bind.annotation.*; + + +@Tag(name = "02. Task[검토자]") +@WebAdapter +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/tasks") +public class ChangeTaskController { + + private final UpdateTaskStatusUsecase updateTaskStatusUsecase; + private final UpdateTaskProcessorUsecase updateTaskProcessorUsecase; + private final UpdateTaskLabelUsecase updateTaskLabelUsecase; + private final ApprovalTaskUsecase approvalTaskUsecase; + + @Operation(summary = "작업 상태 변경") + @Secured({"ROLE_MANGER"}) + @PatchMapping("/state/{taskId}") + public ResponseEntity updateTaskState( + @PathVariable @NotNull Long taskId, + @AuthenticationPrincipal SecurityUserDetails userInfo, + @RequestBody UpdateTaskStatusRequest updateTaskStatusRequest) { + + return ResponseEntity.ok(updateTaskStatusUsecase.updateTaskState(userInfo.getUserId(), taskId, updateTaskStatusRequest)); + } + + @Operation(summary = "작업 처리자 변경") + @Secured({"ROLE_MANAGER"}) + @PatchMapping("/processor/{taskId}") + public ResponseEntity updateTaskProcessor( + @PathVariable Long taskId, + @AuthenticationPrincipal SecurityUserDetails userInfo, + @RequestBody UpdateTaskProcessorRequest updateTaskProcessorRequest) { + return ResponseEntity.ok(updateTaskProcessorUsecase.updateTaskProcessor(taskId, userInfo.getUserId(), updateTaskProcessorRequest)); + } + + @Operation(summary = "작업 구분 변경") + @Secured({"ROLE_MANAGER"}) + @PatchMapping("/label/{taskId}") + public ResponseEntity updateTaskLabel( + @PathVariable Long taskId, + @AuthenticationPrincipal SecurityUserDetails userInfo, + @RequestBody UpdateTaskLabelRequest updateTaskLabelRequest) { + return ResponseEntity.ok(updateTaskLabelUsecase.updateTaskLabel(taskId, userInfo.getUserId(), updateTaskLabelRequest)); + } + + @Operation(summary = "작업 승인") + @Secured({"ROLE_MANAGER"}) + @PostMapping("/approval/{taskId}") + public ResponseEntity approvalTask( + @RequestBody @Valid ApprovalTaskRequest approvalTaskRequest, + @PathVariable Long taskId, + @AuthenticationPrincipal SecurityUserDetails userInfo){ + return ResponseEntity.ok(approvalTaskUsecase.approvalTaskByReviewer(userInfo.getUserId(), taskId, approvalTaskRequest)); + } +} diff --git a/src/main/java/clap/server/adapter/inbound/web/task/ManagementTaskController.java b/src/main/java/clap/server/adapter/inbound/web/task/ManagementTaskController.java index ab045008..b45238b1 100644 --- a/src/main/java/clap/server/adapter/inbound/web/task/ManagementTaskController.java +++ b/src/main/java/clap/server/adapter/inbound/web/task/ManagementTaskController.java @@ -2,7 +2,6 @@ import clap.server.adapter.inbound.security.SecurityUserDetails; import clap.server.adapter.inbound.web.dto.task.*; -import clap.server.adapter.inbound.web.dto.task.UpdateTaskProcessorRequest; import clap.server.application.port.inbound.task.*; import clap.server.common.annotation.architecture.WebAdapter; import io.swagger.v3.oas.annotations.Operation; @@ -29,9 +28,6 @@ public class ManagementTaskController { private final CreateTaskUsecase createTaskUsecase; private final UpdateTaskUsecase updateTaskUsecase; - private final UpdateTaskStatusUsecase updateTaskStatusUsecase; - private final UpdateTaskProcessorUsecase updateTaskProcessorUsecase; - private final ApprovalTaskUsecase approvalTaskUsecase; @Operation(summary = "작업 요청 생성") @PostMapping(consumes = {MediaType.MULTIPART_FORM_DATA_VALUE, MediaType.APPLICATION_JSON_VALUE}) @@ -54,35 +50,4 @@ public ResponseEntity updateTask( @AuthenticationPrincipal SecurityUserDetails userInfo){ return ResponseEntity.ok(updateTaskUsecase.updateTask(userInfo.getUserId(), taskId, updateTaskRequest, attachments)); } - - @Operation(summary = "작업 상태 변경") - @Secured({"ROLE_MANGER"}) - @PatchMapping("/state/{taskId}") - public ResponseEntity updateTaskState( - @PathVariable @NotNull Long taskId, - @AuthenticationPrincipal SecurityUserDetails userInfo, - @RequestBody UpdateTaskStatusRequest updateTaskStatusRequest) { - - return ResponseEntity.ok(updateTaskStatusUsecase.updateTaskState(userInfo.getUserId(), taskId, updateTaskStatusRequest)); - } - - @Operation(summary = "작업 처리자 변경") - @Secured({"ROLE_MANAGER"}) - @PatchMapping("/processor/{taskId}") - public ResponseEntity updateTaskProcessor( - @PathVariable Long taskId, - @AuthenticationPrincipal SecurityUserDetails userInfo, - @RequestBody UpdateTaskProcessorRequest updateTaskProcessorRequest) { - return ResponseEntity.ok(updateTaskProcessorUsecase.updateTaskProcessor(taskId, userInfo.getUserId(), updateTaskProcessorRequest)); - } - - @Operation(summary = "작업 승인") - @Secured({"ROLE_MANAGER"}) - @PostMapping("/approval/{taskId}") - public ResponseEntity approvalTask( - @RequestBody @Valid ApprovalTaskRequest approvalTaskRequest, - @PathVariable Long taskId, - @AuthenticationPrincipal SecurityUserDetails userInfo){ - return ResponseEntity.ok(approvalTaskUsecase.approvalTaskByReviewer(userInfo.getUserId(), taskId, approvalTaskRequest)); - } } diff --git a/src/main/java/clap/server/adapter/outbound/persistense/LabelPersistenceAdapter.java b/src/main/java/clap/server/adapter/outbound/persistense/LabelPersistenceAdapter.java index dd09e12a..5a26a3d7 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/LabelPersistenceAdapter.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/LabelPersistenceAdapter.java @@ -1,14 +1,24 @@ package clap.server.adapter.outbound.persistense; +import clap.server.adapter.inbound.web.dto.common.SliceResponse; +import clap.server.adapter.inbound.web.dto.label.FindLabelListResponse; +import clap.server.adapter.inbound.web.dto.notification.FindNotificationListResponse; import clap.server.adapter.outbound.persistense.entity.task.LabelEntity; import clap.server.adapter.outbound.persistense.mapper.LabelPersistenceMapper; import clap.server.adapter.outbound.persistense.repository.task.LabelRepository; +import clap.server.application.mapper.LabelMapper; +import clap.server.application.mapper.NotificationMapper; import clap.server.application.port.outbound.task.LoadLabelPort; import clap.server.common.annotation.architecture.PersistenceAdapter; +import clap.server.domain.model.notification.Notification; import clap.server.domain.model.task.Label; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Slice; +import java.util.List; import java.util.Optional; +import java.util.stream.Collectors; @PersistenceAdapter @RequiredArgsConstructor @@ -18,8 +28,27 @@ public class LabelPersistenceAdapter implements LoadLabelPort { private final LabelPersistenceMapper labelPersistenceMapper; @Override - public Optional