Skip to content

Conversation

@sukangpunch
Copy link
Contributor

@sukangpunch sukangpunch commented Jan 2, 2026

관련 이슈

작업 내용

  1. 어드민 페이지에서 지원서 대상 유저의 이전 지원 이력을 내림차순으로 최대 5개까지 조회하는 api 추가

특이 사항

MentorApplicationHistoryResponse 의 applicationOrder 부분은
"N차 멘토 신청" 에서 N 부분을 나타내었습니다.

리뷰 요구사항 (선택)

현재 데이터를 조회 할 때, 지원서 생성 시간 기준으로 내림차순 조회 및 5개 limit 을 걸고 조회를 합니다.
생성 시간 기준 내림차순으로 조회해서 가져오는 부분은 스스로 판단한 부분인데 혹시 더 좋은 방법이나, 해당 방식에 어색함이 있다면 수정하거나 다시 명확한 기획을 요청 드리겠습니다!

* refactor: long 타입을 Long 으로 수정
* test: MentorApplicationFixtureBuilder 에 rejectedReason 필드 및 빌더 메서드 추가
@coderabbitai
Copy link

coderabbitai bot commented Jan 2, 2026

Walkthrough

이번 변경사항은 멘토 지원서 이력 조회 기능을 구현하는 것입니다. 다음과 같이 구성됩니다:

  1. API 엔드포인트 추가

    • AdminMentorApplicationController에 /admin/mentor-applications/{site-user-id}/mentor-application-history GET 엔드포인트 추가
  2. 응답 DTO 신규 생성

    • MentorApplicationHistoryResponse 레코드 클래스로 지원서 이력 데이터 정의
  3. 서비스 로직 구현

    • AdminMentorApplicationService에 findMentorApplicationHistory 메서드 추가
    • 사용자 존재 여부 검증 및 최대 5개 최신 지원서 조회 기능 포함
  4. 데이터베이스 쿼리 메서드 추가

    • MentorApplicationRepository에 상위 5개 최신 지원서 조회 및 전체 지원서 개수 조회 메서드 추가
  5. 테스트 코드 및 픽스처 업데이트

    • 다양한 시나리오에 대한 통합 테스트 작성
    • MentorApplicationFixture 및 FixtureBuilder 확장

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • wibaek
  • lsy1307
  • Gyuhyeok99
  • Hexeong
  • whqtker

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 멘토 지원서 신청 이력 조회 기능 추가라는 주요 변경사항을 명확하고 간결하게 설명합니다.
Linked Issues check ✅ Passed PR의 모든 코드 변경사항이 #600 이슈의 요구사항을 충족합니다: 최대 5개 이력 조회, 생성 시간 기준 내림차순, 제출 날짜 포함.
Out of Scope Changes check ✅ Passed 변경사항들이 모두 멘토 지원서 이력 조회 기능 구현 범위 내에 있으며, 범위 외의 불필요한 수정이 없습니다.
Description check ✅ Passed PR 설명이 기본 템플릿 구조를 따르고 있으며, 작업 내용이 명확하게 기술되어 있습니다.
✨ Finishing touches
  • 📝 Generate docstrings

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: 0

🧹 Nitpick comments (2)
src/main/java/com/example/solidconnection/admin/controller/AdminMentorApplicationController.java (1)

79-85: 엔드포인트 경로 설계 개선을 고려해보세요.

기능은 정상적으로 작동하지만, 현재 경로 구조가 RESTful 설계 관점에서 다소 혼란스러울 수 있습니다.

현재: /admin/mentor-applications/{site-user-id}/mentor-application-history

  • 경로 상 mentor-applications 리소스 하위에 site-user-id가 위치하여, 특정 멘토 신청서의 하위 리소스처럼 보입니다.
  • 실제로는 특정 사용자의 전체 멘토 지원서 이력을 조회하는 기능입니다.

다음과 같은 대안을 고려해보세요:

  1. /admin/site-users/{site-user-id}/mentor-application-history (리소스 중심)
  2. /admin/mentor-application-history/{site-user-id} (기능 중심)

이는 설계 선호도의 문제이며, 팀 내 REST API 설계 가이드라인이 있다면 그에 따라 결정하시면 됩니다.

src/main/java/com/example/solidconnection/admin/service/AdminMentorApplicationService.java (1)

91-110: 지원서 이력 조회 로직이 잘 구현되었으나, ID 사용의 일관성 개선이 필요합니다.

전체적인 로직은 명확하고 올바르게 구현되었습니다:

  1. ✅ 유저 존재 여부 검증 (lines 92-93)
  2. ✅ 총 지원서 개수 조회 (line 95)
  3. ✅ 최신 5개 지원서 조회 (line 97)
  4. ✅ 지원서 순번 계산 로직 (totalCount - index)이 정확합니다

