Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static record Details(
) {}

public static record TaskDetails(
String newValue
String value
) {}

public static record CommentDetails(
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -41,9 +43,11 @@ public class ChangeTaskController {
public ResponseEntity<UpdateTaskResponse> 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 = "작업 처리자 변경")
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ public enum TaskHistoryType {
COMMENT_FILE("댓글 첨부파일"),
STATUS_SWITCHED("상태 전환"),
PROCESSOR_ASSIGNED("처리자 할당"),
PROCESSOR_CHANGED("처리자 변경");
PROCESSOR_CHANGED("처리자 변경"),
TASK_TERMINATED("작업 종료됨");

private final String description;
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static FindTaskHistoryResponse toFindTaskHistoryResponse(List<TaskHistory
null,
null
);
case STATUS_SWITCHED -> new FindTaskHistoryResponse.Details(
case STATUS_SWITCHED, TASK_TERMINATED -> new FindTaskHistoryResponse.Details(
new FindTaskHistoryResponse.TaskDetails(
taskHistory.getTaskModificationInfo().getModifiedStatus()
),
Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package clap.server.application.port.inbound.task;

public interface TerminateTaskUsecase {
void terminateTask(Long memberId, Long taskId, String reason);
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ public ApprovalTaskResponse approvalTaskByReviewer(Long reviewerId, Long taskId,
List<Member> receivers = List.of(reviewer, processor);
publishNotification(receivers, task);

return TaskResponseMapper.toApprovalTaskResponse(commandTaskPort.save(task));
return TaskResponseMapper.toApprovalTaskResponse(taskService.upsert(task));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -18,29 +18,29 @@

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;

@Override
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<Task> tasks = loadTaskPort.findByProcessorAndStatus(processorId, TaskValuePolicy.TASK_BOARD_STATUS_FILTER, untilDateTime, pageable);
Slice<Task> tasks = loadTaskPort.findByProcessorAndStatus(processorId, TaskPolicyConstants.TASK_BOARD_STATUS_FILTER, untilDateTime, pageable);
return TaskResponseMapper.toSliceTaskItemResponse(tasks);
}

@Override
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<Task> tasks = loadTaskPort.findTaskBoardByFilter(processorId, TaskValuePolicy.TASK_BOARD_STATUS_FILTER, untilDateTime, request, pageable);
Slice<Task> tasks = loadTaskPort.findTaskBoardByFilter(processorId, TaskPolicyConstants.TASK_BOARD_STATUS_FILTER, untilDateTime, request, pageable);
return TaskResponseMapper.toSliceTaskItemResponse(tasks);
}
}
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -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);
}

/**
Expand Down Expand Up @@ -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);
}

/**
Expand All @@ -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);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
Expand All @@ -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);
}

Expand Down
Loading