Skip to content

Commit c9f1a92

Browse files
authored
메인 머지(10/12) Merge pull request #196
메인 머지(10/12) - API 연동 테스트용 데이터 추가
2 parents bb9c696 + 6c844c8 commit c9f1a92

File tree

6 files changed

+937
-107
lines changed

6 files changed

+937
-107
lines changed

back/src/main/java/com/back/domain/roadmap/roadmap/controller/JobRoadmapController.java

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,36 @@ public class JobRoadmapController {
2020

2121
@GetMapping
2222
@Operation(
23-
summary = "직업 로드맵 다건 조회",
24-
description = "직업 로드맵 목록을 페이징과 키워드 검색으로 조회합니다."
23+
summary = "직업 로드맵 목록 조회",
24+
description = """
25+
### 개요
26+
모든 직업의 로드맵 목록을 페이징과 키워드 검색으로 조회합니다.
27+
28+
### 쿼리 파라미터
29+
- `page`: 페이지 번호 (0부터 시작, 기본값: 0)
30+
- `size`: 페이지 크기 (기본값: 10)
31+
- `keyword`: 검색 키워드 (선택, 직업명으로 검색)
32+
33+
### 반환 정보
34+
각 직업 로드맵의 요약 정보:
35+
- id: 직업 로드맵 ID
36+
- jobName: 직업명
37+
- jobDescription: 직업 설명
38+
39+
### 응답 형식
40+
- content: 직업 로드맵 목록
41+
- totalElements: 전체 개수
42+
- totalPages: 전체 페이지 수
43+
- number: 현재 페이지 번호
44+
- size: 페이지 크기
45+
46+
### 응답 코드
47+
- **200**: 조회 성공
48+
49+
### 참고
50+
- 인증 불필요 (누구나 조회 가능)
51+
- 키워드는 직업명(jobName)에 대해 부분 일치 검색
52+
"""
2553
)
2654
public RsData<JobRoadmapPagingResponse> getJobRoadmaps(
2755
@RequestParam(defaultValue = "0") int page,
@@ -37,7 +65,71 @@ public RsData<JobRoadmapPagingResponse> getJobRoadmaps(
3765
@GetMapping("/{id}")
3866
@Operation(
3967
summary = "직업 로드맵 상세 조회",
40-
description = "특정 직업 로드맵의 상세 정보(직업 정보 + 모든 노드)를 조회합니다."
68+
description = """
69+
### 개요
70+
특정 직업의 통합 로드맵을 트리 구조로 조회합니다.
71+
여러 멘토의 멘토 로드맵을 통합하여 생성된 로드맵입니다.
72+
73+
### 직업 로드맵이란?
74+
- 동일 직업의 멘토들의 로드맵을 통합한 결과
75+
- 비선형 구조 (트리형) - 다양한 학습 경로 표현
76+
- 멘토들의 빈도, 순서 패턴, 연결 관계를 분석하여 생성
77+
- 주기적으로 자동 업데이트 (멘토 로드맵 변경 시)
78+
79+
### 반환 정보
80+
81+
**로드맵 기본 정보:**
82+
- id, jobId, jobName: 직업 정보
83+
- totalNodeCount: 전체 노드 개수
84+
- createdDate, modifiedDate: 생성/수정일
85+
86+
**노드 정보 (트리 구조):**
87+
88+
각 노드는 다음 정보를 포함합니다:
89+
90+
*기본 정보:*
91+
- id, parentId, childIds: 트리 구조 정보
92+
- taskId, taskName: Task 정보
93+
- level: 트리 깊이 (0: 루트, 1: 1단계 자식...)
94+
- stepOrder: 같은 부모 내 순서
95+
96+
*학습 정보 (여러 멘토의 정보 통합):*
97+
- learningAdvice: 학습 조언 통합
98+
- recommendedResources: 추천 자료 통합
99+
- learningGoals: 학습 목표 통합
100+
- difficulty: 평균 난이도 (1-5)
101+
- importance: 평균 중요도 (1-5)
102+
- estimatedHours: 평균 예상 학습 시간
103+
104+
*통계 정보:*
105+
- weight: 노드 가중치 (빈도, 위치, 연결성 기반)
106+
- mentorCount: 이 노드를 사용한 멘토 수
107+
- totalMentorCount: 해당 직업의 전체 멘토 수
108+
- mentorCoverageRatio: 커버리지 비율 (0.0 ~ 1.0)
109+
- isEssential: 필수 노드 여부 (50% 이상)
110+
- essentialLevel:
111+
- "CORE": 80% 이상의 멘토가 선택 (핵심 필수)
112+
- "COMMON": 50% 이상의 멘토가 선택 (일반 필수)
113+
- "OPTIONAL": 50% 미만의 멘토가 선택 (선택)
114+
115+
*자식 노드:*
116+
- children: 자식 노드 목록 (재귀 구조)
117+
118+
### 응답 구조
119+
- 루트 노드들만 최상위에 반환
120+
- 각 노드의 children 필드에 자식 노드들이 재귀적으로 포함
121+
- 전체 트리 구조를 한 번에 조회 가능
122+
123+
### 응답 코드
124+
- **200**: 조회 성공
125+
- **404**: 직업 로드맵을 찾을 수 없음
126+
127+
### 참고
128+
- 로그인한 사용자만 조회 가능
129+
- 통합 알고리즘: 빈도수(40%), 멘토 커버리지(30%), 위치(20%), 연결성(10%)
130+
- essentialLevel로 필수/선택 경로 구분 가능
131+
- 통계 정보를 활용해 학습 우선순위 판단 가능
132+
"""
41133
)
42134
public RsData<JobRoadmapResponse> getJobRoadmapById(@PathVariable Long id) {
43135
JobRoadmapResponse roadmap = jobRoadmapService.getJobRoadmapById(id);

back/src/main/java/com/back/domain/roadmap/roadmap/controller/MentorRoadmapController.java

Lines changed: 136 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,51 @@ public class MentorRoadmapController {
2727
@Operation(
2828
summary = "멘토 로드맵 생성",
2929
description = """
30-
멘토가 자신의 커리어 로드맵을 생성합니다.
31-
- 멘토는 하나의 로드맵만 생성 가능
32-
- TaskId는 nullable (DB에 있는 Task 중 선택하게 하고, 원하는 Task 없는 경우 null 가능)
33-
- TaskName은 필수 (표시용 이름. DB에 있는 Task 선택시 해당 taskName으로 저장, 없는 경우 입력한 이름으로 저장)
34-
- stepOrder는 1부터 시작하는 연속된 숫자로, 로드맵 상 노드의 순서를 나타냄
35-
- 노드들은 stepOrder 순으로 자동 정렬(멘토 로드맵은 선형으로만 구성)
36-
37-
사용 시나리오:
38-
1. TaskController로 Task 검색
39-
2. Task 선택 시 TaskId와 TaskName 획득
40-
3. Task 없는 경우 TaskId는 null, TaskName 직접 입력
41-
4. description(Task에 대한 멘토의 경험, 조언, 학습 방법 등) 입력
30+
### 개요
31+
멘토가 자신의 커리어 여정을 단계별로 기록한 로드맵을 생성합니다.
32+
33+
### 제약 사항
34+
- **멘토당 1개의 로드맵만 생성 가능** (중복 시 409 에러)
35+
- **최소 1개 이상의 노드** 필요
36+
- **stepOrder는 1부터 시작하는 연속된 숫자** (예: 1,2,3,...)
37+
- **멘토 권한(MENTOR)** 필요
38+
39+
### 노드(RoadmapNode) 구성
40+
41+
**필수 필드:**
42+
- `taskName`: 기술/단계 이름 (최대 100자)
43+
- `stepOrder`: 로드맵 상 순서 (1부터 시작, 중복 불가)
44+
45+
**선택 필드:**
46+
- `taskId`: 표준 Task ID (nullable)
47+
- Task 검색(`/tasks/search`)으로 선택 가능
48+
- null이면 자동으로 pending alias 등록 (관리자 승인 대기)
49+
- `learningAdvice`: 학습 조언/방법 (최대 2000자)
50+
- `recommendedResources`: 추천 자료 (최대 2000자)
51+
- `learningGoals`: 학습 목표 (최대 1000자)
52+
- `difficulty`: 난이도 (1-5)
53+
- `importance`: 중요도 (1-5)
54+
- `hoursPerDay`: 하루 학습 시간
55+
- `weeks`: 학습 주차
56+
- `estimatedHours`: 자동 계산 (hoursPerDay × weeks × 7)
57+
58+
### 사용 시나리오
59+
1. `/tasks/search`로 Task 검색
60+
2. 원하는 Task 선택 → taskId, taskName 획득
61+
3. 원하는 Task 없으면 → taskId는 null, taskName 직접 입력
62+
4. 각 단계별 학습 정보 입력 (조언, 자료, 목표 등)
63+
5. 로드맵 생성 요청
64+
65+
### 응답 코드
66+
- **201**: 생성 성공
67+
- **400**: 유효성 검증 실패 (stepOrder 불연속/중복 등)
68+
- **403**: 멘토 권한 없음
69+
- **404**: 존재하지 않는 taskId 참조
70+
- **409**: 이미 로드맵 존재
71+
72+
### 참고
73+
- 멘토 로드맵은 선형 구조 (순차적 학습 경로)
74+
- 로드맵 생성 후 직업 로드맵 통합 이벤트 발행 (비동기)
4275
"""
4376
)
4477
@PostMapping
@@ -58,12 +91,29 @@ public RsData<MentorRoadmapSaveResponse> create(@Valid @RequestBody MentorRoadma
5891
@Operation(
5992
summary = "멘토 로드맵 상세 조회 (로드맵 ID)",
6093
description = """
61-
로드맵 ID로 멘토 로드맵 상세 정보를 조회합니다.
62-
로그인한 사용자만 조회할 수 있습니다.
94+
### 개요
95+
로드맵 ID로 멘토 로드맵의 전체 정보를 조회합니다.
6396
64-
반환 정보:
65-
- 로드맵 기본 정보 (로드맵 ID, 멘토 ID, 제목, 설명, 생성일, 수정일 등)
97+
### 권한
98+
- 로그인한 모든 사용자 조회 가능
99+
100+
### 반환 정보
101+
- 로드맵 기본 정보 (id, mentorId, title, description)
66102
- 모든 노드 정보 (stepOrder 순으로 정렬)
103+
- 생성일, 수정일
104+
105+
### 노드 정보 구조
106+
각 노드는 다음 정보를 포함합니다:
107+
- taskId, taskName: Task 정보
108+
- learningAdvice, recommendedResources, learningGoals: 학습 가이드
109+
- difficulty, importance: 난이도/중요도 (1-5)
110+
- hoursPerDay, weeks, estimatedHours: 학습 시간 정보
111+
- stepOrder: 로드맵 상 순서
112+
113+
### 응답 코드
114+
- **200**: 조회 성공
115+
- **401**: 인증 필요
116+
- **404**: 로드맵을 찾을 수 없음
67117
"""
68118
)
69119
@GetMapping("/{id}")
@@ -81,14 +131,25 @@ public RsData<MentorRoadmapResponse> getById(@PathVariable Long id) {
81131
@Operation(
82132
summary = "멘토 로드맵 상세 조회 (멘토 ID)",
83133
description = """
84-
멘토 ID로 해당 멘토의 로드맵 상세 정보를 조회합니다.
85-
로그인한 사용자만 조회할 수 있습니다.
134+
### 개요
135+
멘토 ID로 해당 멘토의 로드맵 전체 정보를 조회합니다.
136+
137+
### 권한
138+
- 로그인한 모든 사용자 조회 가능
86139
87-
반환 정보:
88-
- 로드맵 기본 정보 (로드맵 ID, 멘토 ID, 제목, 설명, 생성일, 수정일 등)
140+
### 반환 정보
141+
- 로드맵 기본 정보 (id, mentorId, title, description)
89142
- 모든 노드 정보 (stepOrder 순으로 정렬)
143+
- 생성일, 수정일
90144
91-
주의: 멘토가 로드맵을 생성하지 않았다면 404 에러가 발생합니다.
145+
### 응답 코드
146+
- **200**: 조회 성공
147+
- **401**: 인증 필요
148+
- **404**: 해당 멘토의 로드맵을 찾을 수 없음
149+
150+
### 참고
151+
- 멘토가 로드맵을 생성하지 않았으면 404 에러 발생
152+
- 멘토 ID는 Member ID가 아닌 Mentor 엔티티의 ID입니다
92153
"""
93154
)
94155
@GetMapping("/mentor/{mentorId}")
@@ -103,7 +164,36 @@ public RsData<MentorRoadmapResponse> getByMentorId(@PathVariable Long mentorId)
103164
);
104165
}
105166

106-
@Operation(summary = "멘토 로드맵 수정", description = "로드맵 ID로 로드맵을 찾아 수정합니다. 본인이 생성한 로드맵만 수정할 수 있습니다.")
167+
@Operation(
168+
summary = "멘토 로드맵 수정",
169+
description = """
170+
### 개요
171+
로드맵 ID로 로드맵을 찾아 전체 내용을 수정합니다.
172+
173+
### 권한
174+
- **본인이 생성한 로드맵만 수정 가능** (타인 수정 시 403 에러)
175+
- 멘토 권한(MENTOR) 필요
176+
177+
### 수정 방식
178+
- **전체 교체 방식**: 기존 노드를 모두 삭제하고 새 노드로 교체
179+
- 로드맵 제목, 설명도 함께 수정
180+
- 생성 API와 동일한 유효성 검증 적용
181+
182+
### 요청 형식
183+
- 생성 API와 동일한 Request Body 사용
184+
- 모든 노드를 다시 전송해야 함 (부분 수정 불가)
185+
186+
### 응답 코드
187+
- **200**: 수정 성공
188+
- **400**: 유효성 검증 실패
189+
- **403**: 본인의 로드맵이 아님
190+
- **404**: 로드맵을 찾을 수 없음
191+
192+
### 참고
193+
- 수정 후 직업 로드맵 통합 이벤트 발행 (비동기)
194+
- taskId가 null인 노드는 자동으로 pending alias 등록
195+
"""
196+
)
107197
@PutMapping("/{id}")
108198
@PreAuthorize("hasRole('MENTOR')")
109199
public RsData<MentorRoadmapSaveResponse> update(@PathVariable Long id, @Valid @RequestBody MentorRoadmapSaveRequest request) {
@@ -118,7 +208,30 @@ public RsData<MentorRoadmapSaveResponse> update(@PathVariable Long id, @Valid @R
118208
);
119209
}
120210

121-
@Operation(summary = "멘토 로드맵 삭제", description = "로드맵 ID로 로드맵을 삭제합니다. 본인이 생성한 로드맵만 삭제할 수 있습니다.")
211+
@Operation(
212+
summary = "멘토 로드맵 삭제",
213+
description = """
214+
### 개요
215+
로드맵 ID로 로드맵을 삭제합니다.
216+
217+
### 권한
218+
- **본인이 생성한 로드맵만 삭제 가능** (타인 삭제 시 403 에러)
219+
- 멘토 권한(MENTOR) 필요
220+
221+
### 삭제 범위
222+
- 로드맵과 모든 노드가 함께 삭제됩니다 (Cascade)
223+
- 참조하던 Task는 삭제되지 않습니다 (Task는 공유 자원)
224+
225+
### 응답 코드
226+
- **200**: 삭제 성공
227+
- **403**: 본인의 로드맵이 아님
228+
- **404**: 로드맵을 찾을 수 없음
229+
230+
### 참고
231+
- 삭제 후 직업 로드맵 통합 이벤트 발행 (비동기)
232+
- 삭제된 로드맵은 복구할 수 없습니다
233+
"""
234+
)
122235
@DeleteMapping("/{id}")
123236
@PreAuthorize("hasRole('MENTOR')")
124237
public RsData<Void> delete(@PathVariable Long id) {

0 commit comments

Comments
 (0)