Skip to content

Commit dfde0a5

Browse files
authored
Merge pull request #156 from prgrms-web-devcourse-final-project/develop
메인 머지 (10/3)
2 parents cd988fd + 01da591 commit dfde0a5

File tree

2 files changed

+77
-25
lines changed

2 files changed

+77
-25
lines changed

back/src/main/java/com/back/domain/roadmap/roadmap/service/MentorRoadmapService.java

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@
44
import com.back.domain.member.mentor.repository.MentorRepository;
55
import com.back.domain.roadmap.roadmap.dto.request.MentorRoadmapSaveRequest;
66
import com.back.domain.roadmap.roadmap.dto.request.RoadmapNodeRequest;
7-
import com.back.domain.roadmap.roadmap.dto.response.MentorRoadmapSaveResponse;
87
import com.back.domain.roadmap.roadmap.dto.response.MentorRoadmapResponse;
8+
import com.back.domain.roadmap.roadmap.dto.response.MentorRoadmapSaveResponse;
99
import com.back.domain.roadmap.roadmap.entity.MentorRoadmap;
1010
import com.back.domain.roadmap.roadmap.entity.RoadmapNode;
1111
import com.back.domain.roadmap.roadmap.repository.MentorRoadmapRepository;
1212
import com.back.domain.roadmap.roadmap.repository.RoadmapNodeRepository;
1313
import com.back.domain.roadmap.task.entity.Task;
14-
import com.back.domain.roadmap.task.repository.TaskRepository;
14+
import com.back.domain.roadmap.task.service.TaskService;
1515
import com.back.global.exception.ServiceException;
1616
import lombok.RequiredArgsConstructor;
1717
import lombok.extern.slf4j.Slf4j;
@@ -21,17 +21,15 @@
2121
import java.util.ArrayList;
2222
import java.util.List;
2323
import java.util.Map;
24-
import java.util.function.Function;
25-
import java.util.stream.Collectors;
2624

