Skip to content

Conversation

@sukangpunch
Copy link
Contributor

@sukangpunch sukangpunch commented Nov 5, 2025

관련 이슈

작업 내용

변경 파일이 너무 많아서 죄송합니다... 너무 보기 어렵다면 pr을 나눠보도록 하겠습니다.

멘토 승격 요청 이후 상태 기반 임시 멘토 프로필을 생성하는 로직을 작성 하였습니다.

  1. 멘토 엔티티에 MentorStatus 상태 추가
  2. Role 에 TEMP_MENTOR 추가
  3. 멘토 마이페이지 생성 api 추가
  4. 사용자가 멘토를 조회하는 로직 들 에서 임시멘토를 제외하도록 수정
  5. 멘토 마이페이지 생성 테스트 추가 및 사용자 멘토 조회 테스트에서 임시멘토 관련 추가 검증

특이 사항

  1. 멘토와 임시멘토의 status가 다르고, 로직에 영향이 있어서 MentorFixture에 멘토와 임시 멘토 생성을 구분 하였습니다.

  2. MentorQueryService 에서 멘토를 조회 할 때, jpa 메서드를 통해 status 기반으로 조회 하여 임시 멘토를 조회에 제외하였습니다. 비즈니스 로직으로 처리 할 수도 있지만, slice 로 조회 하는 경우에 가져오려는 size 에서 제외가 된다면 논리적 오류가 발생할 수 있어 쿼리로 제외하고 가져오도록 처리하게 되었습니다.(slice에서 빈 만큼 추가로 가져올 수 있긴 한데 비효율적이라 판단하였습니다)

  3. 멘토 승격 지원만 하면 TEMP_MENTOR ROLE 을 부여 받는 것으로 처리 하였습니다.(멘티만 할수 있는 기능을 사용하지 못하는 문제가 발생하는데, 추후 role 을 list 로 관리할 수 있도록 할 때 개선 해 보도록 하겠습니다)

리뷰 요구사항 (선택)

해당 pr 에는 아직 임시 아티클(News) 작성에 대한 처리는 없습니다. 상태 기반으로 처리하면 크게 어렵지 않게 구현 할 수 있을 듯 하여 바로 진행 해보도록 하겠습니다.

추가 고민

현재 createMentorMyPage(멘토 마이페이지 생성 메서드) 에서 MentorApplication을 가져와서 해당 값을 Mentor 에 옮겨 작성하도록 하였는데, 해당 부분에서 문제가 존재합니다.
1. MentorApplication 이 여러개 존재 할 수 있다.

  • rejected 된 MentorApplication이라면 pending 버전 지원서를 더 작성할 수 있게 하였는데, 현재 조회 로직은 단일 조회 로직입니다.

2. MentorApplication 의 정보를 Mentor 에 옮겼는데 해당 MentorApplication이 rejected 된 경우

  • MentorApplication 이 rejected 되면 사실상 해당 정보는 유효하지 않을 텐데 이미 해당 Application의 값을 옮겨 Mentor 를 생성하면, 새로운 MentorApplication이 들어오고 그게 Approve 된다면 값을 또 옮겨 작성해야 합니다.

3. 서비스에서 제공하지 않는 대학일 경우 University는 무조건 null 이 들어가야한다.

  • 임시 멘토 생성에서는 서비스에서 해당 대학을 추가하기 전까지는 UniversityId가 null 이 들어 가야 하는데 MentorApplication에서 옮겨 적는 내용의 가장 큰 비중인 universityId가 null 이면 당장 옮겨 적는 것이 큰 의미가 있을까 라는 생각이 들었습니다.

@coderabbitai
Copy link

coderabbitai bot commented Nov 5, 2025

Walkthrough

멘토 지원 프로세스를 개선하고 멘토 마이페이지 생성 기능을 추가하는 변경입니다. 주요 수정 사항은 다음과 같습니다:

  1. 멘토 상태 관리 — MentorStatus(TEMPORARY, APPROVED) 열거형 추가로 멘토의 승인 상태 구분
  2. 임시 멘토 역할 도입 — Role에 TEMP_MENTOR 추가하여 단계별 권한 관리
  3. 학기 정보 연동 — MentorApplication과 Mentor 도메인에 termId 필드 추가
  4. 마이페이지 생성 API — MentorMyPageCreateRequest 및 createMentorMyPage 엔드포인트 신규 추가
  5. 역할 승격 로직 — 멘토 신청 후 MENTEE에서 TEMP_MENTOR로 자동 역할 전환
  6. 채널 관리 개선 — 채널 생성 로직 재구성
  7. 저장소 쿼리 정제 — 멘토 상태 필터링을 반영한 repository 메서드 확장
  8. 데이터베이스 스키마 확장 — mentor_status 컬럼 추가 및 site_user.role 열거형 수정

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45분

세부 검토 영역:

  • ErrorCode.java에서 MENTOR_ALREADY_EXISTS가 두 위치에 중복 정의됨 — 실제 필요한 정의 위치 및 중복 제거 여부 확인 필요
  • MentorStatus와 Role 추가에 따른 권한 흐름 — MENTEE → TEMP_MENTOR → (MENTOR?) 전환 로직의 정확성 검증
  • MentorApplication 생성자 시그니처 변경 — termId 파라미터 추가에 따른 기존 코드와의 호환성 검토
  • MentorMyPageService 로직 — validateUserCanCreateMentor 검증 로직과 채널 생성 흐름의 일관성
  • MentorRepository 쿼리 개선 — findAllByRegionAndMentorStatus 등 상태 필터링 적용의 완전성 확인
  • 데이터베이스 마이그레이션 순서 — mentor_status 컬럼 추가 → 데이터 역채우기 → NOT NULL 제약 추가의 순차성
  • 테스트 코드 확장 — MentorQueryServiceTest에 임시멘토 제외 검증 로직이 모든 조회 경로를 커버하는지 확인

Suggested reviewers

  • wibaek
  • whqtker
  • lsy1307
  • Gyuhyeok99
  • Hexeong

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목이 변경 사항의 핵심을 명확하게 전달합니다. '멘토 승격 신청 이후 멘토 프로필 작성 기능'이라는 주요 기능을 정확히 요약하고 있습니다.
Linked Issues check ✅ Passed 멘토 프로필 작성 API 추가 요구사항이 완전히 구현되었으며, MentorStatus 추가, Role 확장, 임시멘토 제외 로직 등이 모두 이슈의 목표를 충족합니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 멘토 프로필 작성 기능과 관련된 필수 구현에 집중되어 있으며, 이슈 범위를 벗어나는 변경이 없습니다.
Description check ✅ Passed 풀 리퀘스트 설명이 제공된 템플릿을 대부분 따르고 있으며, 주요 작업 내용과 특이사항이 상세히 기술되어 있습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (9)
src/main/java/com/example/solidconnection/news/domain/NewsStatus.java (1)

7-7: 불필요한 세미콜론을 제거할 수 있습니다 (선택사항).

enum 상수 뒤의 세미콜론(;)은 메서드나 필드가 없는 경우 생략 가능합니다. 코드를 더 간결하게 만들 수 있습니다.

다음과 같이 세미콜론을 제거할 수 있습니다:

 public enum NewsStatus {
 
     TEMPORARY,
-    APPROVED,
-    ;
+    APPROVED
 }

참고: MentorStatus enum도 동일한 패턴을 따르고 있다면, 일관성을 위해 함께 수정하는 것을 고려해보세요.

src/main/java/com/example/solidconnection/common/exception/ErrorCode.java (1)

53-53: 에러 코드 네이밍과 메시지 불일치

에러 코드 이름은 MENTOR_APPLICATION_NOT_FOUND인데 메시지는 "멘토 프로필이 존재하지 않습니다"로 되어 있습니다.

  1. 만약 MentorApplication 엔티티를 찾지 못한 경우라면, 메시지를 "멘토 승격 신청을 찾을 수 없습니다" 등으로 변경하는 것이 좋겠습니다.
  2. 만약 멘토 프로필을 찾지 못한 경우라면, 에러 코드명을 MENTOR_PROFILE_NOT_FOUND 등으로 변경하는 것이 명확합니다.

코드와 메시지의 일관성을 맞춰주시면 유지보수에 도움이 될 것 같습니다.

src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java (1)

124-126: 역할 변경 메서드 추가 확인

changeRole 메서드가 추가되어 사용자의 역할을 변경할 수 있게 되었습니다.

현재 구현은 간단한 setter 형태로, 기존 updatePassword 메서드와 유사한 패턴을 따르고 있습니다. 다만, 역할 변경은 민감한 작업이므로 향후 다음 사항을 고려해보시면 좋을 것 같습니다:

  1. 특정 역할 전환만 허용하는 비즈니스 규칙 검증 (예: USER → TEMP_MENTOR는 허용, USER → ADMIN은 불가 등)
  2. 역할 변경 이력 로깅