다만, line 95와 97에서 사용하는 ID가 일관되지 않습니다:

  • Line 95: siteUserId (파라미터, Long 타입) 사용
  • Line 97: siteUser.getId() (엔티티의 ID, long 타입) 사용

Line 92에서 이미 SiteUser 엔티티를 조회했으므로, 두 repository 호출 모두 siteUser.getId()를 사용하는 것이 더 일관되고 명확합니다.

🔎 일관성 개선을 위한 제안
     @Transactional(readOnly = true)
     public List<MentorApplicationHistoryResponse> findMentorApplicationHistory(Long siteUserId) {
         SiteUser siteUser = siteUserRepository.findById(siteUserId)
                 .orElseThrow(() -> new CustomException(USER_NOT_FOUND));
 
-        long totalCount = mentorApplicationRepository.countBySiteUserId(siteUserId);
+        long totalCount = mentorApplicationRepository.countBySiteUserId(siteUser.getId());
 
         List<MentorApplication> mentorApplications = mentorApplicationRepository.findTop5BySiteUserIdOrderByCreatedAtDesc(siteUser.getId());
 
         return IntStream.range(0, mentorApplications.size())
                 .mapToObj(index -> {
                     MentorApplication app = mentorApplications.get(index);
                     return new MentorApplicationHistoryResponse(
                             app.getId(),
                             app.getMentorApplicationStatus(),
                             app.getRejectedReason(),
                             app.getCreatedAt(),
                             (int) totalCount - index
                     );
                 }).toList();
     }
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d1cc8c3 and 9e43bc3.

📒 Files selected for processing (8)
  • src/main/java/com/example/solidconnection/admin/controller/AdminMentorApplicationController.java
  • src/main/java/com/example/solidconnection/admin/dto/MentorApplicationHistoryResponse.java
  • src/main/java/com/example/solidconnection/admin/service/AdminMentorApplicationService.java
  • src/main/java/com/example/solidconnection/mentor/repository/MentorApplicationRepository.java
  • src/main/resources/secret
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixture.java
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixtureBuilder.java
🧰 Additional context used
🧠 Learnings (2)
📚 Learning: 2025-11-17T06:30:49.502Z
Learnt from: sukangpunch
Repo: solid-connection/solid-connect-server PR: 562
File: src/main/java/com/example/solidconnection/mentor/dto/MentorApplicationRequest.java:10-23
Timestamp: 2025-11-17T06:30:49.502Z
Learning: MentorApplication 도메인에서 universityId는 null일 수 있으며, MentorApplicationRequest에서도 이 필드에 대한 NotNull validation을 추가하지 않아야 한다.

Applied to files:

  • src/main/java/com/example/solidconnection/admin/controller/AdminMentorApplicationController.java
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixtureBuilder.java
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixture.java
  • src/main/java/com/example/solidconnection/admin/service/AdminMentorApplicationService.java
📚 Learning: 2025-11-20T14:03:56.462Z
Learnt from: sukangpunch
Repo: solid-connection/solid-connect-server PR: 562
File: src/main/java/com/example/solidconnection/mentor/service/MentorMyPageService.java:76-93
Timestamp: 2025-11-20T14:03:56.462Z
Learning: MentorApplication의 universityId는 PENDING 상태에서는 null일 수 있지만, admin이 승인(APPROVED)할 때 반드시 대학 데이터를 생성하고 universityId를 채운 후 승인하므로, APPROVED 상태의 MentorApplication은 항상 non-null universityId를 가진다는 것이 비즈니스 규칙이다.

Applied to files:

  • src/main/java/com/example/solidconnection/admin/controller/AdminMentorApplicationController.java
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixtureBuilder.java
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
  • src/test/java/com/example/solidconnection/mentor/fixture/MentorApplicationFixture.java
  • src/main/java/com/example/solidconnection/admin/service/AdminMentorApplicationService.java
🧬 Code graph analysis (1)
src/main/java/com/example/solidconnection/admin/dto/MentorApplicationHistoryResponse.java (1)
src/main/java/com/example/solidconnection/admin/dto/MentorApplicationResponse.java (1)
  • MentorApplicationResponse (7-20)
⏰ 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 (9)
src/main/resources/secret (1)

1-1: 서브모듈 업데이트 - 상세 코드 리뷰 불가

제공된 파일이 서브모듈 커밋 포인터 업데이트만 포함하고 있으므로, PR의 핵심 구현 코드에 대한 상세한 코드 리뷰를 진행할 수 없습니다.

