diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/task/ApprovalTaskRequest.java b/src/main/java/clap/server/adapter/inbound/web/dto/task/ApprovalTaskRequest.java new file mode 100644 index 00000000..9e84f3ce --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/dto/task/ApprovalTaskRequest.java @@ -0,0 +1,18 @@ +package clap.server.adapter.inbound.web.dto.task; + +import jakarta.validation.constraints.NotNull; + +import java.time.LocalDateTime; + +public record ApprovalTaskRequest( + @NotNull + Long categoryId, + @NotNull + Long processorId, + @NotNull + LocalDateTime dueDate, + @NotNull + Long labelId + +) { +} diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/task/ApprovalTaskResponse.java b/src/main/java/clap/server/adapter/inbound/web/dto/task/ApprovalTaskResponse.java new file mode 100644 index 00000000..ebc46883 --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/dto/task/ApprovalTaskResponse.java @@ -0,0 +1,15 @@ +package clap.server.adapter.inbound.web.dto.task; + +import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus; + +import java.time.LocalDateTime; + +public record ApprovalTaskResponse( + Long taskId, + String processorName, + String reviewerName, + LocalDateTime deadLine, + String labelName, + TaskStatus taskStatus +) { +} diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/task/FilterTaskListRequest.java b/src/main/java/clap/server/adapter/inbound/web/dto/task/FilterTaskListRequest.java index 6b361be3..afedd25b 100644 --- a/src/main/java/clap/server/adapter/inbound/web/dto/task/FilterTaskListRequest.java +++ b/src/main/java/clap/server/adapter/inbound/web/dto/task/FilterTaskListRequest.java @@ -32,8 +32,8 @@ public record FilterTaskListRequest( @NotNull List taskStatus, - @Schema(description = "정렬 기준", implementation = OrderRequest.class) + @Schema(description = "정렬 기준", implementation = OrderTaskRequest.class) @NotNull - OrderRequest orderRequest + OrderTaskRequest orderRequest ) { } diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/task/OrderRequest.java b/src/main/java/clap/server/adapter/inbound/web/dto/task/OrderTaskRequest.java similarity index 90% rename from src/main/java/clap/server/adapter/inbound/web/dto/task/OrderRequest.java rename to src/main/java/clap/server/adapter/inbound/web/dto/task/OrderTaskRequest.java index c756d06e..fd849bab 100644 --- a/src/main/java/clap/server/adapter/inbound/web/dto/task/OrderRequest.java +++ b/src/main/java/clap/server/adapter/inbound/web/dto/task/OrderTaskRequest.java @@ -2,7 +2,7 @@ import io.swagger.v3.oas.annotations.media.Schema; -public record OrderRequest( +public record OrderTaskRequest( @Schema(description = "정렬 기준", example = "REQUESTED_AT") String sortBy, diff --git a/src/main/java/clap/server/adapter/inbound/web/task/FindTaskController.java b/src/main/java/clap/server/adapter/inbound/web/task/FindTaskController.java index f58dcdbb..e7618937 100644 --- a/src/main/java/clap/server/adapter/inbound/web/task/FindTaskController.java +++ b/src/main/java/clap/server/adapter/inbound/web/task/FindTaskController.java @@ -27,7 +27,7 @@ public class FindTaskController { private final FindTaskListUsecase taskListUsecase; @Operation(summary = "사용자 요청 작업 목록 조회") - @Secured({"ROLE_USER"}) + @Secured({"ROLE_USER", "ROLE_MANAGER"}) @GetMapping("/requests") public ResponseEntity> findTasksRequestedByUser( @RequestParam(defaultValue = "0") int page, 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 5e30f255..3b20d9ee 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 @@ -1,10 +1,8 @@ package clap.server.adapter.inbound.web.task; import clap.server.adapter.inbound.security.SecurityUserDetails; -import clap.server.adapter.inbound.web.dto.task.CreateTaskRequest; -import clap.server.adapter.inbound.web.dto.task.CreateTaskResponse; -import clap.server.adapter.inbound.web.dto.task.UpdateTaskRequest; -import clap.server.adapter.inbound.web.dto.task.UpdateTaskResponse; +import clap.server.adapter.inbound.web.dto.task.*; +import clap.server.application.port.inbound.task.ApprovalTaskUsecase; import clap.server.application.port.inbound.task.CreateTaskUsecase; import clap.server.application.port.inbound.task.UpdateTaskUsecase; import clap.server.common.annotation.architecture.WebAdapter; @@ -15,6 +13,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.http.MediaType; 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.*; import org.springframework.web.multipart.MultipartFile; @@ -31,9 +30,11 @@ public class ManagementTaskController { private final CreateTaskUsecase createTaskUsecase; private final UpdateTaskUsecase updateTaskUsecase; + private final ApprovalTaskUsecase approvalTaskUsecase; @Operation(summary = "작업 요청 생성") @PostMapping(consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE}) + @Secured({"ROLE_MANAGER, ROLE_USER"}) public ResponseEntity createTask( @RequestPart(name = "taskInfo") @Valid CreateTaskRequest createTaskRequest, @RequestPart(name = "attachment") @NotNull List attachments, @@ -44,6 +45,7 @@ public ResponseEntity createTask( @Operation(summary = "작업 수정") @PatchMapping(value = "/{taskId}", consumes = {MediaType.APPLICATION_JSON_VALUE, MediaType.MULTIPART_FORM_DATA_VALUE}) + @Secured({"ROLE_MANAGER, ROLE_USER"}) public ResponseEntity updateTask( @PathVariable @NotNull Long taskId, @RequestPart(name = "taskInfo") @Valid UpdateTaskRequest updateTaskRequest, @@ -51,4 +53,14 @@ public ResponseEntity updateTask( @AuthenticationPrincipal SecurityUserDetails userInfo){ return ResponseEntity.ok(updateTaskUsecase.updateTask(userInfo.getUserId(), taskId, updateTaskRequest, attachments)); } + + @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/MemberPersistenceAdapter.java b/src/main/java/clap/server/adapter/outbound/persistense/MemberPersistenceAdapter.java index 6a142f5d..355879d4 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/MemberPersistenceAdapter.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/MemberPersistenceAdapter.java @@ -85,6 +85,5 @@ public List findTasksByMemberIdAndStatus(Long memberId, List t .map(taskPersistenceMapper::toDomain) .collect(Collectors.toList()); } - } diff --git a/src/main/java/clap/server/adapter/outbound/persistense/entity/task/LabelEntity.java b/src/main/java/clap/server/adapter/outbound/persistense/entity/task/LabelEntity.java index ead2c5ab..ef8f6ad7 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/entity/task/LabelEntity.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/entity/task/LabelEntity.java @@ -2,7 +2,7 @@ import clap.server.adapter.outbound.persistense.entity.common.BaseTimeEntity; import clap.server.adapter.outbound.persistense.entity.member.MemberEntity; -import clap.server.adapter.outbound.persistense.entity.task.constant.LabelType; +import clap.server.adapter.outbound.persistense.entity.task.constant.LabelColor; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; @@ -24,9 +24,12 @@ public class LabelEntity extends BaseTimeEntity { @JoinColumn(name = "admin_id", nullable = false) private MemberEntity admin; + @Column(nullable = false) + private String labelName; + @Column(nullable = false) @Enumerated(EnumType.STRING) - private LabelType labelType; + private LabelColor labelColor; @Column(nullable = false) private boolean isDeleted; diff --git a/src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/LabelType.java b/src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/LabelColor.java similarity index 54% rename from src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/LabelType.java rename to src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/LabelColor.java index 0706e8f5..79ccb338 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/LabelType.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/LabelColor.java @@ -5,11 +5,14 @@ @Getter @RequiredArgsConstructor -public enum LabelType { - EMERGENCY("긴급"), - NORMAL("일반"), - REGULAR("정기"); +public enum LabelColor { + RED("빨강"), + ORANGE("주황"), + YELLOW("노랑"), + GREEN("초록"), + BLUE("파랑"), + PURPLE("보라"), + GREY("회색"); private final String description; } - diff --git a/src/main/java/clap/server/adapter/outbound/persistense/repository/LabelPersistenceAdapter.java b/src/main/java/clap/server/adapter/outbound/persistense/repository/LabelPersistenceAdapter.java new file mode 100644 index 00000000..c64863fb --- /dev/null +++ b/src/main/java/clap/server/adapter/outbound/persistense/repository/LabelPersistenceAdapter.java @@ -0,0 +1,26 @@ +package clap.server.adapter.outbound.persistense.repository; + +import clap.server.adapter.outbound.persistense.entity.task.LabelEntity; +import clap.server.adapter.outbound.persistense.entity.task.TaskEntity; +import clap.server.adapter.outbound.persistense.mapper.LabelPersistenceMapper; +import clap.server.adapter.outbound.persistense.repository.task.LabelRepository; +import clap.server.application.port.outbound.task.LoadLabelPort; +import clap.server.common.annotation.architecture.PersistenceAdapter; +import clap.server.domain.model.task.Label; +import lombok.RequiredArgsConstructor; + +import java.util.Optional; + +@PersistenceAdapter +@RequiredArgsConstructor +public class LabelPersistenceAdapter implements LoadLabelPort { + + private final LabelRepository labelRepository; + private final LabelPersistenceMapper labelPersistenceMapper; + + @Override + public Optional