현재는 멘토 승격 플로우에 필요한 기능이므로 이대로 진행하되, 추후 역할 관리가 복잡해지면 리팩토링을 고려하시면 됩니다.

src/main/java/com/example/solidconnection/mentor/dto/MentorApplicationRequest.java (1)

13-13: 학기 필드가 추가되었습니다.

term 필드가 추가되어 멘토 신청 시 학기 정보를 받을 수 있습니다.

학기 정보가 필수인 경우, 유효성 검증 어노테이션 추가를 고려해 보세요:

+import jakarta.validation.constraints.NotBlank;
+
 public record MentorApplicationRequest(
         @JsonProperty("preparationStatus")
         ExchangeStatus exchangeStatus,
         UniversitySelectType universitySelectType,
         String country,
         Long universityId,
-        String term
+        @NotBlank(message = "학기 정보는 필수입니다")
+        String term
 ) {
 }
src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java (1)

14-15: 사용하지 않는 필드 정리를 고려해 주세요.

menteeCounthasBadge 필드가 선언되어 있지만 create()createTempMentor() 메서드에서 사용되지 않습니다.

더 이상 필요하지 않다면 필드 제거를 고려해 주세요:

 public class MentorFixtureBuilder {
 
     private final MentorRepository mentorRepository;
 
-    private int menteeCount = 0;
-    private boolean hasBadge = false;
     private String introduction;
     private String passTip;
     private long siteUserId;
     private long universityId;
     private long termId;

그리고 관련 빌더 메서드도 제거:

-    public MentorFixtureBuilder menteeCount(int menteeCount) {
-        this.menteeCount = menteeCount;
-        return this;
-    }
-
-    public MentorFixtureBuilder hasBadge(boolean hasBadge) {
-        this.hasBadge = hasBadge;
-        return this;
-    }
src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java (1)

29-29: @slf4j 어노테이션이 추가되었습니다.

로깅 지원을 위해 Lombok의 @Slf4j가 추가되었습니다.

현재 코드에서 log 사용이 보이지 않습니다. 로깅이 필요하지 않다면 어노테이션 제거를 고려해 주세요. 또는 향후 로깅 추가를 위한 사전 작업이라면 현재 상태를 유지해도 좋습니다.

Also applies to: 37-37

src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageCreateRequest.java (1)

7-17: 멘토 마이페이지 생성 DTO가 명확하게 정의되었습니다!

변경 내역:

  1. introduction, passTip 필드에 @NotBlank 검증이 적용되어 필수 입력을 보장합니다
  2. channels 필드는 @Valid로 중첩 검증을 지원하며, 선택적 입력으로 설계되었습니다
  3. MentorMyPageUpdateRequest와 구조가 동일한데, 이는 생성/수정 요청의 명확한 분리를 위한 의도적 선택으로 보입니다

다만, 두 DTO의 구조가 완전히 동일하므로, 추후 유지보수 시 중복을 줄이기 위해 공통 인터페이스나 상위 레코드를 고려해볼 수 있습니다.

src/main/java/com/example/solidconnection/mentor/domain/MentorApplication.java (1)

56-57: termId 필드가 추가되어 학기 정보를 관리합니다!

필드 정의:

  1. long 타입으로 학기 ID를 저장합니다
  2. nullable = false로 필수 값임을 명시합니다
  3. length = 50 속성이 지정되어 있습니다

다만, long 타입(숫자)에 length = 50 속성은 JPA/Hibernate에서 일반적으로 무시되는 속성입니다. 이 속성은 주로 문자열 컬럼(varchar)에 사용되므로, 제거해도 동작에는 영향이 없습니다.

다음과 같이 수정할 수 있습니다:

-    @Column(length = 50, nullable = false)
+    @Column(nullable = false)
     private long termId;
src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (1)

30-30: @slf4j 애노테이션이 추가되었지만 실제 로그 사용이 보이지 않습니다.

현재 제공된 코드에서 log 사용이 확인되지 않습니다. 향후 디버깅이나 모니터링을 위해 추가하신 것이라면 괜찮지만, 사용하지 않는다면 제거하는 것이 좋습니다.

Also applies to: 34-34

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 093b6af and 1cd3aae.

📒 Files selected for processing (34)
  • src/main/java/com/example/solidconnection/common/exception/ErrorCode.java (2 hunks)
  • src/main/java/com/example/solidconnection/mentor/controller/MentorMyPageController.java (3 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/Mentor.java (4 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/MentorApplication.java (3 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/MentorStatus.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/UniversitySelectType.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/dto/MentorApplicationRequest.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageCreateRequest.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/repository/MentorApplicationRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/repository/MentorBatchQueryRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/repository/MentorRepository.java (2 hunks)
  • src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java (4 hunks)
  • src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (5 hunks)
  • src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java (4 hunks)
  • src/main/java/com/example/solidconnection/news/domain/NewsStatus.java (1 hunks)
  • src/main/java/com/example/solidconnection/siteuser/domain/Role.java (1 hunks)
  • src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java (1 hunks)
  • src/main/java/com/example/solidconnection/term/repository/TermRepository.java (1 hunks)
  • src/main/resources/db/migration/V37__add_mentor_status_filed_and_temp_mentor_role.sql (1 hunks)
  • src/main/resources/secret (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/ChannelFixture.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/ChannelFixtureBuilder.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixture.java (5 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixtureBuilder.java (4 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorFixture.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/MentoringFixture.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java (7 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java (3 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java (4 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentoringCheckServiceTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentoringCommandServiceTest.java (2 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentoringQueryServiceTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java (1 hunks)
🧰 Additional context used
🧠 Learnings (5)
📚 Learning: 2025-08-02T21:44:08.950Z
Learnt from: nayonsoso
Repo: solid-connection/solid-connect-server PR: 426
File: src/main/java/com/example/solidconnection/mentor/domain/Mentor.java:80-80
Timestamp: 2025-08-02T21:44:08.950Z
Learning: Mentor.updateChannels() 메서드에서 채널 삭제 시 originalChannelSize를 메서드 시작 시점에 고정하여 사용하므로, 반복문 내에서 리스트 크기가 변경되어도 올바른 수의 채널이 삭제된다. i < originalChannelSize 조건으로 넘치는 채널을 정확히 제거할 수 있다.

Applied to files:

  • src/test/java/com/example/solidconnection/mentor/fixture/ChannelFixtureBuilder.java
  • src/main/java/com/example/solidconnection/mentor/domain/Mentor.java
📚 Learning: 2025-09-25T15:53:53.419Z
Learnt from: Gyuhyeok99
Repo: solid-connection/solid-connect-server PR: 513
File: src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java:180-193
Timestamp: 2025-09-25T15:53:53.419Z
Learning: Gyuhyeok99 prefers using assertThatCode() for exception testing in AssertJ tests, even when testing that exceptions are thrown. This works functionally and the user has confirmed it works well in their codebase.

Applied to files:

  • src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java
📚 Learning: 2025-08-12T21:43:45.760Z
Learnt from: nayonsoso
Repo: solid-connection/solid-connect-server PR: 448
File: src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java:118-121
Timestamp: 2025-08-12T21:43:45.760Z
Learning: SiteUser 도메인의 updatePassword 메서드에서는 파라미터 이름을 newEncodedPassword로 하거나 Javadoc을 추가해서 인코딩된 비밀번호가 들어와야 한다는 것을 명시해야 합니다.

Applied to files:

  • src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java
📚 Learning: 2025-08-11T14:39:49.462Z
Learnt from: Gyuhyeok99
Repo: solid-connection/solid-connect-server PR: 443
File: src/main/resources/db/migration/V28__alter_mentor_introduction_pass_tip_not_null.sql:1-5
Timestamp: 2025-08-11T14:39:49.462Z
Learning: The mentor table currently has no data in production/staging environment, so NULL backfill operations are not needed when adding NOT NULL constraints to the introduction and pass_tip columns in the mentor table.

Applied to files:

  • src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java
  • src/main/java/com/example/solidconnection/mentor/domain/Mentor.java
  • src/main/resources/db/migration/V37__add_mentor_status_filed_and_temp_mentor_role.sql
📚 Learning: 2025-07-05T17:54:42.475Z
Learnt from: nayonsoso
Repo: solid-connection/solid-connect-server PR: 375
File: src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java:47-53
Timestamp: 2025-07-05T17:54:42.475Z
Learning: MentorMyPageService에서 PUT 메서드 구현 시 전체 채널을 새로 생성하여 교체하는 방식을 사용하는 것이 PUT의 의미론적 특성과 일치하며, 트랜잭션 로킹 관점에서도 합리적인 접근이다.

Applied to files:

  • src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java
🧬 Code graph analysis (5)
src/main/java/com/example/solidconnection/mentor/controller/MentorMyPageController.java (1)
src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (1)
  • Slf4j (34-124)
src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageCreateRequest.java (1)
src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageUpdateRequest.java (1)
  • MentorMyPageUpdateRequest (8-18)
src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java (2)
src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (1)
  • Slf4j (34-124)
src/main/java/com/example/solidconnection/mentor/controller/MentorController.java (1)
  • RequiredArgsConstructor (21-52)
src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java (1)
src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java (1)
  • TestContainerSpringBootTest (43-245)
src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (2)
src/main/java/com/example/solidconnection/mentor/controller/MentorMyPageController.java (1)
  • Slf4j (21-57)
src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java (1)
  • Service (27-79)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (31)
src/test/java/com/example/solidconnection/mentor/service/MentoringQueryServiceTest.java (2)

327-327: EOF 개행 문자 정리 완료.

파일 끝의 개행 문자 처리가 깔끔하게 정리되었습니다. 이 변경은 기능상 영향이 없으므로 승인합니다.


75-88: 멘토 조회 테스트 및 임시 멘토 필터링 검증 확인 요청.

PR 목표에서 명시한 내용:

  1. 멘토 마이페이지 생성 테스트 추가
  2. 사용자 멘토 조회 테스트에 임시 멘토 관련 검증 추가

제공된 코드 검토 결과:

  • setUp() 메서드에서 일반 멘토만 생성되고 있음 (임시 멘토 미생성)
  • 멘티의 멘토 목록 조회 테스트(멘티의_멘토_목록_조회_테스트)에서 임시 멘토가 제외되는지 검증하는 케이스가 미포함
  • PR 특이사항에서 MentorFixture 분리를 언급했으나, 테스트에서 임시 멘토 생성 미확인

다음을 검증하고 확인해주세요:

  1. 임시 멘토(TEMP_MENTOR) 필터링 검증 테스트가 이 파일 내 다른 위치에 있는지
  2. 또는 별도 테스트 파일(예: MentorProfileServiceTest, MentorQueryServiceTest 등)에서 관리되는지
  3. 멘티의 멘토 조회 시 임시 멘토가 반환되지 않는지 확인하는 테스트 케이스 추가 필요 여부
src/main/java/com/example/solidconnection/mentor/repository/MentorBatchQueryRepository.java (1)

93-93: 파일 끝 개행 추가 - LGTM!

파일 끝에 개행을 추가한 것은 POSIX 표준을 따르는 좋은 관행입니다. 기능적 변경 사항이 없으며, 코드 품질 향상에 도움이 됩니다.

src/main/resources/secret (1)

1-1: Submodule 업데이트 검증 필요

  1. 파일 유형 확인

    • 이 파일은 Git 서브모듈 참조이므로, 실제 코드 변경 검토가 불가능합니다
    • 파일명이 secret으로 표시되어 있어 민감한 정보를 포함할 가능성이 있습니다
  2. 확인 사항

    • 새로운 커밋 해시(e15e2b020d19532adde2afe570203ab03287614d)의 목적 및 변경 내용을 확인해주세요
    • 이 서브모듈 업데이트가 PR 목표(멘토 프로필 작성 기능)와 일치하는지 검증이 필요합니다
    • 서브모듈이 신뢰할 수 있는 소스에서 온 것인지 확인해주세요
  3. 보안 고려사항

    • secret 파일이라는 이름으로 보아 민감한 데이터가 포함되어 있을 수 있습니다
    • 업데이트 전후 변경사항을 검증하여 의도하지 않은 변경이 없는지 확인해주세요
src/main/java/com/example/solidconnection/common/exception/ErrorCode.java (1)

130-130: LGTM!

멘토 마이페이지 중복 생성을 방지하는 에러 코드가 명확하게 정의되어 있습니다.

src/test/java/com/example/solidconnection/mentor/service/MentoringCommandServiceTest.java (1)

9-9: LGTM!

사용하지 않는 import를 제거한 코드 정리 작업입니다.

src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java (3)

129-139: LGTM!

임시 멘토 조회 시 예외가 발생하는 것을 검증하는 테스트가 잘 작성되어 있습니다. PR 목표인 "사용자가 멘토를 조회하는 로직에서 임시 멘토를 제외"하는 요구사항을 충실히 검증하고 있습니다.


191-221: LGTM!

멘토 미리보기 목록에서 임시 멘토가 제외되는 것을 검증하는 테스트입니다.

  1. 정상 멘토 2명과 임시 멘토 1명을 생성
  2. 미리보기 목록 조회
  3. 임시 멘토가 결과에 포함되지 않음을 확인

테스트 로직이 명확하고 검증도 충분합니다.


279-303: LGTM!

권역 필터링 시에도 임시 멘토가 제외되는 것을 검증하는 테스트입니다.

  1. 아시아, 유럽, 아메리카 권역에 멘토 생성 (아메리카에 임시 멘토 배치)
  2. 각 권역별로 필터링 조회
  3. 임시 멘토가 있는 아메리카 권역은 빈 결과 반환을 확인
  4. 다른 권역들은 정상 멘토만 반환됨을 확인

권역 필터링 로직에서도 임시 멘토 제외가 잘 동작하는지 검증하고 있어 좋습니다.

src/main/java/com/example/solidconnection/mentor/repository/MentorApplicationRepository.java (1)

13-13: 메서드 추가가 적절합니다.

사용자 ID로 멘토 신청 정보를 조회하는 메서드가 올바르게 추가되었습니다. Spring Data JPA 네이밍 컨벤션을 준수하고 있으며, MentorMyPageService에서 멘토 프로필 생성 시 필요한 신청 정보를 가져오는 용도로 적절하게 사용됩니다.

src/main/java/com/example/solidconnection/term/repository/TermRepository.java (1)

11-11: 학기명 기반 조회 메서드가 적절하게 추가되었습니다.

findByName 메서드가 올바르게 추가되어 학기명으로 Term을 조회할 수 있습니다. 기존 findByIsCurrentTrue()와 함께 학기 조회 기능을 보완합니다.

src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java (1)

81-90: 임시 멘토 픽스처가 적절하게 추가되었습니다.

임시멘토() 메서드가 기존 픽스처 패턴을 따라 일관성 있게 구현되었습니다. TEMP_MENTOR 역할을 가진 테스트 데이터 생성을 지원합니다.

src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java (2)

61-71: 승인된 멘토 생성 로직이 명확해졌습니다.

create() 메서드가 approve()를 호출하여 멘토 상태를 명시적으로 APPROVED로 설정합니다. 기존 테스트와의 호환성을 유지하면서 상태 관리가 명확해졌습니다.


73-82: 임시 멘토 생성 메서드가 추가되었습니다.

createTempMentor() 메서드가 추가되어 TEMPORARY 상태의 멘토를 생성할 수 있습니다. approve()를 호출하지 않아 임시 상태를 유지합니다.

src/main/java/com/example/solidconnection/mentor/domain/UniversitySelectType.java (1)

6-7: Enum 형식이 개선되었습니다.

후행 쉼표와 세미콜론을 추가하여 Java enum 모범 사례를 따르도록 개선되었습니다. 향후 새로운 상수 추가 시 diff가 최소화됩니다.

src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java (2)

50-51: 승인된 멘토 필터링 로직 검증 완료

변경사항이 안전하게 구현되었습니다. MentorRepository에 findByIdAndMentorStatus 메서드가 올바르게 존재하여 다음과 같이 작동합니다:

  1. 쿼리 메서드 확인

    • findByIdAndMentorStatus(long id, MentorStatus mentorStatus) 구현 확인
  2. 필터링 동작

    • 승인된 멘토(APPROVED)만 조회 가능
    • 임시 멘토(TEMPORARY) 상세 조회 시 자동으로 MENTOR_NOT_FOUND 예외 발생
  3. 추가 기능

    • findAllByMentorStatus 메서드도 함께 지원되어 향후 리스트 조회에도 활용 가능

72-79: 상태 필터링 검증 완료 - 모든 조건이 올바르게 적용되었습니다.

  1. 지역별 조회 필터링 (MentorQueryService 72-79줄)

    • 지역 미선택: findAllByMentorStatus(MentorStatus.APPROVED, pageable)
    • 지역 선택: findAllByRegionAndMentorStatus(region, MentorStatus.APPROVED, pageable)
    • ✅ 공개 목록 조회에서 APPROVED 상태만 노출됨
  2. 자기 데이터 접근 시 상태 필터링 미적용 (findBySiteUserId 사용처)

    • MentoringCheckService: 멘토 본인의 멘토링 확인 (7건)
    • MentorMyPageService: 멘토 본인의 프로필 조회/수정 (52, 64줄)
    • MentoringQueryService: 멘토 본인의 멘토링 목록 (137줄)
    • ✅ 임시 상태 멘토도 자신의 데이터에 접근 가능 (의도된 동작)
  3. 설계의 일관성

    • 공개 API: 상태 필터링 적용 (APPROVED만)
    • 개인 API: 상태 필터링 미적용 (모든 상태 허용)

모든 조회에서 상태 필터링이 적절하게 적용되었으므로 추가 조치는 필요하지 않습니다.

src/main/java/com/example/solidconnection/siteuser/domain/Role.java (1)

7-9: TEMP_MENTOR 역할 추가가 올바르게 검증되었습니다.

데이터베이스 마이그레이션 스크립트 검증 결과, TEMP_MENTOR 역할이 모두 제대로 추가되었음을 확인했습니다:

  1. Java 열거형에서의 추가 – Role.java의 7-9번 라인에 TEMP_MENTOR가 올바르게 정의됨
  2. 데이터베이스 마이그레이션 적용 – V37__add_mentor_status_filed_and_temp_mentor_role.sql에서 site_user 테이블의 role 컬럼 ENUM에 TEMP_MENTOR 추가됨 (ENUM('MENTEE','MENTOR','ADMIN','TEMP_MENTOR'))

멘토 승격 신청 이후 승인 전까지의 상태 관리를 위한 역할이 일관성 있게 구현되었습니다.

src/main/java/com/example/solidconnection/mentor/domain/MentorStatus.java (1)

3-8: 깔끔한 enum 정의입니다!

멘토 상태를 명확하게 TEMPORARYAPPROVED 두 가지로 구분하는 enum이 추가되었네요. 간결하고 직관적인 구조로 잘 정의되어 있습니다.

src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixtureBuilder.java (1)

24-24: 테스트 픽스처가 termId를 올바르게 지원합니다!

변경 사항을 정리하면:

  1. termId 필드 추가로 학기 정보를 관리할 수 있게 되었습니다
  2. 빌더 패턴의 setter 메서드 termId(long)가 추가되었습니다
  3. MentorApplication 생성 시 termId를 제대로 전달하고 있습니다

도메인 엔티티의 생성자 변경사항과 잘 맞물려 있어 좋습니다.

Also applies to: 57-60, 79-79

src/main/resources/db/migration/V37__add_mentor_status_filed_and_temp_mentor_role.sql (1)

1-17: 안전한 마이그레이션 패턴이 적용되었습니다!

변경 사항을 단계별로 정리하면:

  1. mentor_status 컬럼 추가 (nullable): TEMPORARY, APPROVED enum 타입으로 정의
  2. 기존 데이터 백필: 모든 기존 멘토를 APPROVED 상태로 설정 (기존 멘토는 이미 승인된 상태로 간주)
  3. NOT NULL 제약 적용: 기본값 TEMPORARY로 설정 (신규 멘토는 임시 상태로 시작)
  4. TEMP_MENTOR 역할 추가: site_user 테이블의 role enum에 새로운 역할 추가

nullable → 백필 → NOT NULL 순서로 진행하는 안전한 마이그레이션 패턴을 따르고 있어 좋습니다.

Based on learnings

src/test/java/com/example/solidconnection/mentor/fixture/MentorFixture.java (1)

25-33: 임시 멘토 픽스처가 깔끔하게 추가되었습니다!

새로운 임시멘토() 메서드가 추가되어 테스트에서 임시 멘토를 쉽게 생성할 수 있게 되었습니다:

  1. 기존 멘토() 메서드와 동일한 구조로 일관성을 유지합니다
  2. createTempMentor()를 호출하여 TEMPORARY 상태의 멘토를 생성합니다
  3. 동일한 기본값(소개, 팁, 학기)을 사용하여 테스트 데이터의 일관성을 보장합니다

멘토와 임시 멘토를 명확하게 분리한 설계가 좋습니다!

src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java (3)

44-45: 테스트 인프라가 학기(Term) 지원을 위해 잘 확장되었습니다!

변경된 부분들:

  1. SiteUserRepositoryTermFixture가 새롭게 주입되었습니다
  2. setUp() 메서드에서 현재 학기("2025-1")를 초기화하여 테스트 전제조건을 준비합니다
  3. 학기 정보가 필요한 MentorApplication 생성을 지원합니다

테스트 환경 설정이 도메인 변경사항과 잘 맞춰져 있습니다.

Also applies to: 50-51, 64-64


82-82: 멘토 신청 후 역할 변경 검증이 정확하게 추가되었습니다!

개선 사항:

  1. 멘토 신청 성공 시 사용자 역할이 TEMP_MENTOR로 변경되는지 검증합니다
  2. 다양한 시나리오(기본 신청, universityId null, 거절 후 재신청)에서 일관되게 검증합니다
  3. 임시 멘토 상태 관리 로직이 제대로 작동하는지 확인합니다

신규 기능의 핵심 동작을 빠짐없이 검증하고 있어 좋습니다!

Also applies to: 101-101, 188-188


201-209: MentorApplicationRequest에 학기 정보가 올바르게 전달됩니다!

테스트 헬퍼 메서드가 업데이트되었습니다:

  1. term 파라미터("2025-1")가 요청 생성 시 전달됩니다
  2. 프로덕션 코드의 DTO 시그니처 변경과 일치합니다
  3. 모든 테스트에서 일관된 학기 값을 사용합니다
src/main/java/com/example/solidconnection/mentor/controller/MentorMyPageController.java (3)

29-29: 임시 멘토에게도 접근 권한이 올바르게 부여되었습니다!

개선된 권한 제어:

  1. 기존 GET 엔드포인트(멘토 마이페이지 조회)에 TEMP_MENTOR 역할 추가
  2. PUT 엔드포인트(멘토 마이페이지 수정)에도 TEMP_MENTOR 역할 추가
  3. 임시 멘토가 자신의 프로필을 조회하고 수정할 수 있게 되었습니다

임시 멘토의 프로필 작성 플로우를 지원하기 위한 적절한 권한 확장입니다!

Also applies to: 38-38


48-56: 멘토 마이페이지 생성 API가 깔끔하게 추가되었습니다!

새 엔드포인트의 특징:

  1. POST /mentor/my 경로로 멘토 프로필 생성을 처리합니다
  2. @Valid 검증을 통해 요청 데이터의 유효성을 보장합니다
  3. @RequireRoleAccessMENTORTEMP_MENTOR 역할만 접근 가능합니다
  4. 서비스 레이어에 위임하는 표준적인 컨트롤러 패턴을 따릅니다

API 설계가 기존 패턴과 일관성 있게 잘 구현되었습니다!


21-21: @slf4j 애노테이션이 추가되었습니다

로깅 기능이 활성화되었으나 현재 코드에서는 실제 로그 문장이 보이지 않습니다. 향후 디버깅이나 모니터링을 위한 준비로 보이며, 필요 시 활용하시면 됩니다.

src/main/java/com/example/solidconnection/mentor/domain/MentorApplication.java (1)

72-91: 생성자가 termId를 올바르게 처리합니다!

개선 사항:

  1. 생성자 시그니처에 long termId 파라미터가 추가되었습니다
  2. 기존 검증 로직(validateExchangeStatus, validateUniversitySelection)을 거친 후 필드에 할당됩니다
  3. 불변성을 유지하면서 필수 학기 정보를 요구하는 설계입니다

도메인 엔티티의 생성 로직이 확장 요구사항을 잘 반영하고 있습니다!

src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (2)

81-98: 멘토 프로필 생성 로직이 올바르게 구현되었습니다.

구현 내용:

  1. 사용자 검증 및 중복 멘토 확인
  2. 채널 등록 제한 검증
  3. MentorApplication에서 데이터 가져오기
  4. Mentor 엔티티 생성 (universityId, termId 포함)
  5. 채널 생성 및 저장

트랜잭션 경계도 적절하며, 예외 처리도 명확합니다. PR 목표에 맞게 멘토 승격 신청 이후 프로필을 작성할 수 있도록 잘 구현되었습니다.


100-108: 사용자 검증 로직이 명확하고 정확합니다.

검증 항목:

  1. 사용자 존재 여부 확인
  2. 기존 멘토 중복 확인

두 가지 검증을 순차적으로 수행하여 적절한 예외를 발생시킵니다. 로직이 명확하고 이해하기 쉽습니다.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java (1)

204-214: 테스트 시나리오의 견고성을 개선해주세요.

현재 테스트는 멘토 신청 없이 멘토만 생성한 상태에서 MENTOR_ALREADY_EXISTS 예외를 기대하고 있습니다. 이는 서비스의 검증 순서(validateUserCanCreateMentor → 멘토 신청 조회)에 의존하고 있어, 향후 검증 순서가 변경되면 테스트가 MENTOR_APPLICATION_NOT_FOUND 예외로 실패할 수 있습니다.

다음과 같이 멘토 신청도 함께 설정하여 테스트의 의도를 명확히 하는 것을 권장합니다:

 void 이미_멘토_정보가_존재하는데_생성_요청_시_예외가_발생한다() {
     // given
     MentorMyPageCreateRequest request = new MentorMyPageCreateRequest("introduction", "passTip", List.of());
+    mentorApplicationFixture.대기중_멘토신청(tempMentorUser.getId(), UniversitySelectType.CATALOG, university.getId());
     mentorFixture.멘토(tempMentorUser.getId(), university.getId());
 
     // when & then
     assertThatCode(() -> mentorMyPageService.createMentorMyPage(tempMentorUser.getId(), request))
             .isInstanceOf(CustomException.class)
             .hasMessage(MENTOR_ALREADY_EXISTS.getMessage());
 }
src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (1)

30-30: 사용하지 않는 로깅 어노테이션을 제거하는 것을 고려해주세요.

@slf4j 어노테이션이 추가되었지만 파일 내에서 log 객체가 사용되지 않고 있습니다. 향후 로깅 추가 예정이 아니라면 제거하는 것이 좋습니다.

-@Slf4j
 @RequiredArgsConstructor
 @Service
 public class MentorMyPageService {

Also applies to: 34-34

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1cd3aae and c6f5724.

📒 Files selected for processing (2)
  • src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (5 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java (3 hunks)
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-08-02T21:44:08.950Z
Learnt from: nayonsoso
Repo: solid-connection/solid-connect-server PR: 426
File: src/main/java/com/example/solidconnection/mentor/domain/Mentor.java:80-80
Timestamp: 2025-08-02T21:44:08.950Z
Learning: Mentor.updateChannels() 메서드에서 채널 삭제 시 originalChannelSize를 메서드 시작 시점에 고정하여 사용하므로, 반복문 내에서 리스트 크기가 변경되어도 올바른 수의 채널이 삭제된다. i < originalChannelSize 조건으로 넘치는 채널을 정확히 제거할 수 있다.

Applied to files:

  • src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java
📚 Learning: 2025-07-05T17:54:42.475Z
Learnt from: nayonsoso
Repo: solid-connection/solid-connect-server PR: 375
File: src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java:47-53
Timestamp: 2025-07-05T17:54:42.475Z
Learning: MentorMyPageService에서 PUT 메서드 구현 시 전체 채널을 새로 생성하여 교체하는 방식을 사용하는 것이 PUT의 의미론적 특성과 일치하며, 트랜잭션 로킹 관점에서도 합리적인 접근이다.

Applied to files:

  • src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java
🧬 Code graph analysis (2)
src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (2)
src/main/java/com/example/solidconnection/mentor/controller/MentorMyPageController.java (1)
  • Slf4j (21-57)
src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java (1)
  • Service (27-79)
src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java (2)
src/test/java/com/example/solidconnection/mentor/service/MentoringCheckServiceTest.java (3)
  • Nested (64-101)
  • Nested (103-170)
  • Nested (141-169)
src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java (4)
  • Nested (67-113)
  • Nested (115-140)
  • Nested (142-240)
  • Nested (242-315)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (6)
src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java (4)

71-72: 테스트 설정이 깔끔하게 추가되었습니다.

멘토 마이페이지 생성 테스트를 위한 픽스처와 임시 멘토 사용자 설정이 적절히 구성되었습니다.

Also applies to: 77-77, 85-85


179-202: 멘토 생성 플로우가 올바르게 검증되고 있습니다.

  1. 멘토 신청 생성 → 마이페이지 생성 → 결과 검증 순서로 진행
  2. introduction, passTip, MentorStatus.TEMPORARY 상태 확인
  3. Line 196에서 findBySiteUserId를 사용하여 이전 리뷰의 지적사항이 올바르게 수정됨

216-232: 채널 제한 초과 검증이 적절합니다.

5개의 채널을 생성하여 제한(4개)을 초과하는 경우를 올바르게 테스트하고 있습니다.


234-243: 멘토 신청 없이 생성 시도하는 예외 케이스가 잘 검증되고 있습니다.

멘토 승격 신청이 없는 상태에서 마이페이지 생성을 시도할 때 MENTOR_APPLICATION_NOT_FOUND 예외가 발생하는 것을 확인합니다.

src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (2)

72-75: 코드 중복 제거가 훌륭하게 완료되었습니다.

이전 리뷰에서 지적된 updateChannel과 createChannels 간의 중복 로직이 buildChannels 메서드로 깔끔하게 추출되었습니다. 시퀀스 초기화 및 채널 생성 로직이 한 곳에서 관리되어 유지보수성이 향상되었습니다.

Also applies to: 112-124


96-104: 사용자 및 멘토 존재 여부 검증이 적절합니다.

  1. 사용자 존재 여부 확인
  2. 멘토가 이미 존재하지 않는지 확인

두 단계의 검증이 명확하게 구현되어 있습니다.

@sukangpunch sukangpunch force-pushed the feat/532-create-mentor-profile-after-request-mentor-application branch from be7b136 to c6f5724 Compare November 5, 2025 14:56
* feat: 멘토 마이페이지 생성 기능 추가

* fix: 멘토 엔티티에 universityId 가 null 을 허용하도록 수정

* feat: MentorStatus enum 클래스 추가

* fix: MentorApplicationRequest 에 term 추가

- 멘토 승격 지원 시 수학한 term 을 입력 받아야 한다

* feat: Role 에 TEMP_MENTOR 추가

* test: MentorApplicationFixture 에 term 추가
* feat: getMentorDetails 에서 Mentor 조회 후 비즈니스 로직으로 조회한
  멘토에 대해 status 확인 후 임시멘토 제외

* fix: getMentorPreviews 에서 멘토 Slice 조회 시 jpa 메서드에 상태 기반
  where 절을 추가하여 임시 멘토 제외
* refactor: createMentorMyPage 에서 mentor 생성할 때, 대학 정보를
  MentorApplication 에서 가져오게 수정
* test: MentorFixture에 임시멘토 생성 메서드 추가

* test: MentorQueryService에서 임시 멘토는 조회 관련 테스트 추가

* test: MentorMyPageServiceTest 에서 멘토 마이페이지 생성 테스트 추가
* feat: mentorRepository에 findByIdAndMentorStatus 메서드 추가
* feat: Mentor 에 MentorStatus enum 필드 추가

* feat: Role 에 TEMP_MENTOR 추가
* refactor: 채널 생성 로직 중복 제거

* fix: 사용하지 않는 NewsStatus 제거

* fix: MentorMyPageServiceTest 에서 siteUserId 를 mentorId 처럼 사용하는 문제 수정
@sukangpunch sukangpunch force-pushed the feat/532-create-mentor-profile-after-request-mentor-application branch from c6f5724 to 6ee3bbd Compare November 5, 2025 15:48
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java (1)

14-15: 사용하지 않는 빌더 필드를 제거해주세요.

menteeCounthasBadge 필드가 더 이상 Mentor 생성자에 전달되지 않지만, 빌더에는 여전히 남아있습니다(Lines 14-15). 관련 메서드들(Lines 26-34)도 사용되지 않습니다.

다음 필드와 메서드를 제거하세요:

-    private int menteeCount = 0;
-    private boolean hasBadge = false;
     private String introduction;
     private String passTip;
     private long siteUserId;
     private long universityId;
     private long termId;

     public MentorFixtureBuilder mentor() {
         return new MentorFixtureBuilder(mentorRepository);
     }

-    public MentorFixtureBuilder menteeCount(int menteeCount) {
-        this.menteeCount = menteeCount;
-        return this;
-    }
-
-    public MentorFixtureBuilder hasBadge(boolean hasBadge) {
-        this.hasBadge = hasBadge;
-        return this;
-    }
-
     public MentorFixtureBuilder introduction(String introduction) {

Also applies to: 26-34

🧹 Nitpick comments (6)
src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java (1)

191-221: 임시 멘토 제외 검증이 정확합니다.

임시 멘토가 미리보기 목록에서 제외되는지 잘 검증하고 있습니다. 다만 Lines 209-220의 어설션이 기존 테스트(Lines 176-188)와 중복됩니다.

테스트 명확성을 위해 현재 방식도 좋지만, 원한다면 임시 멘토 제외 여부만 검증하고 상세 필드 검증은 기존 테스트에 위임하는 방식도 고려할 수 있습니다.

선택적 리팩토링 제안:

         assertThat(mentorPreviewMap.get(tempMentor.getId())).isNull();
         assertAll(
+                () -> assertThat(mentorPreviewMap).containsKeys(mentor1.getId(), mentor2.getId()),
+                () -> assertThat(response.content()).hasSize(2)
-                () -> assertThat(mentor1Response.nickname()).isEqualTo(mentorUser1.getNickname()),
-                () -> assertThat(mentor1Response.universityName()).isEqualTo(university1.getKoreanName()),
-                () -> assertThat(mentor1Response.country()).isEqualTo(university1.getCountry().getKoreanName()),
-                () -> assertThat(mentor1Response.channels()).extracting(ChannelResponse::url)
-                        .containsOnly(channel1.getUrl()),
-
-                () -> assertThat(mentor2Response.nickname()).isEqualTo(mentorUser2.getNickname()),
-                () -> assertThat(mentor2Response.universityName()).isEqualTo(university2.getKoreanName()),
-                () -> assertThat(mentor2Response.country()).isEqualTo(university2.getCountry().getKoreanName()),
-                () -> assertThat(mentor2Response.channels()).extracting(ChannelResponse::url)
-                        .containsOnly(channel2.getUrl())
         );
src/test/java/com/example/solidconnection/mentor/fixture/MentorFixture.java (1)

25-33: 임시 멘토 픽스처 메서드가 잘 추가되었습니다!

멘토 메서드와 동일한 구조로 임시멘토 픽스처를 생성하도록 구현되었습니다. createTempMentor()를 호출하여 상태를 구분하는 것이 명확합니다.

Lines 19-21과 29-31의 중복 코드는 테스트 픽스처에서 명확성을 위해 허용되지만, 원한다면 공통 빌더 설정 메서드를 추출할 수도 있습니다.

선택적 리팩토링 제안 (중복 제거를 원하는 경우):

+    private MentorFixtureBuilder createBaseMentor(long siteUserId, long universityId) {
+        return mentorFixtureBuilder.mentor()
+                .siteUserId(siteUserId)
+                .universityId(universityId)
+                .introduction("멘토 소개")
+                .passTip("합격 팁")
+                .termId(termFixture.현재_학기("2025-1").getId());
+    }
+
     public Mentor 멘토(long siteUserId, long universityId) {
-        return mentorFixtureBuilder.mentor()
-                .siteUserId(siteUserId)
-                .universityId(universityId)
-                .introduction("멘토 소개")
-                .passTip("합격 팁")
-                .termId(termFixture.현재_학기("2025-1").getId())
+        return createBaseMentor(siteUserId, universityId)
                 .create();
     }

     public Mentor 임시멘토(long siteUserId, long universityId) {
-        return mentorFixtureBuilder.mentor()
-                .siteUserId(siteUserId)
-                .universityId(universityId)
-                .introduction("멘토 소개")
-                .passTip("합격 팁")
-                .termId(termFixture.현재_학기("2025-1").getId())
+        return createBaseMentor(siteUserId, universityId)
                 .createTempMentor();
     }
src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java (1)

29-29: @slf4j 애노테이션이 사용되지 않고 있습니다.

@Slf4j 애노테이션과 import를 추가했지만, 제공된 코드에서 실제 로그 문(log.debug(), log.info() 등)이 보이지 않습니다. 향후 로깅을 위한 준비라면 괜찮지만, 현재 사용하지 않는다면 제거하는 것이 좋습니다.

사용하지 않는다면 다음과 같이 제거하세요:

-import lombok.extern.slf4j.Slf4j;

 @RequiredArgsConstructor
 @Service
-@Slf4j
 public class MentorQueryService {

Also applies to: 37-37

src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixtureBuilder.java (1)

8-8: 사용하지 않는 import를 제거해주세요.

Term 클래스를 import했지만 실제로는 long termId만 사용하고 있습니다.

-import com.example.solidconnection.term.domain.Term;
src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageCreateRequest.java (1)

7-16: 멘토 마이페이지 생성 DTO가 잘 정의되었습니다!

  1. 필수 필드에 @NotBlank 검증 적용
  2. 채널 목록에 @Valid 적용하여 중첩 검증 수행
  3. 사용자 친화적인 한글 에러 메시지 제공

MentorMyPageUpdateRequest와 구조가 동일하지만, Create와 Update를 별도 DTO로 분리한 것은 명확한 의도 표현과 향후 독립적 진화 가능성을 고려한 합리적인 설계입니다.

선택적 개선 제안:

장기적으로 두 DTO가 계속 동일하게 유지된다면, 공통 인터페이스나 sealed interface를 활용하여 중복을 줄일 수 있습니다:

// 향후 고려사항
public sealed interface MentorMyPageRequest 
    permits MentorMyPageCreateRequest, MentorMyPageUpdateRequest {
    String introduction();
    String passTip();
    List<ChannelRequest> channels();
}

하지만 현재 구조도 충분히 명확하므로, 실제 필요성이 생길 때 리팩토링하는 것이 좋습니다.

src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java (1)

74-78: 역할 승격 로직을 검토해 주세요.

현재 구현에 몇 가지 개선 가능한 부분이 있습니다:

  1. Line 75: enum 비교 시 == 대신 .equals()를 사용하는 것이 더 방어적입니다 (enum은 == 사용 가능하지만 일관성을 위해).
  2. MENTEE가 아닌 경우 조용히 무시되는데, MENTOR나 ADMIN이 신청하는 경우도 고려해야 할 수 있습니다.
  3. 역할 변경이 일어나지 않는 경우 로깅을 추가하면 디버깅에 도움이 될 수 있습니다.

다음과 같이 개선할 수 있습니다:

 private void promoteRoleMenteeToTempMentor(SiteUser siteUser) {
-    if(siteUser.getRole() == Role.MENTEE){
+    if(siteUser.getRole().equals(Role.MENTEE)){
         siteUser.changeRole(Role.TEMP_MENTOR);
+        log.info("User {} promoted from MENTEE to TEMP_MENTOR", siteUser.getId());
+    } else {
+        log.warn("User {} with role {} attempted mentor application", siteUser.getId(), siteUser.getRole());
     }
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between be7b136 and 6ee3bbd.

📒 Files selected for processing (32)
  • src/main/java/com/example/solidconnection/common/exception/ErrorCode.java (2 hunks)
  • src/main/java/com/example/solidconnection/mentor/controller/MentorMyPageController.java (3 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/Mentor.java (4 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/MentorApplication.java (3 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/MentorStatus.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/UniversitySelectType.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/dto/MentorApplicationRequest.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageCreateRequest.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/repository/MentorApplicationRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/repository/MentorBatchQueryRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/repository/MentorRepository.java (2 hunks)
  • src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java (4 hunks)
  • src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (5 hunks)
  • src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java (4 hunks)
  • src/main/java/com/example/solidconnection/siteuser/domain/Role.java (1 hunks)
  • src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java (1 hunks)
  • src/main/java/com/example/solidconnection/term/repository/TermRepository.java (1 hunks)
  • src/main/resources/db/migration/V37__add_mentor_status_filed_and_temp_mentor_role.sql (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/ChannelFixture.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/ChannelFixtureBuilder.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixture.java (5 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixtureBuilder.java (4 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorFixture.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/fixture/MentoringFixture.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java (7 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java (3 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java (4 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentoringCheckServiceTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentoringCommandServiceTest.java (2 hunks)
  • src/test/java/com/example/solidconnection/mentor/service/MentoringQueryServiceTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java (1 hunks)
✅ Files skipped from review due to trivial changes (2)
  • src/main/java/com/example/solidconnection/mentor/repository/MentorBatchQueryRepository.java
  • src/test/java/com/example/solidconnection/mentor/fixture/ChannelFixture.java
🚧 Files skipped from review as they are similar to previous changes (14)
  • src/test/java/com/example/solidconnection/siteuser/fixture/SiteUserFixture.java
  • src/test/java/com/example/solidconnection/mentor/service/MentoringQueryServiceTest.java
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixture.java
  • src/main/java/com/example/solidconnection/term/repository/TermRepository.java
  • src/main/java/com/example/solidconnection/siteuser/domain/SiteUser.java
  • src/main/java/com/example/solidconnection/mentor/domain/MentorStatus.java
  • src/main/java/com/example/solidconnection/siteuser/domain/Role.java
  • src/test/java/com/example/solidconnection/mentor/service/MentoringCheckServiceTest.java
  • src/main/java/com/example/solidconnection/mentor/domain/Mentor.java
  • src/test/java/com/example/solidconnection/mentor/service/MentoringCommandServiceTest.java
  • src/main/java/com/example/solidconnection/common/exception/ErrorCode.java
  • src/main/java/com/example/solidconnection/mentor/repository/MentorApplicationRepository.java
  • src/main/java/com/example/solidconnection/mentor/dto/MentorApplicationRequest.java
  • src/test/java/com/example/solidconnection/mentor/fixture/ChannelFixtureBuilder.java
🧰 Additional context used
🧠 Learnings (5)
📓 Common learnings
Learnt from: whqtker
Repo: solid-connection/solid-connect-server PR: 362
File: src/main/java/com/example/solidconnection/mentor/service/MentoringQueryService.java:0-0
Timestamp: 2025-07-04T10:41:32.999Z
Learning: 멘토링 관련 기능에는 페이지네이션을 적용하지 않는 것이 해당 프로젝트의 설계 방침이다.
📚 Learning: 2025-08-11T14:39:49.462Z
Learnt from: Gyuhyeok99
Repo: solid-connection/solid-connect-server PR: 443
File: src/main/resources/db/migration/V28__alter_mentor_introduction_pass_tip_not_null.sql:1-5
Timestamp: 2025-08-11T14:39:49.462Z
Learning: The mentor table currently has no data in production/staging environment, so NULL backfill operations are not needed when adding NOT NULL constraints to the introduction and pass_tip columns in the mentor table.

Applied to files:

  • src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java
  • src/main/resources/db/migration/V37__add_mentor_status_filed_and_temp_mentor_role.sql
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorFixture.java
📚 Learning: 2025-08-02T21:44:08.950Z
Learnt from: nayonsoso
Repo: solid-connection/solid-connect-server PR: 426
File: src/main/java/com/example/solidconnection/mentor/domain/Mentor.java:80-80
Timestamp: 2025-08-02T21:44:08.950Z
Learning: Mentor.updateChannels() 메서드에서 채널 삭제 시 originalChannelSize를 메서드 시작 시점에 고정하여 사용하므로, 반복문 내에서 리스트 크기가 변경되어도 올바른 수의 채널이 삭제된다. i < originalChannelSize 조건으로 넘치는 채널을 정확히 제거할 수 있다.

Applied to files:

  • src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java
📚 Learning: 2025-07-05T17:54:42.475Z
Learnt from: nayonsoso
Repo: solid-connection/solid-connect-server PR: 375
File: src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java:47-53
Timestamp: 2025-07-05T17:54:42.475Z
Learning: MentorMyPageService에서 PUT 메서드 구현 시 전체 채널을 새로 생성하여 교체하는 방식을 사용하는 것이 PUT의 의미론적 특성과 일치하며, 트랜잭션 로킹 관점에서도 합리적인 접근이다.

Applied to files:

  • src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java
📚 Learning: 2025-09-25T15:53:53.419Z
Learnt from: Gyuhyeok99
Repo: solid-connection/solid-connect-server PR: 513
File: src/test/java/com/example/solidconnection/community/post/service/PostQueryServiceTest.java:180-193
Timestamp: 2025-09-25T15:53:53.419Z
Learning: Gyuhyeok99 prefers using assertThatCode() for exception testing in AssertJ tests, even when testing that exceptions are thrown. This works functionally and the user has confirmed it works well in their codebase.

Applied to files:

  • src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java
🧬 Code graph analysis (5)
src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java (1)
src/main/java/com/example/solidconnection/mentor/controller/MentorController.java (1)
  • RequiredArgsConstructor (21-52)
src/main/java/com/example/solidconnection/mentor/controller/MentorMyPageController.java (1)
src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (1)
  • Slf4j (34-125)
src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (2)
src/main/java/com/example/solidconnection/mentor/controller/MentorMyPageController.java (1)
  • Slf4j (21-57)
src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java (1)
  • Service (27-79)
src/test/java/com/example/solidconnection/mentor/service/MentorApplicationServiceTest.java (1)
src/test/java/com/example/solidconnection/mentor/service/MentorMyPageServiceTest.java (1)
  • TestContainerSpringBootTest (43-245)
src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageCreateRequest.java (1)
src/main/java/com/example/solidconnection/mentor/dto/MentorMyPageUpdateRequest.java (1)
  • MentorMyPageUpdateRequest (8-18)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (17)
src/test/java/com/example/solidconnection/mentor/service/MentorQueryServiceTest.java (2)

129-139: 임시 멘토 조회 실패 테스트가 잘 추가되었습니다!

임시 멘토를 조회할 때 MENTOR_NOT_FOUND 예외가 발생하는지 검증하는 테스트가 명확하게 구현되었습니다. 기존 테스트 패턴과 일관성 있게 작성되었고, assertThatCode()를 사용한 방식도 프로젝트 컨벤션에 부합합니다.


279-303: 권역 필터링 시 임시 멘토 제외 로직이 잘 검증되었습니다!

아메리카 권역에 임시 멘토만 있을 때 빈 결과를 반환하는지, 그리고 다른 권역의 승인된 멘토들은 정상적으로 필터링되는지 명확하게 검증하고 있습니다. 테스트 시나리오가 포괄적이고 구현이 깔끔합니다.

src/main/java/com/example/solidconnection/mentor/domain/UniversitySelectType.java (1)

6-7: Enum 포맷 개선이 좋습니다!

마지막 상수 뒤에 trailing comma를 추가하고 명시적인 세미콜론으로 종료하는 방식은 Java enum의 모범 사례입니다. 향후 새로운 상수를 추가할 때 이전 줄을 수정하지 않아도 되어 변경 이력이 깔끔해집니다.

src/main/java/com/example/solidconnection/mentor/service/MentorQueryService.java (2)

50-51: 단일 멘토 조회에 상태 필터링이 올바르게 적용되었습니다!

findByIdAndMentorStatus를 사용하여 APPROVED 상태의 멘토만 조회하도록 변경되었습니다. 임시 멘토를 조회할 때 MENTOR_NOT_FOUND 예외를 발생시키는 것은 적절한 설계입니다(임시 멘토는 사용자에게 노출되지 않아야 함).


72-79: 목록 조회의 상태 필터링이 완벽합니다!

  1. 권역 미지정 시: findAllByMentorStatus 사용 (Line 74)
  2. 권역 지정 시: findAllByRegionAndMentorStatus 사용 (Line 78)

두 경로 모두 MentorStatus.APPROVED로 필터링하여 임시 멘토를 쿼리 단계에서 제외합니다. 이는 PR 목표대로 논리 오류와 비효율을 방지하는 올바른 접근입니다.

src/test/java/com/example/solidconnection/mentor/fixture/MentorFixtureBuilder.java (1)

61-82: 승인 멘토와 임시 멘토 생성 로직이 명확하게 분리되었습니다!

  1. create(): Mentor 생성 → approve() 호출 → 저장 (상태: APPROVED)
  2. createTempMentor(): Mentor 생성 → 저장 (상태: TEMPORARY)

approve() 메서드 호출 여부로 상태를 구분하는 것이 명확하고 간결합니다. 테스트 픽스처 설계가 도메인 모델의 상태 전이를 잘 반영하고 있습니다.

src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixtureBuilder.java (2)

57-60: termId 지원이 올바르게 추가되었습니다!

빌더 패턴으로 termId 설정 메서드를 추가하고 생성자에 전달하는 구조가 깔끔합니다. 멘토 신청에 학기 정보를 연결하는 도메인 요구사항을 잘 반영하고 있습니다.

Also applies to: 79-79


24-24: 검증 결과: 리뷰 의견의 우려사항이 실제 코드에 반영되지 않음

스크립트 결과에 따르면, mentorApplicationFixtureBuilder.mentorApplication() 호출의 모든 3가지 사용 사례에서 .termId(termFixture.현재_학기("2025-1").getId())termId가 명시적으로 설정되고 있습니다.

  1. MentorApplicationFixture.java의 모든 빌더 사용처에서 termId()가 호출됨
  2. 초기화되지 않은 상태로 사용되는 경우 없음
  3. 기본값 설정이나 강제 주석 추가 불필요

현재 코드는 이미 올바르게 작동 중입니다.

Likely an incorrect or invalid review comment.

src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java (2)

43-63: 검증 로직 분리와 Term 연동이 잘 구현되었습니다.

멘토 신청 로직이 명확하게 개선되었습니다:

  1. 중복 신청 검증을 별도 메서드로 추출 (가독성 향상)
  2. Term 엔티티 연동으로 학기 정보 관리 체계화
  3. 역할 승격 로직을 트랜잭션 내에서 처리

65-72: 중복 신청 방지 로직이 깔끔하게 분리되었습니다.

검증 메서드 추출로 코드 가독성과 재사용성이 향상되었습니다.

src/main/java/com/example/solidconnection/mentor/repository/MentorRepository.java (3)

20-22: 상태 기반 조회 메서드가 적절하게 추가되었습니다.

MentorStatus 필터링을 위한 새로운 메서드들이 Spring Data JPA 컨벤션을 잘 따르고 있습니다:

  1. findByIdAndMentorStatus - 특정 ID와 상태로 멘토 조회
  2. findAllByMentorStatus - 상태별 페이지네이션 조회

24-30: 지역 기반 조회에 상태 필터링이 일관되게 적용되었습니다.

JPQL 쿼리 수정이 올바르게 이루어졌습니다:

  1. WHERE 절에 상태 조건 추가
  2. 메서드 시그니처에 MentorStatus 파라미터 추가
  3. 메서드명도 의미에 맞게 변경

이로써 모든 멘토 조회 로직에서 임시 멘토가 일관되게 제외됩니다.


16-18: 사용처 검증 완료 — 의도된 설계가 맞습니다.

스크립트 결과 확인 결과, existsBySiteUserIdfindBySiteUserId 메서드의 사용처가 모두 내부 로직에 한정되어 있으며, 각 메서드는 의도된 대로 정확히 사용되고 있습니다:

  1. findBySiteUserId 사용 패턴 — 멘토 자신의 마이페이지 조회, 멘토링 관련 작업(조회, 명령, 확인)에서 호출되며, 이 모든 맥락에서 상태 필터 없이 멘토 데이터를 조회하는 것이 타당합니다.

  2. existsBySiteUserId 사용 패턴 — 중복 검사 로직에서만 호출되며, 어떤 상태의 멘토든 존재한다면 새 멘토 생성을 차단해야 하므로 상태 필터를 적용하면 안 됩니다.

  3. 공개 API 쿼리findAll, findByRegion 등 공개 조회 메서드는 이미 상태 필터가 적용되어 있으므로 설계가 일관성 있게 유지되고 있습니다.

현재 구현이 올바릅니다. 추가 수정이 필요하지 않습니다.

src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java (4)

72-75: 채널 생성 로직 중복이 깔끔하게 제거되었습니다.

이전 리뷰 코멘트에서 지적된 중복 코드가 buildChannels 헬퍼 메서드로 잘 추출되었습니다.


96-104: 멘토 생성 전 검증 로직이 적절합니다.

사용자 존재 여부와 멘토 중복 생성 방지를 명확하게 검증하고 있습니다.


112-124: 채널 생성 로직이 일관되게 리팩토링되었습니다.

헬퍼 메서드 추출로 코드 중복이 제거되고 가독성이 향상되었습니다:

  1. buildChannels - 채널 리스트 생성 로직 통합
  2. createChannels - 신규 멘토 채널 생성
  3. updateChannel - 기존 멘토 채널 업데이트

각 메서드의 책임이 명확하게 분리되었습니다.


84-90: 검증 결과: 우려 사항 없음 - 코드가 올바르게 구현되어 있습니다.

확인해 드릴 좋은 소식입니다!

  1. MentorStatus 초기화 확인

    • Mentor 생성자의 73번 라인에서 this.mentorStatus = MentorStatus.TEMPORARY;로 명시적으로 설정되고 있습니다.
  2. 필드 선언 확인

    • 57번 라인: @Column(nullable = false)@Enumerated(EnumType.STRING) 어노테이션으로 안전하게 보호되어 있습니다.
  3. PR 목표 달성

    • 신규 Mentor 생성 시 초기 상태가 TEMPORARY로 정확하게 설정되므로, 별도 수정이 불필요합니다.

Comment on lines +47 to +48
Term term = termRepository.findByName(mentorApplicationRequest.term())
.orElseThrow(() -> new CustomException(TERM_NOT_FOUND));
Copy link

@coderabbitai coderabbitai bot Nov 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Term의 유효성 검증을 확인해 주세요.

현재 Term을 이름으로만 조회하고 있습니다. Term이 현재 활성화 상태인지, 신청 가능한 기간인지 등의 추가 검증이 필요한지 확인이 필요합니다.

다음 스크립트로 Term 도메인의 상태 관리 로직을 확인해 주세요:


🏁 Script executed:

#!/bin/bash
# Term 엔티티의 상태 필드와 검증 로직 확인
ast-grep --pattern $'class Term {
  $$$
}'

# Term 관련 검증 로직 확인
rg -n "Term.*valid\|Term.*active\|Term.*status" --type java -C 3

Length of output: 0


더 체계적으로 검증하겠습니다. 새로운 스크립트로 Term 엔티티와 검증 로직을 찾아보겠습니다.

</run_scripts]


🏁 Script executed:

#!/bin/bash
# Term 엔티티 파일 위치 찾기
echo "=== Term 클래스 찾기 ==="
fd -e java | xargs grep -l "^class Term"

# Term 엔티티 전체 구조 확인
echo "=== Term 엔티티 구조 ==="
fd -e java | xargs grep -l "class Term" | head -1 | xargs cat

# MentorApplicationService 전체 맥락 확인
echo "=== MentorApplicationService 전체 코드 ==="
fd "MentorApplicationService.java" -e java | xargs cat

Length of output: 4769


현재 Term의 활성화 상태 검증을 추가해주세요.

검증 결과, Term 엔티티는 isCurrent 필드를 통해 활성화 상태를 관리하도록 설계되어 있으나, MentorApplicationService에서는 Term 이름으로만 조회하고 있습니다. 이는 비활성 또는 지난 학기의 Term으로 멘토 신청이 가능하게 하므로 문제입니다.

필요한 변경 사항:

  1. termRepository.findByName() 조회 후 term.isCurrent() 상태를 확인하거나, TermRepository에 findCurrentByName() 같은 전용 메서드를 추가해주세요.

  2. 현재 활성화되지 않은 Term으로 신청하는 경우 적절한 예외(예: TERM_NOT_ACTIVE 또는 유사한 에러코드)를 던져주세요.

이렇게 하면 애플리케이션이 올바른 시기의 Term으로만 멘토 신청을 받을 수 있습니다.

🤖 Prompt for AI Agents
In
src/main/java/com/example/solidconnection/mentor/service/MentorApplicationService.java
around lines 47-48, after retrieving Term with
termRepository.findByName(...).orElseThrow(...), verify the Term is active by
checking term.isCurrent() (or replace the lookup with a new repository method
like findCurrentByName that only returns current Terms); if the Term is not
active throw a CustomException with an appropriate error code such as
TERM_NOT_ACTIVE so that mentor applications are only accepted for the currently
active Term.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이건 멘토 지원하는 유저의 멘토 자격을 확인하기 위함이라 최신 학기가 강제되어야 하는 부분이 아니야

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sukangpunch, 이해했습니다! 말씀하신 대로 이 필드는 유저가 교환학생을 다녀온 학기를 기록하기 위한 것이므로, 반드시 현재 활성 학기여야 할 필요가 없네요. 과거 학기 정보로도 멘토 자격 검증이 가능하니 현재 구현이 적절합니다.

설명해 주셔서 감사합니다! 👍

Comment on lines +77 to +94
@Transactional
public void createMentorMyPage(long siteUserId, MentorMyPageCreateRequest request) {
validateUserCanCreateMentor(siteUserId);
validateChannelRegistrationLimit(request.channels());
MentorApplication mentorApplication = mentorApplicationRepository.findBySiteUserId(siteUserId)
.orElseThrow(() -> new CustomException(MENTOR_APPLICATION_NOT_FOUND));

Mentor mentor = new Mentor(
request.introduction(),
request.passTip(),
siteUserId,
mentorApplication.getUniversityId(),
mentorApplication.getTermId()
);

createChannels(request.channels(), mentor);
mentorRepository.save(mentor);
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

[중요] MentorApplication 상태 검증이 누락되었습니다.

이전 리뷰에서 지적된 문제가 여전히 해결되지 않았습니다. Lines 81-82에서 MentorApplication을 조회할 때 상태를 검증하지 않아, REJECTED 상태의 신청으로도 멘토 프로필 생성이 가능합니다.

비즈니스 로직상 APPROVED 상태의 신청만 프로필 생성을 허용해야 합니다.

다음 중 하나의 방법으로 수정해 주세요:

방법 1: 조회 후 상태 검증 (권장)

     MentorApplication mentorApplication = mentorApplicationRepository.findBySiteUserId(siteUserId)
             .orElseThrow(() -> new CustomException(MENTOR_APPLICATION_NOT_FOUND));
+    
+    if (mentorApplication.getMentorApplicationStatus() != MentorApplicationStatus.APPROVED) {
+        throw new CustomException(MENTOR_APPLICATION_NOT_APPROVED);
+    }

방법 2: Repository 메서드 수정

// MentorApplicationRepository에 추가
Optional<MentorApplication> findBySiteUserIdAndMentorApplicationStatus(
    long siteUserId, 
    MentorApplicationStatus status
);

// 사용
MentorApplication mentorApplication = mentorApplicationRepository
    .findBySiteUserIdAndMentorApplicationStatus(siteUserId, MentorApplicationStatus.APPROVED)
    .orElseThrow(() -> new CustomException(MENTOR_APPLICATION_NOT_APPROVED));

참고: MENTOR_APPLICATION_NOT_APPROVED 에러 코드 추가가 필요합니다.

🤖 Prompt for AI Agents
In
src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java
around lines 77 to 94, the code fetches MentorApplication but does not verify
its status, allowing REJECTED (or other non-APPROVED) applications to create
mentor profiles; fix by ensuring only APPROVED applications proceed — either
(recommended) after retrieving MentorApplication check its status and throw a
CustomException with a new MENTOR_APPLICATION_NOT_APPROVED code when it is not
APPROVED, or (alternative) add a repository method
findBySiteUserIdAndMentorApplicationStatus(...) and use it to fetch only
APPROVED applications and throw MENTOR_APPLICATION_NOT_APPROVED if absent; also
add the MENTOR_APPLICATION_NOT_APPROVED error code to your exceptions
enum/messages.

@sukangpunch sukangpunch closed this Nov 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat: 멘토 승격 신청 이후 멘토 프로필 작성 기능 추가

1 participant