diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/history/response/FindTaskHistoryResponse.java b/src/main/java/clap/server/adapter/inbound/web/dto/history/response/FindTaskHistoryResponse.java index 24b0a7a6..3a32b5f9 100644 --- a/src/main/java/clap/server/adapter/inbound/web/dto/history/response/FindTaskHistoryResponse.java +++ b/src/main/java/clap/server/adapter/inbound/web/dto/history/response/FindTaskHistoryResponse.java @@ -24,7 +24,7 @@ public static record Details( ) {} public static record TaskDetails( - String newValue + String value ) {} public static record CommentDetails( diff --git a/src/main/java/clap/server/adapter/inbound/web/dto/task/request/UpdateTaskStatusRequest.java b/src/main/java/clap/server/adapter/inbound/web/dto/task/request/UpdateTaskStatusRequest.java deleted file mode 100644 index c73f2268..00000000 --- a/src/main/java/clap/server/adapter/inbound/web/dto/task/request/UpdateTaskStatusRequest.java +++ /dev/null @@ -1,14 +0,0 @@ -package clap.server.adapter.inbound.web.dto.task.request; - -import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus; -import io.swagger.v3.oas.annotations.media.Schema; -import jakarta.validation.constraints.NotNull; - -@Schema(description = "작업 상태 변경 요청") -public record UpdateTaskStatusRequest( - - @Schema(description = "변경하고 싶은 작업 상태", example = "COMPLETED") - @NotNull - TaskStatus taskStatus -) { -} 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 index e4ca41c2..6f1c348c 100644 --- a/src/main/java/clap/server/adapter/inbound/web/task/ChangeTaskController.java +++ b/src/main/java/clap/server/adapter/inbound/web/task/ChangeTaskController.java @@ -4,15 +4,17 @@ import clap.server.adapter.inbound.web.dto.task.request.ApprovalTaskRequest; import clap.server.adapter.inbound.web.dto.task.request.UpdateTaskLabelRequest; import clap.server.adapter.inbound.web.dto.task.request.UpdateTaskProcessorRequest; -import clap.server.adapter.inbound.web.dto.task.request.UpdateTaskStatusRequest; import clap.server.adapter.inbound.web.dto.task.response.ApprovalTaskResponse; import clap.server.adapter.inbound.web.dto.task.response.UpdateTaskResponse; +import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus; 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.Parameter; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; import jakarta.validation.constraints.NotNull; @@ -41,9 +43,11 @@ public class ChangeTaskController { public ResponseEntity updateTaskState( @PathVariable @NotNull Long taskId, @AuthenticationPrincipal SecurityUserDetails userInfo, - @RequestBody UpdateTaskStatusRequest updateTaskStatusRequest) { + @Parameter(description = "변경하고 싶은 작업 상태", + schema = @Schema(allowableValues = {"IN_PROGRESS", "PENDING_COMPLETED", "COMPLETED"})) + @RequestBody TaskStatus taskStatus) { - return ResponseEntity.ok(updateTaskStatusUsecase.updateTaskState(userInfo.getUserId(), taskId, updateTaskStatusRequest)); + return ResponseEntity.ok(updateTaskStatusUsecase.updateTaskStatus(userInfo.getUserId(), taskId, taskStatus)); } @Operation(summary = "작업 처리자 변경") diff --git a/src/main/java/clap/server/adapter/inbound/web/task/TerminateTaskController.java b/src/main/java/clap/server/adapter/inbound/web/task/TerminateTaskController.java new file mode 100644 index 00000000..af0e8847 --- /dev/null +++ b/src/main/java/clap/server/adapter/inbound/web/task/TerminateTaskController.java @@ -0,0 +1,31 @@ +package clap.server.adapter.inbound.web.task; + +import clap.server.adapter.inbound.security.SecurityUserDetails; +import clap.server.application.port.inbound.task.TerminateTaskUsecase; +import clap.server.common.annotation.architecture.WebAdapter; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.media.Schema; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +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 TerminateTaskController { + private final TerminateTaskUsecase terminateTaskUsecase; + + @Operation(summary = "작업 거부 및 종료") + @Secured({"ROLE_MANAGER"}) + @PatchMapping("/{taskId}/terminate") + public void terminateTask(@AuthenticationPrincipal SecurityUserDetails userInfo, + @PathVariable Long taskId, + @RequestBody @Schema(example = "스웨거에서는 따옴표를 떼고 보내주세요") String reason) { + terminateTaskUsecase.terminateTask(userInfo.getUserId(), taskId, reason); + } + +} diff --git a/src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/TaskHistoryType.java b/src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/TaskHistoryType.java index e028d885..3b7861a9 100644 --- a/src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/TaskHistoryType.java +++ b/src/main/java/clap/server/adapter/outbound/persistense/entity/task/constant/TaskHistoryType.java @@ -10,7 +10,8 @@ public enum TaskHistoryType { COMMENT_FILE("댓글 첨부파일"), STATUS_SWITCHED("상태 전환"), PROCESSOR_ASSIGNED("처리자 할당"), - PROCESSOR_CHANGED("처리자 변경"); + PROCESSOR_CHANGED("처리자 변경"), + TASK_TERMINATED("작업 종료됨"); private final String description; } diff --git a/src/main/java/clap/server/application/mapper/TaskHistoryResponseMapper.java b/src/main/java/clap/server/application/mapper/TaskHistoryResponseMapper.java index f24e8fcd..f8dee5c3 100644 --- a/src/main/java/clap/server/application/mapper/TaskHistoryResponseMapper.java +++ b/src/main/java/clap/server/application/mapper/TaskHistoryResponseMapper.java @@ -26,7 +26,7 @@ public static FindTaskHistoryResponse toFindTaskHistoryResponse(List new FindTaskHistoryResponse.Details( + case STATUS_SWITCHED, TASK_TERMINATED -> new FindTaskHistoryResponse.Details( new FindTaskHistoryResponse.TaskDetails( taskHistory.getTaskModificationInfo().getModifiedStatus() ), diff --git a/src/main/java/clap/server/application/port/inbound/domain/TaskService.java b/src/main/java/clap/server/application/port/inbound/domain/TaskService.java index fada0234..852c214e 100644 --- a/src/main/java/clap/server/application/port/inbound/domain/TaskService.java +++ b/src/main/java/clap/server/application/port/inbound/domain/TaskService.java @@ -1,5 +1,6 @@ package clap.server.application.port.inbound.domain; +import clap.server.application.port.outbound.task.CommandTaskPort; import clap.server.application.port.outbound.task.LoadTaskPort; import clap.server.domain.model.task.Task; import clap.server.exception.ApplicationException; @@ -12,9 +13,14 @@ public class TaskService { private final LoadTaskPort loadTaskPort; + private final CommandTaskPort commandTaskPort; public Task findById(Long taskId) { return loadTaskPort.findById(taskId).orElseThrow( ()-> new ApplicationException(TaskErrorCode.TASK_NOT_FOUND)); } + + public Task upsert(Task task) { + return commandTaskPort.save(task); + } } diff --git a/src/main/java/clap/server/application/port/inbound/task/TerminateTaskUsecase.java b/src/main/java/clap/server/application/port/inbound/task/TerminateTaskUsecase.java new file mode 100644 index 00000000..54f982a3 --- /dev/null +++ b/src/main/java/clap/server/application/port/inbound/task/TerminateTaskUsecase.java @@ -0,0 +1,5 @@ +package clap.server.application.port.inbound.task; + +public interface TerminateTaskUsecase { + void terminateTask(Long memberId, Long taskId, String reason); +} diff --git a/src/main/java/clap/server/application/port/inbound/task/UpdateTaskStatusUsecase.java b/src/main/java/clap/server/application/port/inbound/task/UpdateTaskStatusUsecase.java index 3ab60de5..80c7ff03 100644 --- a/src/main/java/clap/server/application/port/inbound/task/UpdateTaskStatusUsecase.java +++ b/src/main/java/clap/server/application/port/inbound/task/UpdateTaskStatusUsecase.java @@ -1,8 +1,8 @@ package clap.server.application.port.inbound.task; import clap.server.adapter.inbound.web.dto.task.response.UpdateTaskResponse; -import clap.server.adapter.inbound.web.dto.task.request.UpdateTaskStatusRequest; +import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus; public interface UpdateTaskStatusUsecase { - UpdateTaskResponse updateTaskState(Long memberId, Long taskId, UpdateTaskStatusRequest updateTaskStatusRequest); + UpdateTaskResponse updateTaskStatus(Long memberId, Long taskId, TaskStatus taskStatus); } diff --git a/src/main/java/clap/server/application/service/task/ApprovalTaskService.java b/src/main/java/clap/server/application/service/task/ApprovalTaskService.java index eb6f272a..30e61d54 100644 --- a/src/main/java/clap/server/application/service/task/ApprovalTaskService.java +++ b/src/main/java/clap/server/application/service/task/ApprovalTaskService.java @@ -57,7 +57,7 @@ public ApprovalTaskResponse approvalTaskByReviewer(Long reviewerId, Long taskId, List receivers = List.of(reviewer, processor); publishNotification(receivers, task); - return TaskResponseMapper.toApprovalTaskResponse(commandTaskPort.save(task)); + return TaskResponseMapper.toApprovalTaskResponse(taskService.upsert(task)); } @Override diff --git a/src/main/java/clap/server/application/service/task/GetTaskBoardService.java b/src/main/java/clap/server/application/service/task/GetTaskBoardService.java index 94bfd697..3f126e17 100644 --- a/src/main/java/clap/server/application/service/task/GetTaskBoardService.java +++ b/src/main/java/clap/server/application/service/task/GetTaskBoardService.java @@ -9,7 +9,7 @@ import clap.server.application.port.outbound.task.LoadTaskPort; import clap.server.common.annotation.architecture.ApplicationService; import clap.server.domain.model.task.Task; -import clap.server.domain.policy.task.TaskValuePolicy; +import clap.server.domain.policy.task.TaskPolicyConstants; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Pageable; @@ -18,13 +18,13 @@ import java.time.LocalDate; import java.time.LocalDateTime; +import java.util.List; @Slf4j @ApplicationService @RequiredArgsConstructor @Transactional(readOnly = true) class GetTaskBoardService implements GetTaskBoardUsecase, FilterTaskBoardUsecase { - private final MemberService memberService; private final LoadTaskPort loadTaskPort; @@ -32,7 +32,7 @@ class GetTaskBoardService implements GetTaskBoardUsecase, FilterTaskBoardUsecase public TaskBoardResponse getTaskBoards(Long processorId, LocalDate untilDate, Pageable pageable) { memberService.findActiveMember(processorId); LocalDateTime untilDateTime = untilDate == null ? LocalDate.now().plusDays(1).atStartOfDay() : untilDate.plusDays(1).atStartOfDay(); - Slice tasks = loadTaskPort.findByProcessorAndStatus(processorId, TaskValuePolicy.TASK_BOARD_STATUS_FILTER, untilDateTime, pageable); + Slice tasks = loadTaskPort.findByProcessorAndStatus(processorId, TaskPolicyConstants.TASK_BOARD_STATUS_FILTER, untilDateTime, pageable); return TaskResponseMapper.toSliceTaskItemResponse(tasks); } @@ -40,7 +40,7 @@ public TaskBoardResponse getTaskBoards(Long processorId, LocalDate untilDate, Pa public TaskBoardResponse getTaskBoardByFilter(Long processorId, LocalDate untilDate, FilterTaskBoardRequest request, Pageable pageable) { memberService.findActiveMember(processorId); LocalDateTime untilDateTime = untilDate == null ? LocalDate.now().plusDays(1).atStartOfDay() : untilDate.plusDays(1).atStartOfDay(); - Slice tasks = loadTaskPort.findTaskBoardByFilter(processorId, TaskValuePolicy.TASK_BOARD_STATUS_FILTER, untilDateTime, request, pageable); + Slice tasks = loadTaskPort.findTaskBoardByFilter(processorId, TaskPolicyConstants.TASK_BOARD_STATUS_FILTER, untilDateTime, request, pageable); return TaskResponseMapper.toSliceTaskItemResponse(tasks); } } diff --git a/src/main/java/clap/server/application/service/task/TerminateTaskService.java b/src/main/java/clap/server/application/service/task/TerminateTaskService.java new file mode 100644 index 00000000..43281dfd --- /dev/null +++ b/src/main/java/clap/server/application/service/task/TerminateTaskService.java @@ -0,0 +1,32 @@ +package clap.server.application.service.task; + +import clap.server.adapter.outbound.persistense.entity.task.constant.TaskHistoryType; +import clap.server.application.port.inbound.domain.MemberService; +import clap.server.application.port.inbound.domain.TaskService; +import clap.server.application.port.inbound.task.TerminateTaskUsecase; +import clap.server.application.port.outbound.taskhistory.CommandTaskHistoryPort; +import clap.server.common.annotation.architecture.ApplicationService; +import clap.server.domain.model.task.Task; +import clap.server.domain.model.task.TaskHistory; +import lombok.RequiredArgsConstructor; +import org.springframework.transaction.annotation.Transactional; + +@ApplicationService +@RequiredArgsConstructor +@Transactional +public class TerminateTaskService implements TerminateTaskUsecase { + private final MemberService memberService; + private final TaskService taskService; + private final CommandTaskHistoryPort commandTaskHistoryPort; + + @Override + public void terminateTask(Long memberId, Long taskId, String reason) { + memberService.findReviewer(memberId); + Task task = taskService.findById(taskId); + task.terminateTask(); + taskService.upsert(task); + + TaskHistory taskHistory = TaskHistory.createTaskHistory(TaskHistoryType.TASK_TERMINATED, task, reason, null, null); + commandTaskHistoryPort.save(taskHistory); + } +} diff --git a/src/main/java/clap/server/application/service/task/UpdateTaskBoardService.java b/src/main/java/clap/server/application/service/task/UpdateTaskBoardService.java index 1e0f7dca..8cd7a74d 100644 --- a/src/main/java/clap/server/application/service/task/UpdateTaskBoardService.java +++ b/src/main/java/clap/server/application/service/task/UpdateTaskBoardService.java @@ -6,14 +6,13 @@ import clap.server.application.port.inbound.domain.TaskService; import clap.server.application.port.inbound.task.UpdateTaskBoardUsecase; import clap.server.application.port.inbound.task.UpdateTaskOrderAndStatusUsecase; -import clap.server.application.port.outbound.task.CommandTaskPort; import clap.server.application.port.outbound.task.LoadTaskPort; import clap.server.domain.policy.task.TaskOrderCalculationPolicy; import clap.server.domain.policy.task.ProcessorValidationPolicy; import clap.server.common.annotation.architecture.ApplicationService; import clap.server.domain.model.member.Member; import clap.server.domain.model.task.Task; -import clap.server.domain.policy.task.TaskValuePolicy; +import clap.server.domain.policy.task.TaskPolicyConstants; import clap.server.exception.ApplicationException; import clap.server.exception.code.TaskErrorCode; import lombok.RequiredArgsConstructor; @@ -27,7 +26,7 @@ class UpdateTaskBoardService implements UpdateTaskBoardUsecase, UpdateTaskOrderA private final MemberService memberService; private final TaskService taskService; private final LoadTaskPort loadTaskPort; - private final CommandTaskPort commandTaskPort; + private final TaskOrderCalculationPolicy taskOrderCalculationPolicy; private final ProcessorValidationPolicy processorValidationPolicy; @@ -81,7 +80,7 @@ else if (request.nextTaskId() == 0) { */ private void updateNewTaskOrder(Task targetTask, Long newOrder) { targetTask.updateProcessorOrder(newOrder); - commandTaskPort.save(targetTask); + taskService.upsert(targetTask); } /** @@ -125,7 +124,7 @@ public void updateTaskOrderAndStatus(Long processorId, UpdateTaskOrderRequest re private void updateNewTaskOrderAndStatus(TaskStatus targetStatus, Task targetTask, long newOrder) { targetTask.updateProcessorOrder(newOrder); targetTask.updateTaskStatus(targetStatus); - commandTaskPort.save(targetTask); + taskService.upsert(targetTask); } /** @@ -138,7 +137,7 @@ public void validateRequest(UpdateTaskOrderRequest request, TaskStatus targetSta } // 타겟 상태가 유효한지 검증 - if (targetStatus != null && !TaskValuePolicy.TASK_BOARD_STATUS_FILTER.contains(targetStatus)) { + if (targetStatus != null && !TaskPolicyConstants.TASK_BOARD_STATUS_FILTER.contains(targetStatus)) { throw new ApplicationException(TaskErrorCode.INVALID_TASK_STATUS_TRANSITION); } } diff --git a/src/main/java/clap/server/application/service/task/UpdateTaskService.java b/src/main/java/clap/server/application/service/task/UpdateTaskService.java index 829bbf35..9c65a995 100644 --- a/src/main/java/clap/server/application/service/task/UpdateTaskService.java +++ b/src/main/java/clap/server/application/service/task/UpdateTaskService.java @@ -3,9 +3,9 @@ import clap.server.adapter.inbound.web.dto.task.request.UpdateTaskLabelRequest; import clap.server.adapter.inbound.web.dto.task.request.UpdateTaskProcessorRequest; import clap.server.adapter.inbound.web.dto.task.request.UpdateTaskRequest; -import clap.server.adapter.inbound.web.dto.task.request.UpdateTaskStatusRequest; import clap.server.adapter.inbound.web.dto.task.response.UpdateTaskResponse; import clap.server.adapter.outbound.persistense.entity.notification.constant.NotificationType; +import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus; import clap.server.application.mapper.AttachmentMapper; import clap.server.application.mapper.TaskResponseMapper; import clap.server.application.port.inbound.domain.CategoryService; @@ -18,7 +18,6 @@ import clap.server.application.port.inbound.task.UpdateTaskUsecase; import clap.server.application.port.outbound.s3.S3UploadPort; import clap.server.application.port.outbound.task.CommandAttachmentPort; -import clap.server.application.port.outbound.task.CommandTaskPort; import clap.server.application.port.outbound.task.LoadAttachmentPort; import clap.server.application.service.webhook.SendNotificationService; import clap.server.common.annotation.architecture.ApplicationService; @@ -28,6 +27,7 @@ import clap.server.domain.model.task.Category; import clap.server.domain.model.task.Label; import clap.server.domain.model.task.Task; +import clap.server.domain.policy.task.TaskPolicyConstants; import clap.server.exception.ApplicationException; import clap.server.exception.code.TaskErrorCode; import lombok.RequiredArgsConstructor; @@ -48,7 +48,6 @@ public class UpdateTaskService implements UpdateTaskUsecase, UpdateTaskStatusUse private final TaskService taskService; private final SendNotificationService sendNotificationService; - private final CommandTaskPort commandTaskPort; private final LoadAttachmentPort loadAttachmentPort; private final LabelService labelService; private final CommandAttachmentPort commandAttachmentPort; @@ -62,7 +61,7 @@ public UpdateTaskResponse updateTask(Long requesterId, Long taskId, UpdateTaskRe Task task = taskService.findById(taskId); task.updateTask(requesterId, category, updateTaskRequest.title(), updateTaskRequest.description()); - Task updatedTask = commandTaskPort.save(task); + Task updatedTask = taskService.upsert(task); if (!updateTaskRequest.attachmentsToDelete().isEmpty()) { updateAttachments(updateTaskRequest.attachmentsToDelete(), files, task); @@ -72,11 +71,14 @@ public UpdateTaskResponse updateTask(Long requesterId, Long taskId, UpdateTaskRe @Override @Transactional - public UpdateTaskResponse updateTaskState(Long memberId, Long taskId, UpdateTaskStatusRequest updateTaskStatusRequest) { + public UpdateTaskResponse updateTaskStatus(Long memberId, Long taskId, TaskStatus taskStatus) { memberService.findActiveMember(memberId); + if(!TaskPolicyConstants.TASK_UPDATABLE_STATUS.contains(taskStatus)){ + throw new ApplicationException(TaskErrorCode.TASK_STATUS_NOT_ALLOWED); + } Task task = taskService.findById(taskId); - task.updateTaskStatus(updateTaskStatusRequest.taskStatus()); - Task updateTask = commandTaskPort.save(task); + task.updateTaskStatus(taskStatus); + Task updateTask = taskService.upsert(task); publishNotification(updateTask, NotificationType.STATUS_SWITCHED, String.valueOf(updateTask.getTaskStatus())); return TaskResponseMapper.toUpdateTaskResponse(updateTask); @@ -90,7 +92,7 @@ public UpdateTaskResponse updateTaskProcessor(Long taskId, Long userId, UpdateTa Task task = taskService.findById(taskId); task.updateProcessor(processor); - Task updateTask = commandTaskPort.save(task); + Task updateTask = taskService.upsert(task); publishNotification(updateTask, NotificationType.PROCESSOR_CHANGED, updateTask.getProcessor().getNickname()); return TaskResponseMapper.toUpdateTaskResponse(updateTask); @@ -104,7 +106,7 @@ public UpdateTaskResponse updateTaskLabel(Long taskId, Long userId, UpdateTaskLa Label label = labelService.findById(request.labelId()); task.updateLabel(label); - Task updatetask = commandTaskPort.save(task); + Task updatetask = taskService.upsert(task); return TaskResponseMapper.toUpdateTaskResponse(updatetask); } diff --git a/src/main/java/clap/server/domain/model/task/Task.java b/src/main/java/clap/server/domain/model/task/Task.java index 89abf6e2..e5dce10f 100644 --- a/src/main/java/clap/server/domain/model/task/Task.java +++ b/src/main/java/clap/server/domain/model/task/Task.java @@ -4,7 +4,6 @@ import clap.server.domain.model.common.BaseTime; import clap.server.domain.model.member.Member; import clap.server.exception.ApplicationException; -import clap.server.exception.DomainException; import clap.server.exception.code.TaskErrorCode; import lombok.AccessLevel; import lombok.Getter; @@ -15,7 +14,7 @@ import java.time.format.DateTimeFormatter; import java.util.Objects; -import static clap.server.domain.policy.task.TaskValuePolicy.DEFAULT_PROCESSOR_ORDER_GAP; +import static clap.server.domain.policy.task.TaskPolicyConstants.DEFAULT_PROCESSOR_ORDER_GAP; @Getter @SuperBuilder @@ -47,7 +46,7 @@ public static Task createTask(Member member, Category category, String title, St } public void updateTask(Long requesterId, Category category, String title, String description) { - if(!Objects.equals(requesterId, this.requester.getMemberId() )) { + if (!Objects.equals(requesterId, this.requester.getMemberId())) { throw new ApplicationException(TaskErrorCode.NOT_A_REQUESTER); } this.category = category; @@ -63,12 +62,17 @@ public void setInitialProcessorOrder() { } public void updateTaskStatus(TaskStatus status) { - if (status == null) { - throw new DomainException(TaskErrorCode.INVALID_TASK_STATUS_TRANSITION); + if (status.equals(TaskStatus.COMPLETED)) { + this.finishedAt = LocalDateTime.now(); } this.taskStatus = status; } + public void terminateTask() { + this.taskStatus = TaskStatus.TERMINATED; + this.finishedAt = LocalDateTime.now(); + } + public void updateProcessor(Member processor) { this.processor = processor; } diff --git a/src/main/java/clap/server/domain/policy/task/TaskOrderCalculationPolicy.java b/src/main/java/clap/server/domain/policy/task/TaskOrderCalculationPolicy.java index 64f7ec29..c059b21a 100644 --- a/src/main/java/clap/server/domain/policy/task/TaskOrderCalculationPolicy.java +++ b/src/main/java/clap/server/domain/policy/task/TaskOrderCalculationPolicy.java @@ -5,7 +5,7 @@ import clap.server.exception.DomainException; import clap.server.exception.code.TaskErrorCode; -import static clap.server.domain.policy.task.TaskValuePolicy.DEFAULT_PROCESSOR_ORDER_GAP; +import static clap.server.domain.policy.task.TaskPolicyConstants.DEFAULT_PROCESSOR_ORDER_GAP; @Policy public class TaskOrderCalculationPolicy { diff --git a/src/main/java/clap/server/domain/policy/task/TaskValuePolicy.java b/src/main/java/clap/server/domain/policy/task/TaskPolicyConstants.java similarity index 60% rename from src/main/java/clap/server/domain/policy/task/TaskValuePolicy.java rename to src/main/java/clap/server/domain/policy/task/TaskPolicyConstants.java index 2663d656..5bd33802 100644 --- a/src/main/java/clap/server/domain/policy/task/TaskValuePolicy.java +++ b/src/main/java/clap/server/domain/policy/task/TaskPolicyConstants.java @@ -6,11 +6,18 @@ import java.util.List; @Getter -public class TaskValuePolicy { - public static final long DEFAULT_PROCESSOR_ORDER_GAP = (long) Math.pow(2,6); +public class TaskPolicyConstants { + public static final long DEFAULT_PROCESSOR_ORDER_GAP = (long) Math.pow(2, 6); public static final List TASK_BOARD_STATUS_FILTER = List.of( TaskStatus.IN_PROGRESS, TaskStatus.PENDING_COMPLETED, TaskStatus.COMPLETED); + + public static final List TASK_UPDATABLE_STATUS = List.of( + TaskStatus.REQUESTED, + TaskStatus.IN_PROGRESS, + TaskStatus.PENDING_COMPLETED, + TaskStatus.COMPLETED + ); } \ No newline at end of file diff --git a/src/main/java/clap/server/exception/code/TaskErrorCode.java b/src/main/java/clap/server/exception/code/TaskErrorCode.java index 8c8a2cf7..c7976c2b 100644 --- a/src/main/java/clap/server/exception/code/TaskErrorCode.java +++ b/src/main/java/clap/server/exception/code/TaskErrorCode.java @@ -17,6 +17,7 @@ public enum TaskErrorCode implements BaseErrorCode { INVALID_TASK_STATUS_TRANSITION(HttpStatus.BAD_REQUEST, "TASK_008", "유효하지 않은 작업 상태 전환입니다."), NOT_A_REVIEWER(HttpStatus.FORBIDDEN, "TASK_009", "작업 승인 및 수정 권한이 없습니다."), NOT_A_REQUESTER(HttpStatus.FORBIDDEN, "TASK_009", "작업 수정 권한이 없습니다."), + TASK_STATUS_NOT_ALLOWED(HttpStatus.BAD_REQUEST, "TASK_010", "변경할 수 없는 작업 상태입니다.") ; private final HttpStatus httpStatus; diff --git a/src/main/resources/db/migration/dev/V20250203245__Modify_Type_From_Task_History.sql b/src/main/resources/db/migration/dev/V20250203245__Modify_Type_From_Task_History.sql new file mode 100644 index 00000000..cbfe4dea --- /dev/null +++ b/src/main/resources/db/migration/dev/V20250203245__Modify_Type_From_Task_History.sql @@ -0,0 +1,2 @@ +alter table task_history + modify type enum ('TASK_TERMINATED', 'COMMENT', 'COMMENT_FILE', 'PROCESSOR_ASSIGNED', 'PROCESSOR_CHANGED', 'STATUS_SWITCHED') not null; \ No newline at end of file