2725
@Service
2826
@RequiredArgsConstructor
2927
@Slf4j
3028
public class MentorRoadmapService {
3129
private final MentorRoadmapRepository mentorRoadmapRepository;
3230
private final RoadmapNodeRepository roadmapNodeRepository;
33-
private final TaskRepository taskRepository;
3431
private final MentorRepository mentorRepository;
32+
private final TaskService taskService;
3533

3634
// 멘토 로드맵 생성
3735
@Transactional
@@ -48,6 +46,9 @@ public MentorRoadmapSaveResponse create(Long mentorId, MentorRoadmapSaveRequest
4846
// 공통 검증(노드 개수, stepOrder 연속성)
4947
validateRequest(request);
5048

49+
// taskId가 null인 자유입력 Task를 자동으로 pending alias로 등록
50+
registerPendingAliasesForFreeInputTasks(request.nodes());
51+
5152
// MentorRoadmap 생성 및 저장 (로드맵 ID 확보)
5253
MentorRoadmap mentorRoadmap = new MentorRoadmap(mentor, request.title(), request.description());
5354
mentorRoadmap = mentorRoadmapRepository.save(mentorRoadmap);
@@ -106,6 +107,9 @@ public MentorRoadmapSaveResponse update(Long id, Long mentorId, MentorRoadmapSav
106107
// 공통 검증
107108
validateRequest(request);
108109

110+
// taskId가 null인 자유입력 Task를 자동으로 pending alias로 등록
111+
registerPendingAliasesForFreeInputTasks(request.nodes());
112+
109113
// 로드맵 기본 정보 수정
110114
mentorRoadmap.updateTitle(request.title());
111115
mentorRoadmap.updateDescription(request.description());
@@ -159,6 +163,16 @@ public void delete(Long roadmapId, Long mentorId) {
159163
log.info("멘토 로드맵 삭제 완료 - 멘토 ID: {}, 로드맵 ID: {}", mentorId, roadmapId);
160164
}
161165

166+
// taskId가 null인 자유입력 Task를 자동으로 pending alias로 등록
167+
private void registerPendingAliasesForFreeInputTasks(List<RoadmapNodeRequest> nodes) {
168+
for (RoadmapNodeRequest node : nodes) {
169+
if (node.taskId() == null && node.taskName() != null) {
170+
// TaskService를 통해 pending alias 자동 등록 (이미 존재하면 무시)
171+
taskService.createPendingAliasIfNotExists(node.taskName());
172+
}
173+
}
174+
}
175+
162176
// 로드맵 요청 공통 유효성 검증
163177
private void validateRequest(MentorRoadmapSaveRequest request) {
164178
if (request.nodes().isEmpty()) {
@@ -218,26 +232,8 @@ private Map<Long, Task> getValidatedTasksMap(List<RoadmapNodeRequest> nodeReques
218232
.distinct()
219233
.toList();
220234

221-
if (taskIds.isEmpty()) {
222-
return Map.of(); // 빈 맵 반환
223-
}
224-
225-
// 일괄 조회로 존재하는 Task들 확인
226-
List<Task> existingTasks = taskRepository.findAllById(taskIds);
227-
Map<Long, Task> existingTaskMap = existingTasks.stream()
228-
.collect(Collectors.toMap(Task::getId, Function.identity()));
229-
230-
// 존재하지 않는 TaskId 확인
231-
List<Long> missingTaskIds = taskIds.stream()
232-
.filter(taskId -> !existingTaskMap.containsKey(taskId))
233-
.toList();
234-
235-
if (!missingTaskIds.isEmpty()) {
236-
throw new ServiceException("404",
237-
String.format("존재하지 않는 Task ID: %s", missingTaskIds));
238-
}
239-
240-
return existingTaskMap;
235+
// TaskService에 위임하여 검증 및 조회
236+
return taskService.validateAndGetTasks(taskIds);
241237
}
242238

243239

back/src/main/java/com/back/domain/roadmap/task/service/TaskService.java

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import org.springframework.transaction.annotation.Transactional;
1414

1515
import java.util.*;
16+
import java.util.stream.Collectors;
1617

1718
@Service
1819
@RequiredArgsConstructor
@@ -44,6 +45,10 @@ public List<Task> searchByKeyword(String keyword){
4445
return taskRepository.findTasksByKeyword(keyword);
4546
}
4647

48+
/**
49+
* 사용자가 명시적으로 새 Task를 제안할 때 사용
50+
* 이미 존재하는 경우 예외를 던져 사용자에게 알림
51+
*/
4752
@Transactional
4853
public TaskAlias createPendingAlias(String taskName){
4954
// Task나 TaskAlias에 이미 존재하는 이름인지 검증
@@ -54,6 +59,57 @@ public TaskAlias createPendingAlias(String taskName){
5459
return taskAliasRepository.save(pendingAlias);
5560
}
5661

62+
/**
63+
* 로드맵 생성 시 자동으로 pending alias를 등록할 때 사용
64+
* 이미 존재하는 경우 무시 (다른 사용자가 이미 제안했을 수 있음)
65+
*/
66+
@Transactional
67+
public void createPendingAliasIfNotExists(String taskName) {
68+
// TaskAlias에 이미 존재하는지 확인
69+
Optional<TaskAlias> existingAlias = taskAliasRepository.findByNameIgnoreCase(taskName);
70+
if (existingAlias.isPresent()) {
71+
return; // 이미 존재하면 무시
72+
}
73+
74+
// Task에 이미 존재하는지 확인
75+
Optional<Task> existingTask = taskRepository.findByNameIgnoreCase(taskName);
76+
if (existingTask.isPresent()) {
77+
return; // 이미 존재하면 무시
78+
}
79+
80+
// 존재하지 않으면 새로운 pending alias 생성
81+
TaskAlias pendingAlias = new TaskAlias(taskName);
82+
taskAliasRepository.save(pendingAlias);
83+
}
84+
85+
/**
86+
* Task ID 목록을 검증하고 Map으로 반환 (로드맵 생성 시 사용)
87+
* 존재하지 않는 Task ID가 있으면 예외 발생
88+
*/
89+
@Transactional(readOnly = true)
90+
public Map<Long, Task> validateAndGetTasks(List<Long> taskIds) {
91+
if (taskIds == null || taskIds.isEmpty()) {
92+
return Map.of(); // 빈 맵 반환
93+
}
94+
95+
// 일괄 조회로 존재하는 Task들 확인
96+
List<Task> existingTasks = taskRepository.findAllById(taskIds);
97+
Map<Long, Task> existingTaskMap = existingTasks.stream()
98+
.collect(Collectors.toMap(Task::getId, task -> task));
99+
100+
// 존재하지 않는 TaskId 확인
101+
List<Long> missingTaskIds = taskIds.stream()
102+
.filter(taskId -> !existingTaskMap.containsKey(taskId))
103+
.toList();
104+
105+
if (!missingTaskIds.isEmpty()) {
106+
throw new ServiceException("404",
107+
String.format("존재하지 않는 Task ID: %s", missingTaskIds));
108+
}
109+
110+
return existingTaskMap;
111+
}
112+
57113
// === 관리자용 기능들 ===
58114
// Pending alias 목록 조회 (페이징)
59115
@Transactional(readOnly = true)

0 commit comments

Comments
 (0)