Skip to content

Commit ead5258

Browse files
authored
Merge pull request #303 from TaskFlow-CLAP/CLAP-267
CLAP-267 작업 보드 조회에서 하나의 작업만 있을 때의 순서/상태 변경 case 추가
2 parents 257ef4e + eb4d03d commit ead5258

File tree

4 files changed

+89
-28
lines changed

4 files changed

+89
-28
lines changed

src/main/java/clap/server/adapter/outbound/persistense/TaskPersistenceAdapter.java

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -81,14 +81,26 @@ public Page<Task> findAllTasks(Pageable pageable, FilterTaskListRequest filterTa
8181
}
8282

8383
@Override
84-
public Optional<Task> findPrevOrderTaskByProcessorIdAndStatus(Long processorId, TaskStatus taskStatus, Long processorOrder) {
85-
Optional<TaskEntity> taskEntity = taskRepository.findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderLessThanOrderByProcessorOrderDesc(processorId, taskStatus, processorOrder);
84+
public Optional<Task> findPrevOrderTaskByProcessorOrderAndStatus(Long processorId, TaskStatus taskStatus, Long processorOrder) {
85+
Optional<TaskEntity> taskEntity = taskRepository.findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderLessThanOrderByProcessorOrderAsc(processorId, taskStatus, processorOrder);
8686
return taskEntity.map(taskPersistenceMapper::toDomain);
8787
}
8888

8989
@Override
90-
public Optional<Task> findNextOrderTaskByProcessorIdAndStatus(Long processorId, TaskStatus taskStatus, Long processorOrder) {
91-
Optional<TaskEntity> taskEntity = taskRepository.findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderAfterOrderByProcessorOrderDesc(processorId, taskStatus, processorOrder);
90+
public Optional<Task> findNextOrderTaskByProcessorOrderAndStatus(Long processorId, TaskStatus taskStatus, Long processorOrder) {
91+
Optional<TaskEntity> taskEntity = taskRepository.findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderAfterOrderByProcessorOrderAsc(processorId, taskStatus, processorOrder);
92+
return taskEntity.map(taskPersistenceMapper::toDomain);
93+
}
94+
95+
@Override
96+
public Optional<Task> findPrevOrderTaskByTaskIdAndStatus(Long processorId, TaskStatus taskStatus, Long taskId) {
97+
Optional<TaskEntity> taskEntity = taskRepository.findTopByProcessor_MemberIdAndTaskStatusAndTaskIdLessThanOrderByTaskIdDesc(processorId, taskStatus, taskId);
98+
return taskEntity.map(taskPersistenceMapper::toDomain);
99+
}
100+
101+
@Override
102+
public Optional<Task> findNextOrderTaskByTaskIdAndStatus(Long processorId, TaskStatus taskStatus, Long taskId) {
103+
Optional<TaskEntity> taskEntity = taskRepository.findTopByProcessor_MemberIdAndTaskStatusAndTaskIdGreaterThanOrderByTaskIdAsc(processorId, taskStatus, taskId);
92104
return taskEntity.map(taskPersistenceMapper::toDomain);
93105
}
94106

src/main/java/clap/server/adapter/outbound/persistense/repository/task/TaskRepository.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ public interface TaskRepository extends JpaRepository<TaskEntity, Long>, TaskCus
2424

2525
@Query("select t from TaskEntity t join fetch t.processor p" +
2626
" where t.updatedAt between :updatedAtAfter and :updatedAtBefore")
27-
2827
List<TaskEntity> findYesterdayTaskByUpdatedAtIsBetween(
2928
@Param("updatedAtAfter") LocalDateTime updatedAtAfter,
3029
@Param("updatedAtBefore") LocalDateTime updatedAtBefore
@@ -49,14 +48,17 @@ List<TaskEntity> findTasksWithTaskStatusAndCompletedAt(
4948

5049
Optional<TaskEntity> findByTaskIdAndTaskStatus(Long id, TaskStatus status);
5150

52-
Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderLessThanOrderByProcessorOrderDesc(Long processorId, TaskStatus taskStatus, Long processorOrder);
51+
Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderLessThanOrderByProcessorOrderAsc(Long processorId, TaskStatus taskStatus, Long processorOrder);
5352

54-
Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderAfterOrderByProcessorOrderDesc(
53+
Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndProcessorOrderAfterOrderByProcessorOrderAsc(
5554
Long processorId, TaskStatus taskStatus, Long processorOrder);
5655

5756
@Query("SELECT t FROM TaskEntity t JOIN FETCH t.processor p WHERE (:memberId IS NULL OR p.memberId = :memberId) ")
5857
Page<TeamTaskResponse> findTeamStatus(@Param("memberId") Long memberId, FilterTeamStatusRequest filter, Pageable pageable);
5958

59+
Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndTaskIdLessThanOrderByTaskIdDesc(Long processorId, TaskStatus taskStatus, Long taskId);
60+
61+
Optional<TaskEntity> findTopByProcessor_MemberIdAndTaskStatusAndTaskIdGreaterThanOrderByTaskIdAsc(Long processorId, TaskStatus status, Long taskId);
6062

6163

6264
}

src/main/java/clap/server/application/port/outbound/task/LoadTaskPort.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,13 @@ public interface LoadTaskPort {
2828

2929
Optional<Task> findByIdAndStatus(Long id, TaskStatus status);
3030

31-
Optional<Task> findPrevOrderTaskByProcessorIdAndStatus(Long processorId, TaskStatus taskStatus, Long processorOrder);
31+
Optional<Task> findPrevOrderTaskByProcessorOrderAndStatus(Long processorId, TaskStatus taskStatus, Long processorOrder);
3232

33-
Optional<Task> findNextOrderTaskByProcessorIdAndStatus(Long processorId, TaskStatus taskStatus, Long processorOrder);
33+
Optional<Task> findNextOrderTaskByProcessorOrderAndStatus(Long processorId, TaskStatus taskStatus, Long processorOrder);
34+
35+
Optional<Task> findPrevOrderTaskByTaskIdAndStatus(Long processorId, TaskStatus taskStatus, Long taskId);
36+
37+
Optional<Task> findNextOrderTaskByTaskIdAndStatus(Long processorId, TaskStatus taskStatus, Long taskId);
3438

3539
List<Task> findTaskBoardByFilter(Long processorId, List<TaskStatus> statuses, LocalDateTime untilDateTime, FilterTaskBoardRequest request);
3640

src/main/java/clap/server/application/service/task/UpdateTaskBoardService.java

Lines changed: 62 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package clap.server.application.service.task;
22

33
import clap.server.adapter.inbound.web.dto.task.request.UpdateTaskOrderRequest;
4+
import clap.server.adapter.outbound.persistense.entity.notification.constant.NotificationType;
45
import clap.server.adapter.outbound.persistense.entity.task.constant.TaskStatus;
56
import clap.server.application.port.inbound.domain.MemberService;
67
import clap.server.application.port.inbound.domain.TaskService;
78
import clap.server.application.port.inbound.task.UpdateTaskBoardUsecase;
89
import clap.server.application.port.inbound.task.UpdateTaskOrderAndStatusUsecase;
910
import clap.server.application.port.outbound.task.LoadTaskPort;
11+
import clap.server.application.service.webhook.SendNotificationService;
1012
import clap.server.common.annotation.architecture.ApplicationService;
1113
import clap.server.domain.model.member.Member;
1214
import clap.server.domain.model.task.Task;
@@ -19,13 +21,16 @@
1921
import lombok.extern.slf4j.Slf4j;
2022
import org.springframework.transaction.annotation.Transactional;
2123

24+
import java.util.List;
25+
2226
@Slf4j
2327
@ApplicationService
2428
@RequiredArgsConstructor
2529
class UpdateTaskBoardService implements UpdateTaskBoardUsecase, UpdateTaskOrderAndStatusUsecase {
2630
private final MemberService memberService;
2731
private final TaskService taskService;
2832
private final LoadTaskPort loadTaskPort;
33+
private final SendNotificationService sendNotificationService;
2934

3035
private final TaskOrderCalculationPolicy taskOrderCalculationPolicy;
3136
private final ProcessorValidationPolicy processorValidationPolicy;
@@ -53,15 +58,15 @@ public void updateTaskOrder(Long processorId, UpdateTaskOrderRequest request) {
5358
if (request.prevTaskId() == 0) {
5459
Task nextTask = findByIdAndStatus(request.nextTaskId(), targetTask.getTaskStatus());
5560
// 해당 상태에서 바로 앞에 있는 작업 찾기
56-
Task prevTask = loadTaskPort.findPrevOrderTaskByProcessorIdAndStatus(processorId, targetTask.getTaskStatus(), nextTask.getProcessorOrder()).orElse(null);
61+
Task prevTask = loadTaskPort.findPrevOrderTaskByProcessorOrderAndStatus(processorId, targetTask.getTaskStatus(), nextTask.getProcessorOrder()).orElse(null);
5762
long newOrder = taskOrderCalculationPolicy.calculateOrderForTop(prevTask, nextTask);
5863
updateNewTaskOrder(targetTask, newOrder);
5964
}
6065
// 가장 하위로 이동
6166
else if (request.nextTaskId() == 0) {
6267
Task prevTask = findByIdAndStatus(request.prevTaskId(), targetTask.getTaskStatus());
6368
// 해당 상태에서 바로 뒤에 있는 작업 찾기
64-
Task nextTask = loadTaskPort.findNextOrderTaskByProcessorIdAndStatus(processorId, targetTask.getTaskStatus(), prevTask.getProcessorOrder()).orElse(null);
69+
Task nextTask = loadTaskPort.findNextOrderTaskByProcessorOrderAndStatus(processorId, targetTask.getTaskStatus(), prevTask.getProcessorOrder()).orElse(null);
6570
long newOrder = taskOrderCalculationPolicy.calculateOrderForBottom(prevTask, nextTask);
6671
updateNewTaskOrder(targetTask, newOrder);
6772
} else {
@@ -98,49 +103,87 @@ public void updateTaskOrderAndStatus(Long processorId, UpdateTaskOrderRequest re
98103
Task targetTask = taskService.findById(request.targetTaskId());
99104
processorValidationPolicy.validateProcessor(processorId, targetTask);
100105

101-
if (request.prevTaskId() == 0) {
102-
Task nextTask = findByIdAndStatus(request.nextTaskId(), targetStatus);
106+
Task updatedTask;
107+
Task prevTask;
108+
Task nextTask;
109+
110+
// 조회된 작업 보드에서 하나의 작업만 존재하고, 이 작업을 이동할 때
111+
if (request.prevTaskId() == 0 && request.nextTaskId() == 0) {
112+
113+
// 요청 시간 기준으로 가장 가장 근접한 이전의 Task를 조회
114+
prevTask = loadTaskPort.findPrevOrderTaskByTaskIdAndStatus(processorId, targetStatus, targetTask.getTaskId()).orElse(null);
115+
if (prevTask != null) {
116+
// 이전 Task가 있다면 바로 다음의 Task 조회
117+
nextTask = loadTaskPort.findNextOrderTaskByProcessorOrderAndStatus(processorId, targetStatus, prevTask.getProcessorOrder()).orElse(null);
118+
} // 요청 시간 기준으로 가장 가장 근접한 이후의 Task를 조회
119+
else
120+
nextTask = loadTaskPort.findNextOrderTaskByTaskIdAndStatus(processorId, targetStatus, targetTask.getTaskId()).orElse(null);
121+
122+
// 하나의 task만 존재할 경우 상태만 update
123+
if (prevTask == null && nextTask == null) {
124+
targetTask.updateTaskStatus(targetStatus);
125+
updatedTask = taskService.upsert(targetTask);
126+
} else if (prevTask == null) {
127+
long newOrder = taskOrderCalculationPolicy.calculateOrderForBottom(null, nextTask);
128+
updatedTask = updateNewTaskOrderAndStatus(targetStatus, targetTask, newOrder);
129+
} else if (nextTask == null) {
130+
long newOrder = taskOrderCalculationPolicy.calculateOrderForBottom(prevTask, null);
131+
updatedTask = updateNewTaskOrderAndStatus(targetStatus, targetTask, newOrder);
132+
} else {
133+
long newOrder = taskOrderCalculationPolicy.calculateNewProcessorOrder(prevTask.getProcessorOrder(), nextTask.getProcessorOrder());
134+
updatedTask = updateNewTaskOrderAndStatus(targetStatus, targetTask, newOrder);
135+
}
136+
} else if (request.prevTaskId() == 0) {
137+
nextTask = findByIdAndStatus(request.nextTaskId(), targetStatus);
103138
// 해당 상태에서 바로 앞 있는 작업 찾기
104-
Task prevTask = loadTaskPort.findPrevOrderTaskByProcessorIdAndStatus(processorId, targetStatus, nextTask.getProcessorOrder()).orElse(null);
139+
prevTask = loadTaskPort.findPrevOrderTaskByProcessorOrderAndStatus(processorId, targetStatus, nextTask.getProcessorOrder()).orElse(null);
105140
long newOrder = taskOrderCalculationPolicy.calculateOrderForTop(prevTask, nextTask);
106-
updateNewTaskOrderAndStatus(targetStatus, targetTask, newOrder);
141+
updatedTask = updateNewTaskOrderAndStatus(targetStatus, targetTask, newOrder);
107142
} else if (request.nextTaskId() == 0) {
108-
Task prevTask = findByIdAndStatus(request.prevTaskId(), targetStatus);
143+
prevTask = findByIdAndStatus(request.prevTaskId(), targetStatus);
109144
// 해당 상태에서 바로 뒤에 있는 작업 찾기
110-
Task nextTask = loadTaskPort.findNextOrderTaskByProcessorIdAndStatus(processorId, targetStatus, prevTask.getProcessorOrder()).orElse(null);
145+
nextTask = loadTaskPort.findNextOrderTaskByProcessorOrderAndStatus(processorId, targetStatus, prevTask.getProcessorOrder()).orElse(null);
111146
long newOrder = taskOrderCalculationPolicy.calculateOrderForBottom(prevTask, nextTask);
112-
updateNewTaskOrderAndStatus(targetStatus, targetTask, newOrder);
147+
updatedTask = updateNewTaskOrderAndStatus(targetStatus, targetTask, newOrder);
113148
} else {
114-
Task prevTask = findByIdAndStatus(request.prevTaskId(), targetStatus);
115-
Task nextTask = findByIdAndStatus(request.nextTaskId(), targetStatus);
149+
prevTask = findByIdAndStatus(request.prevTaskId(), targetStatus);
150+
nextTask = findByIdAndStatus(request.nextTaskId(), targetStatus);
116151
long newOrder = taskOrderCalculationPolicy.calculateNewProcessorOrder(prevTask.getProcessorOrder(), nextTask.getProcessorOrder());
117-
updateNewTaskOrderAndStatus(targetStatus, targetTask, newOrder);
152+
updatedTask = updateNewTaskOrderAndStatus(targetStatus, targetTask, newOrder);
118153
}
154+
155+
//TODO: 최종 단계에서 주석 처리 해제
156+
//publishNotification(targetTask, NotificationType.STATUS_SWITCHED, String.valueOf(updatedTask.getTaskStatus()));
119157
}
120158

121159
/**
122160
* 작업의 상태와 순서를 업데이트하는 메서드
123161
*/
124-
private void updateNewTaskOrderAndStatus(TaskStatus targetStatus, Task targetTask, long newOrder) {
162+
private Task updateNewTaskOrderAndStatus(TaskStatus targetStatus, Task targetTask, long newOrder) {
125163
targetTask.updateProcessorOrder(newOrder);
126164
targetTask.updateTaskStatus(targetStatus);
127-
taskService.upsert(targetTask);
165+
return taskService.upsert(targetTask);
128166
}
129167

130168
/**
131169
* 순서 변경 요청의 유효성을 검증하는 메서드
132170
*/
133171
public void validateRequest(UpdateTaskOrderRequest request, TaskStatus targetStatus) {
134-
// 이전 및 다음 작업 ID가 모두 0인 경우 예외 발생
135-
if (request.prevTaskId() == 0 && request.nextTaskId() == 0) {
136-
throw new ApplicationException(TaskErrorCode.INVALID_TASK_STATUS_TRANSITION);
137-
}
138-
139172
// 타겟 상태가 유효한지 검증
140173
if (targetStatus != null && !TaskPolicyConstants.TASK_BOARD_STATUS_FILTER.contains(targetStatus)) {
141174
throw new ApplicationException(TaskErrorCode.INVALID_TASK_STATUS_TRANSITION);
142175
}
143176
}
144177

178+
private void publishNotification(Task task, NotificationType notificationType, String message) {
179+
List<Member> receivers = List.of(task.getRequester(), task.getProcessor());
180+
receivers.forEach(receiver -> {
181+
sendNotificationService.sendPushNotification(receiver, notificationType,
182+
task, message, null);
183+
});
184+
sendNotificationService.sendAgitNotification(notificationType,
185+
task, message, null);
186+
}
187+
145188
}
146189

0 commit comments

Comments
 (0)