다음 파일들이 리뷰에 필요합니다:

  1. Controller 계층

    • AdminMentorApplicationController: 멘토 지원서 이력 조회 엔드포인트 구현
  2. Service 계층

    • AdminMentorApplicationService: 사이트 유저 유효성 검사, 총 신청 건수 조회, 상위 5개 항목 조회, DTO 매핑 로직
  3. Repository 계층

    • MentorApplicationRepository: findTop5BySiteUserIdOrderByCreatedAtDesc(), countBySiteUserId() 쿼리 메서드
  4. DTO & Model

    • MentorApplicationHistoryResponse: 응답 구조 및 필드 정의
  5. 테스트

    • AdminMentorApplicationServiceTest: 정렬, 제한, 빈 이력, 필드 검증, 존재하지 않는 유저 처리

이 실제 구현 파일들이 포함된 전체 코드 리뷰를 요청드립니다.

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

21-21: 거절 사유 상수 추가가 깔끔합니다.

테스트에서 사용할 거절 사유를 상수로 정의하여 fixture에서 일관되게 사용하고 있어 좋습니다. 테스트 데이터의 일관성이 확보되었습니다.

Also applies to: 68-68

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

24-24: Fixture 빌더 확장이 잘 구현되었습니다.

rejectedReason 필드와 빌더 메서드가 기존 패턴과 일관되게 추가되었고, create() 메서드에서 null 체크 후 reflection으로 값을 설정하는 방식도 적절합니다. 테스트 목적의 reflection 사용은 합당합니다.

Also applies to: 62-65, 88-90

src/main/java/com/example/solidconnection/admin/dto/MentorApplicationHistoryResponse.java (1)

6-12: 이력 조회용 DTO 설계가 간결하고 적절합니다.

멘토 지원서 이력 조회에 필요한 핵심 정보만 포함하여 깔끔합니다. applicationOrder 필드를 통해 전체 지원 순서를 파악할 수 있도록 한 점이 좋습니다. 기존 MentorApplicationResponse보다 단순화된 구조로 용도에 맞게 설계되었습니다.

src/main/java/com/example/solidconnection/admin/controller/AdminMentorApplicationController.java (1)

79-85: 사용자 존재 여부 검증이 서비스 레이어에서 처리되고 있습니다.

컨트롤러에서 별도로 siteUserId 검증을 하지 않지만, 테스트 코드(Line 611-613)를 확인한 결과 서비스 레이어에서 USER_NOT_FOUND 예외를 던지고 있어 적절하게 처리되고 있습니다.

src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java (1)

515-615: 멘토 지원서 이력 조회 테스트가 매우 포괄적입니다.

새로운 이력 조회 기능에 대한 테스트가 다음 시나리오를 모두 커버하고 있어 훌륭합니다:

  1. 기본 이력 조회 및 정렬 검증 (Lines 519-540)

    • 최신 생성 내림차순 정렬 확인
    • applicationOrder 필드 검증
  2. 5개 제한 검증 (Lines 543-568)

    • 7개 생성 시 최신 5개만 반환되는지 확인
  3. 빈 이력 처리 (Lines 571-580)

    • 지원서가 없을 때 빈 리스트 반환
  4. 응답 필드 검증 (Lines 583-603)

    • 상태값과 거절 사유가 올바르게 포함되는지 확인
  5. 에러 처리 (Lines 606-614)

    • 존재하지 않는 사용자 조회 시 예외 발생 검증

applicationOrder가 반환된 목록 내 순위가 아닌 전체 지원 이력에서의 순서를 나타내는 점도 잘 검증되었습니다.

src/main/java/com/example/solidconnection/admin/service/AdminMentorApplicationService.java (2)

33-33: 새로운 의존성 주입이 적절합니다.

유저 존재 여부 검증을 위해 SiteUserRepository가 추가되었습니다. 새로 추가된 히스토리 조회 기능에 필요한 의존성이며, 기존 패턴과 일관되게 구성되어 있습니다.


52-55: 파라미터 타입 변경은 호환성 문제가 없습니다.

검토 결과:

  1. 메서드 구현: rejectMentorApplication(Long mentorApplicationId, ...) 파라미터는 이미 박싱된 Long 타입입니다.

  2. 호출 지점 확인:

    • 컨트롤러에서는 @PathVariable("mentor-application-id") Long mentorApplicationId로 받은 Long 타입을 그대로 전달합니다.
    • 테스트에서는 원시 long 타입을 사용하나, Java의 오토박싱이 자동으로 Long으로 변환합니다.
  3. 결론: 모든 호출자가 이미 호환되어 있으므로 추가 조정은 필요하지 않습니다.

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

18-20: 새로운 쿼리 메서드 구현이 완벽합니다.

추가된 두 메서드는 Spring Data JPA 3.1.5의 query derivation 규칙을 정확하게 따르고 있습니다:

  1. findTop5BySiteUserIdOrderByCreatedAtDesc

    • 생성일 기준 내림차순으로 상위 5개를 조회하는 명확한 의도
  2. countBySiteUserId

    • 특정 유저의 지원서 총 개수를 카운트

기존 메서드들과 동일하게 primitive long 타입을 사용하여 코드의 일관성도 잘 유지되고 있습니다.

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