Skip to content

Conversation

@sukangpunch
Copy link
Contributor

@sukangpunch sukangpunch commented Nov 23, 2025

관련 이슈

작업 내용

멘토 지원서 관련하여 페이징 조회 기능을 추가하였습니다.
이전에 작성되어있는 어드민 성적 페이징 조회 기능을 그대로 참고 하였습니다.

기획 내용에서 text 기반 다수 칼럼 을 조회하는 것을 선호한다고 하여,
test 기반 조회가 가능해 보이는 닉네임, 권역, 나라, 파견학교 등에 대해서 매칭 하여 조회를 가능하게 하였습니다.

특이 사항

아직 부족한 점은, 검색에 있어서 우선순위가 존재하지 않습니다.

  • 어떤 칼럼이든 매칭이 된다면 포함하는 것이기 때문에 칼럼 별 우선순위나, 풀매칭, 부분매칭 에 대한 우선순위가 고려되어있지 않습니다.

브루노 업데이트도 추후 진행하도록 하겠습니다!

리뷰 요구사항 (선택)

* feat: mentor/repository 패키지에 custom 패키지 추가

- custom 패키지에 페이징 조회를 책임지는 MentorApplicationFilterRepository 추가

- MentorApplicationSearchCondition 에서 넘긴 keyword 기반으로 닉네임, 권역, 나라, 학교명으로 필터링 검색 기능 추가

- MentorApplicationSearchCondition 에서 넘긴 mentorApplicationStatus 기반으로 승인, 거절, 진행중 으로 필터링 기능 추가
@coderabbitai
Copy link

coderabbitai bot commented Nov 23, 2025

Walkthrough

  1. REST 엔드포인트 추가 — /admin/mentor-applications GET 컨트롤러가 추가되어 검색 조건과 페이징을 수신합니다.
  2. DTO 확장 — MentorApplicationSearchCondition, MentorApplicationResponse, MentorApplicationSearchResponse 같은 레코드형 DTO들이 추가되었습니다.
  3. 서비스 추가 — AdminMentorApplicationService가 리포지토리에 위임하는 읽기 전용 검색 메서드를 제공합니다.
  4. 리포지토리 확장 — MentorApplicationRepository가 MentorApplicationFilterRepository를 확장하고 QueryDSL 기반 구현체가 추가되었습니다.
  5. 엔티티 변경 — MentorApplication 엔티티에 ZonedDateTime 타입의 approvedAt 필드가 추가되었습니다.
  6. 테스트 추가 — 다양한 필터와 페이징 시나리오를 검증하는 통합 테스트가 추가되었습니다.
  7. DB 마이그레이션 — approved_at 컬럼 추가 및 기존 승인 행에 대해 초기값을 채우는 마이그레이션 스크립트가 추가되었습니다.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50분

  • QueryDSL의 콘텐츠/카운트 쿼리 동기화 및 조인 조건(키워드 유무에 따른 조인 포함)을 검증해야 합니다.
  • createdAt에 대한 로컬 날짜 범위 계산 및 타임존 처리 로직을 주의 깊게 확인하세요.
  • DB 마이그레이션의 기존 데이터 영향(널 처리, 타임스탬프 포맷)을 점검하세요.
  • 컨트롤러-서비스-리포지토리 흐름과 DTO 매핑(특히 생성자 프로젝션)을 검토하세요.

Suggested reviewers

  • wibaek
  • whqtker
  • Hexeong
  • JAEHEE25
  • lsy1307
  • Gyuhyeok99

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 제목은 '어드민 멘토 승격 요청 페이징 조회 기능 추가'로 변경사항의 핵심(어드민 멘토 애플리케이션의 페이징 조회 기능)을 명확하게 요약하고 있습니다.
Description check ✅ Passed PR 설명은 템플릿의 필수 섹션(관련 이슈, 작업 내용, 특이 사항)을 모두 포함하고 있으며, 작업 내용과 제한사항이 충분히 기술되어 있습니다.
Linked Issues check ✅ Passed PR의 모든 변경사항은 #528의 요구사항인 '멘토 승격 요청 페이징 조회 API 추가'를 충족합니다. 컨트롤러, 서비스, 저장소, DTO, 테스트, DB 마이그레이션 모두 이 목표를 지원합니다.
Out of Scope Changes check ✅ Passed 모든 변경사항이 멘토 승격 요청 페이징 조회 기능(#528)의 범위 내에 있으며, 범위를 벗어나는 변경사항은 발견되지 않습니다.
✨ 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 (4)
src/main/java/com/example/solidconnection/mentor/repository/custom/MentorApplicationFilterRepositoryImpl.java (2)

31-94: 1) 멘토 지원서 검색 쿼리 설계 전반적으로 잘 맞습니다

  1. 세 가지 DTO projection을 static 상수로 만들어 select(...)에 재사용하는 구조가 깔끔하고, N+1 없이 한 번에 필요한 필드를 모두 가져오는 점이 좋습니다.
  2. mentorStatus, keyword, createdAt를 각각 helper 메서드로 분리해서 content 쿼리와 count 쿼리에서 동일한 where 조건을 공유하는 것도 페이지네이션 일관성 유지에 도움이 됩니다.
  3. 키워드 검색을 닉네임/대학/지역/나라 containsIgnoreCase OR 조합으로 구현한 부분이 기획에서 말한 “텍스트 기반 다수 컬럼 조회, 우선순위 없음” 요구사항과 잘 들어맞습니다.
  4. totalCountnull일 가능성은 사실상 없어서 totalCount != null ? totalCount : 0L는 방어 코드에 가깝지만, 문제는 아니고 유지하셔도 무방합니다.
  5. PENDING 상태에서 universityId가 null일 수 있어 left join을 사용하는 구조가 필요한데, 여기서 leftJoin(university)...leftJoin(region)...leftJoin(country)를 쓰신 방향이 그 비즈니스 규칙과도 잘 맞습니다. (Based on learnings, universityId-null 규칙 확인됨)

65-70: 2) 생성자 @Autowired는 선택 사항이라 제거해도 됩니다 (선택)

  1. 스프링 부트에서 생성자가 하나뿐인 경우에는 @Autowired가 없어도 자동 주입되므로, MentorApplicationFilterRepositoryImpl(EntityManager em) 위의 @Autowired는 생략 가능한 보일러플레이트입니다.
  2. 팀 코드 스타일이 “생성자에는 @Autowired 생략”이라면 제거해서 다른 빈들과 일관성을 맞추는 것도 좋겠습니다.
src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java (2)

27-29: 2) 테스트 클래스 @DisplayName 문구가 도메인과 조금 어긋납니다 (선택)

  1. 현재 클래스 레벨 @DisplayName("어학 검증 관리자 서비스 테스트")는 이전 테스트에서 복사된 것으로 보이고, 실제로는 “멘토 승격 지원서 목록 조회”에 대한 테스트입니다.
  2. 추후 리포트/IDE에서 테스트 명세를 볼 때 헷갈리지 않도록, 예를 들어 "관리자 멘토 승격 지원서 서비스 테스트"처럼 이 도메인에 맞는 이름으로 정리해 두면 좋겠습니다.

161-180: 3) 날짜 조건 테스트에서 LocalDate.now() 사용은 향후 유지보수 시 주의가 필요합니다 (선택)

  1. MentorApplicationSearchConditioncreatedAtLocalDate.now()로 셋업하면, 테스트 실행 시점의 ‘오늘 날짜’에 생성된 신청서만 조회하는 동작은 잘 검증됩니다.
  2. 다만 나중에 fixture에서 createdAt을 명시적으로 다른 날짜로 세팅하거나, 타임존 설정을 바꾸는 등의 변경이 생기면 이 테스트가 의도치 않게 깨질 수 있으니, 필요하다면 fixture에서 createdAt을 고정 날짜로 세팅하고 그 날짜를 조건에 넘기는 형태로 바꾸는 것도 고려해볼 만합니다.
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0e9d476 and bbde8fc.

📒 Files selected for processing (11)
  • src/main/java/com/example/solidconnection/admin/controller/AdminMentorApplicationController.java (1 hunks)
  • src/main/java/com/example/solidconnection/admin/dto/MentorApplicationResponse.java (1 hunks)
  • src/main/java/com/example/solidconnection/admin/dto/MentorApplicationSearchCondition.java (1 hunks)
  • src/main/java/com/example/solidconnection/admin/dto/MentorApplicationSearchResponse.java (1 hunks)
  • src/main/java/com/example/solidconnection/admin/service/AdminMentorApplicationService.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/domain/MentorApplication.java (2 hunks)
  • src/main/java/com/example/solidconnection/mentor/repository/MentorApplicationRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/repository/custom/MentorApplicationFilterRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/mentor/repository/custom/MentorApplicationFilterRepositoryImpl.java (1 hunks)
  • src/main/resources/db/migration/V39__add_approved_at_mentro_application.sql (1 hunks)
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java (1 hunks)
🧰 Additional context used
🧠 Learnings (4)
📚 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/dto/MentorApplicationResponse.java
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
📚 Learning: 2025-11-20T14:03:56.450Z
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.450Z
Learning: MentorApplication의 universityId는 PENDING 상태에서는 null일 수 있지만, admin이 승인(APPROVED)할 때 반드시 대학 데이터를 생성하고 universityId를 채운 후 승인하므로, APPROVED 상태의 MentorApplication은 항상 non-null universityId를 가진다는 것이 비즈니스 규칙이다.

Applied to files:

  • src/main/java/com/example/solidconnection/mentor/domain/MentorApplication.java
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
📚 Learning: 2025-09-30T09:16:14.993Z
Learnt from: Gyuhyeok99
Repo: solid-connection/solid-connect-server PR: 522
File: src/main/java/com/example/solidconnection/common/BaseEntity.java:39-41
Timestamp: 2025-09-30T09:16:14.993Z
Learning: BaseEntity와 같은 엔티티의 타임스탬프 필드는 테스트를 위해 public setter를 추가하지 말고, reflection이나 EntityManager를 활용한 테스트 전용 헬퍼를 사용해야 합니다. 프로덕션 코드의 캡슐화를 유지하는 것이 중요합니다.

Applied to files:

  • src/main/java/com/example/solidconnection/mentor/domain/MentorApplication.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/main/resources/db/migration/V39__add_approved_at_mentro_application.sql
🧬 Code graph analysis (2)
src/main/java/com/example/solidconnection/admin/service/AdminMentorApplicationService.java (1)
src/main/java/com/example/solidconnection/admin/controller/AdminMentorApplicationController.java (1)
  • RequiredArgsConstructor (18-37)
src/main/java/com/example/solidconnection/admin/controller/AdminMentorApplicationController.java (1)
src/main/java/com/example/solidconnection/admin/service/AdminMentorApplicationService.java (1)
  • RequiredArgsConstructor (12-25)
⏰ 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/java/com/example/solidconnection/admin/dto/MentorApplicationSearchResponse.java (1)

1-8: 깔끔한 복합 DTO 설계입니다!

사용자 정보와 멘토 지원서 정보를 하나의 검색 결과로 묶는 구조가 명확하고 적절합니다.

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

5-10: 커스텀 필터 리포지토리 확장이 올바르게 구현되었습니다!

MentorApplicationFilterRepository 인터페이스를 확장하여 페이징 검색 기능을 추가한 구조가 Spring Data JPA의 표준 패턴을 잘 따르고 있습니다.

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

1-18: 어드민 응답 DTO가 잘 설계되었습니다!

멘토 지원서 정보를 표현하는 데 필요한 모든 필드가 포함되어 있고, 새로 추가된 approvedAt 필드도 적절히 포함되어 있습니다.

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

1-12: 커스텀 리포지토리 인터페이스가 명확하게 정의되었습니다!

페이징 검색을 위한 메서드 시그니처가 Spring Data의 컨벤션을 잘 따르고 있으며, 검색 조건과 페이징 파라미터를 적절히 수용하고 있습니다.

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

1-25: 서비스 레이어가 깔끔하게 구현되었습니다!

다음과 같이 적절히 설계되었습니다:

  1. 읽기 전용 트랜잭션: @Transactional(readOnly = true) 애노테이션으로 조회 성능 최적화
  2. 명확한 위임: 리포지토리로 직접 위임하는 구조로 불필요한 복잡도 없음
  3. 일관된 명명: 메서드명이 의도를 명확히 표현
src/main/java/com/example/solidconnection/admin/dto/MentorApplicationSearchCondition.java (1)

6-9: 타임존 변환이 올바르게 처리되고 있습니다.

검증 결과, MentorApplicationFilterRepositoryImplcreatedAtEq() 메서드(132-143번 라인)에서 다음과 같이 안전하게 처리하고 있습니다:

  1. LocalDate를 받아 일일 범위로 변환 (atStartOfDay() 사용)
  2. 시스템 타임존을 명시적으로 지정 (.atZone(SYSTEM_ZONE_ID))
  3. ZonedDateTime 타입의 엔티티 필드와 between() 비교 수행

타임존 정보 손실에 대한 우려는 구현체에서 이미 올바르게 해결되어 있으므로, 추가 조치가 필요 없습니다.

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

70-71: 멘토 지원서 승인 처리 기능이 완전히 구현되지 않았습니다.

검증 결과, approvedAt 필드는 도메인 엔티티와 DTO에 정의되어 있지만 실제로 값을 설정하는 비즈니스 로직이 전혀 없습니다. 더 심각한 문제는 멘토 지원서를 승인(APPROVED) 또는 거절하는 기능 자체가 구현되지 않았다는 점입니다.

다음 항목들이 필요합니다:

  1. MentorApplication 엔티티에 상태 변경 메서드 추가

    • approve() 메서드: 상태를 APPROVED로 변경하고 approvedAt을 현재 시간으로 설정
    • reject() 메서드: 상태를 REJECTED로 변경하고 거절 사유 저장
  2. AdminMentorApplicationService에 승인/거절 비즈니스 로직 추가

    • 멘토 지원서 조회 후 상태 변경 메서드 호출
    • 거절 시 사유 저장
  3. AdminMentorApplicationController에 승인/거절 엔드포인트 추가

    • PUT 또는 POST 엔드포인트로 승인/거절 요청 처리

현재 controller와 service에는 검색(GET) 기능만 있고, approve/reject 엔드포인트가 전혀 없습니다.

⛔ Skipped due to learnings
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.450Z
Learning: MentorApplication의 universityId는 PENDING 상태에서는 null일 수 있지만, admin이 승인(APPROVED)할 때 반드시 대학 데이터를 생성하고 universityId를 채운 후 승인하므로, APPROVED 상태의 MentorApplication은 항상 non-null universityId를 가진다는 것이 비즈니스 규칙이다.
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을 추가하지 않아야 한다.
src/main/java/com/example/solidconnection/admin/controller/AdminMentorApplicationController.java (1)

18-36: 1) 관리자 멘토 지원서 페이징 조회 컨트롤러 구조가 자연스럽습니다

  1. @Valid @ModelAttribute로 검색 조건 DTO를 바인딩하고, Pageable을 그대로 서비스에 넘기는 패턴이 기존 스프링 관용구와 잘 맞습니다.
  2. 서비스에서 받은 Page를 공통 PageResponse.of(page)로 감싸 ResponseEntity.ok(...)로 반환하는 것도 응답 일관성 측면에서 좋아 보입니다.
src/main/java/com/example/solidconnection/mentor/repository/custom/MentorApplicationFilterRepositoryImpl.java (1)

132-144: 3) createdAt 일자 필터는 의도대로 ‘하루 구간’으로 잘 잘리고 있습니다

  1. LocalDate createdAt을 받아 startOfDay ~ endOfDay(+1일 시작 - 1ns)로 구간을 만든 뒤, createdAt 컬럼과 between으로 비교하는 방식이라 “특정 날짜에 생성된 신청서만” 잘 필터링될 것으로 보입니다.
  2. 애플리케이션과 DB가 같은 타임존(또는 UTC 기반 ZonedDateTime)으로 운용된다는 전제에서는, 관리자 화면에서 기대하는 날짜 검색 UX와도 자연스럽게 맞을 것 같습니다.

Comment on lines +1 to +7
ALTER TABLE mentor_application
ADD COLUMN approved_at DATETIME(6);

UPDATE mentor_application
SET approved_at = NOW()
WHERE mentor_application_status = 'APPROVED'
AND approved_at IS NULL;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

마이그레이션 파일명에 오타가 있습니다.

파일명이 V39__add_approved_at_mentro_application.sql인데, mentromentor의 오타로 보입니다.

다음과 같이 파일명을 수정해주세요:

-V39__add_approved_at_mentro_application.sql
+V39__add_approved_at_mentor_application.sql

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In src/main/resources/db/migration/V39__add_approved_at_mentro_application.sql
lines 1-7 the filename contains a typo ("mentro" → "mentor"); rename the file to
V39__add_approved_at_mentor_application.sql (use git mv to preserve history),
keep the file contents unchanged, and update any references or build/migration
config that refer to the old filename so the migration tool recognizes the
corrected migration.

Comment on lines +4 to +7
UPDATE mentor_application
SET approved_at = NOW()
WHERE mentor_application_status = 'APPROVED'
AND approved_at IS NULL;
Copy link

@coderabbitai coderabbitai bot Nov 23, 2025

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

기존 승인 데이터의 실제 승인 시점이 손실됩니다.

4-7번 라인의 UPDATE 구문이 모든 기존 APPROVED 레코드에 대해 NOW()를 사용하여 동일한 타임스탬프를 설정합니다. 이는 각 멘토 지원서가 실제로 승인된 시점 정보를 잃게 되어 히스토리 추적이 불가능해집니다.

더 나은 접근 방법:

  1. 선호하는 방식: created_at을 대체 값으로 사용 - 승인 시점의 근사치로 활용
  2. 대안: 기존 데이터는 NULL로 두고, 향후 승인부터만 정확한 시점 기록

방식 1을 적용한 diff:

 UPDATE mentor_application
-SET approved_at = NOW()
+SET approved_at = created_at
 WHERE mentor_application_status = 'APPROVED'
   AND approved_at IS NULL;

참고: Line 7의 AND approved_at IS NULL 체크는 방금 추가된 컬럼이므로 모든 값이 NULL이어서 실제로는 불필요합니다만, 재실행 방어를 위해 유지하는 것도 합리적입니다.

🤖 Prompt for AI Agents
In src/main/resources/db/migration/V39__add_approved_at_mentro_application.sql
around lines 4-7, the UPDATE uses NOW() which overwrites historical approval
times; instead set approved_at to the row's created_at as an approximate
approval timestamp: run UPDATE mentor_application SET approved_at = created_at
WHERE mentor_application_status = 'APPROVED' AND approved_at IS NULL; keep the
approved_at IS NULL guard for idempotency (or, if preferred, leave existing rows
NULL and only populate future approvals).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@coderabbitai 현재 서비스에서 승인 된 멘토 지원서는 존재할 수 없다는 가정이면?

Copy link

Choose a reason for hiding this comment

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

@sukangpunch 좋은 지적입니다!

만약 현재 프로덕션/스테이징 환경에 APPROVED 상태의 멘토 지원서가 존재하지 않는다면, 제가 제기한 우려는 해당되지 않습니다. UPDATE 구문이 0개의 행에 영향을 미치므로 데이터 손실 문제가 발생하지 않습니다.

해당 가정이 맞다면 현재 마이그레이션 스크립트는 안전합니다. 다만 확실성을 위해:

1. 이 가정을 확인해주실 수 있나요?

  • 현재 운영/스테이징 DB에 mentor_application_status = 'APPROVED'인 레코드가 0건인지 확인

2. (선택사항) 명확성을 위해 주석 추가를 고려해보시겠어요?

-- Note: As of this migration, no APPROVED mentor applications exist in production/staging
-- This UPDATE serves as a defensive measure for any edge cases
UPDATE mentor_application
SET approved_at = NOW()
WHERE mentor_application_status = 'APPROVED'
  AND approved_at IS NULL;

가정이 맞다면 현재 코드 그대로 진행하셔도 괜찮습니다! 👍


🧠 Learnings used
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.

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.450Z
Learning: MentorApplication의 universityId는 PENDING 상태에서는 null일 수 있지만, admin이 승인(APPROVED)할 때 반드시 대학 데이터를 생성하고 universityId를 채운 후 승인하므로, APPROVED 상태의 MentorApplication은 항상 non-null universityId를 가진다는 것이 비즈니스 규칙이다.

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

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bbde8fc and a9dd644.

📒 Files selected for processing (2)
  • src/main/resources/db/migration/V39__add_approved_at_mentor_application.sql (1 hunks)
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 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/main/resources/db/migration/V39__add_approved_at_mentor_application.sql
📚 Learning: 2025-11-20T14:03:56.450Z
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.450Z
Learning: MentorApplication의 universityId는 PENDING 상태에서는 null일 수 있지만, admin이 승인(APPROVED)할 때 반드시 대학 데이터를 생성하고 universityId를 채운 후 승인하므로, APPROVED 상태의 MentorApplication은 항상 non-null universityId를 가진다는 것이 비즈니스 규칙이다.

Applied to files:

  • src/main/resources/db/migration/V39__add_approved_at_mentor_application.sql
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
📚 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/resources/db/migration/V39__add_approved_at_mentor_application.sql
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
⏰ 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 (3)
src/main/resources/db/migration/V39__add_approved_at_mentor_application.sql (2)

1-2: 승인된 멘토 지원서의 승인 시점 추적을 위한 컬럼 추가, LGTM!

DATETIME(6) 타입은 microsecond 정밀도를 제공하여 Java의 ZonedDateTime과 잘 매칭됩니다.


4-7: 기존 논의 사항이 해결되었으므로 승인합니다.

과거 리뷰에서 제기된 히스토리 손실 우려는 프로덕션/스테이징에 APPROVED 상태의 데이터가 없다는 확인을 통해 해결되었습니다. AND approved_at IS NULL 조건은 재실행 방어를 위한 좋은 관행입니다.

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

72-92: 나머지 테스트 메서드들은 잘 작성되었습니다!

  1. 상태별 필터링 테스트는 PENDING 상태를 올바르게 검증합니다.
  2. 닉네임, 대학명, 지역명 키워드 검색 테스트들이 적절한 예상 결과와 함께 구성되어 있습니다.
  3. 복합 조건 테스트도 모든 필터가 함께 작동하는지 확인합니다.
  4. 과거 리뷰에서 지적된 response.get() 이슈가 response.getContent()로 올바르게 수정되었습니다.

Also applies to: 94-115, 117-138, 140-161, 186-210

* fix: flyway V39 스크립트 파일명 수정

* test: 테스트 코드 오류 수정, 검증 추가  
@sukangpunch sukangpunch force-pushed the feat/528-admin-mentor-application-pagination branch from a9dd644 to 9d8bedd Compare November 23, 2025 09:16
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

♻️ Duplicate comments (1)
src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java (1)

27-29: DisplayName이 여전히 테스트 내용과 불일치합니다.

이전 리뷰에서 지적되었지만 아직 수정되지 않았습니다. 클래스는 멘토 지원서 관리 서비스를 테스트하는데, DisplayName은 "어학 검증 관리자 서비스 테스트"로 되어 있습니다.

다음과 같이 수정하세요:

-@DisplayName("어학 검증 관리자 서비스 테스트")
+@DisplayName("어드민 멘토 지원서 관리 서비스 테스트")
🧹 Nitpick comments (1)
src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java (1)

69-211: 추가 테스트 케이스 고려를 제안합니다.

현재 테스트는 주요 기능을 잘 검증하고 있지만, 다음과 같은 추가 테스트를 고려하면 더욱 견고해질 수 있습니다:

  1. 엣지 케이스 테스트

    • 검색 결과가 없는 경우 (존재하지 않는 키워드 검색)
    • 빈 문자열이나 null 키워드로 검색하는 경우
    • 페이지 크기가 0이거나 음수인 경우
  2. 복합 검색 테스트

    • 키워드가 여러 컬럼(닉네임, 대학명, 지역명, 국가명)에 동시에 매칭되는 케이스
    • 키워드가 한 엔티티의 여러 필드에 걸쳐 매칭되는 케이스
  3. 정렬/순서 검증

    • 조회 결과의 정렬 순서가 의도한 대로인지 검증 (예: 생성일 기준)
  4. 페이징 경계 테스트

    • 마지막 페이지 조회
    • 존재하지 않는 페이지 번호 조회
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a9dd644 and 9d8bedd.

📒 Files selected for processing (2)
  • src/main/resources/db/migration/V39__add_approved_at_mentor_application.sql (1 hunks)
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/main/resources/db/migration/V39__add_approved_at_mentor_application.sql
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
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.450Z
Learning: MentorApplication의 universityId는 PENDING 상태에서는 null일 수 있지만, admin이 승인(APPROVED)할 때 반드시 대학 데이터를 생성하고 universityId를 채운 후 승인하므로, APPROVED 상태의 MentorApplication은 항상 non-null universityId를 가진다는 것이 비즈니스 규칙이다.
📚 Learning: 2025-11-20T14:03:56.450Z
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.450Z
Learning: MentorApplication의 universityId는 PENDING 상태에서는 null일 수 있지만, admin이 승인(APPROVED)할 때 반드시 대학 데이터를 생성하고 universityId를 채운 후 승인하므로, APPROVED 상태의 MentorApplication은 항상 non-null universityId를 가진다는 것이 비즈니스 규칙이다.

Applied to files:

  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
📚 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/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
⏰ 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 (7)
src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java (7)

50-67: 테스트 픽스처 구성이 적절합니다.

다양한 상태(APPROVED, PENDING, REJECTED)와 여러 대학을 조합하여 검색 시나리오를 충분히 커버할 수 있는 테스트 데이터가 잘 준비되었습니다.


72-92: LGTM! 상태 필터링 테스트가 올바릅니다.

PENDING 상태로 필터링하여 예상된 결과를 정확하게 검증하고 있습니다.


94-115: LGTM! 닉네임 필터링 테스트가 올바릅니다.

특정 닉네임으로 검색하여 해당하는 지원서만 조회되는지 정확하게 검증하고 있습니다.


117-138: LGTM! 대학명 필터링 테스트가 올바릅니다.

대학명으로 검색하여 해당 대학의 지원서들만 조회되는지 정확하게 검증하고 있습니다.


140-161: LGTM! 지역명 필터링 테스트가 올바릅니다.

지역명으로 검색하여 해당 지역의 지원서들만 조회되는지 정확하게 검증하고 있습니다.


163-184: LGTM! 나라명 필터링 테스트가 올바릅니다.

국가명으로 검색하여 해당 국가의 지원서들만 조회되는지 정확하게 검증하고 있습니다. 그라츠 대학은 오스트리아에 위치하므로 예상 결과가 올바릅니다.


186-210: 추가 정보가 필요합니다. 다음 사항을 확인하겠습니다:

테스트에서 LocalDate.now() 사용 시 시간대 경계 문제 검토 필요합니다.

Line 190에서 LocalDate.now()를 생성일 필터 기준으로 사용하고 있는데, 다음 사항들을 확인하세요:

  1. fixture 생성 시점: MentorApplicationFixture에서 명시적인 생성 날짜 설정이 없어 JPA 자동 타임스탬프(LocalDateTime)에 의존합니다.

  2. 타입 불일치 위험: LocalDate를 LocalDateTime 필드와 비교할 때는 between 쿼리(atStartOfDay() ~ plusDays(1).atStartOfDay())를 사용해야 합니다. searchMentorApplications 메서드가 이를 적절히 처리하는지 확인하세요.

  3. 간헐적 실패 가능성: 테스트와 fixture 생성 시점 간격에 따라 테스트가 실패할 수 있습니다(예: fixture 생성 23:59, 테스트 실행 다음날 00:01).

제안사항:

  • LocalDate.now() 대신 테스트 메서드 내에서 생성할 때 사용한 구체적인 날짜 사용
  • 또는 searchMentorApplications 구현이 날짜 비교를 올바르게 처리하는지 확인

@sukangpunch sukangpunch force-pushed the feat/528-admin-mentor-application-pagination branch from 9d8bedd to 06a0492 Compare November 23, 2025 09:26
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/admin/service/AdminMentorApplicationServiceTest.java (2)

75-75: 코드 컨벤션: 쉼표 뒤 공백 추가를 권장합니다.

null, 다음에 공백이 누락되었습니다. 일관된 코드 스타일을 위해 추가를 고려해보세요.

-            MentorApplicationSearchCondition condition = new MentorApplicationSearchCondition(MentorApplicationStatus.PENDING,null, null);
+            MentorApplicationSearchCondition condition = new MentorApplicationSearchCondition(MentorApplicationStatus.PENDING, null, null);

72-210: 선택사항: 반복되는 검증 패턴을 헬퍼 메서드로 추출할 수 있습니다.

  1. 6개 테스트 모두 동일한 assertion 패턴을 사용하고 있습니다.
  2. 코드 중복을 줄이고 유지보수성을 높이기 위해 헬퍼 메서드 추출을 고려해보세요.

예시:

private void assertMentorApplicationIds(
    Page<MentorApplicationSearchResponse> response, 
    List<MentorApplication> expected
) {
    assertThat(response.getContent()).hasSize(expected.size());
    assertThat(response.getContent())
        .extracting(content -> content.mentorApplicationResponse().id())
        .containsOnly(expected.stream()
            .map(MentorApplication::getId)
            .toArray(Long[]::new));
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9d8bedd and 06a0492.

📒 Files selected for processing (1)
  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java (1 hunks)
🧰 Additional context used
🧠 Learnings (3)
📓 Common learnings
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.450Z
Learning: MentorApplication의 universityId는 PENDING 상태에서는 null일 수 있지만, admin이 승인(APPROVED)할 때 반드시 대학 데이터를 생성하고 universityId를 채운 후 승인하므로, APPROVED 상태의 MentorApplication은 항상 non-null universityId를 가진다는 것이 비즈니스 규칙이다.
📚 Learning: 2025-11-20T14:03:56.450Z
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.450Z
Learning: MentorApplication의 universityId는 PENDING 상태에서는 null일 수 있지만, admin이 승인(APPROVED)할 때 반드시 대학 데이터를 생성하고 universityId를 채운 후 승인하므로, APPROVED 상태의 MentorApplication은 항상 non-null universityId를 가진다는 것이 비즈니스 규칙이다.

Applied to files:

  • src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
📚 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/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
⏰ 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 (5)
src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java (5)

27-67: 테스트 설정이 잘 구성되어 있습니다.

  1. 통합 테스트 환경이 적절하게 설정되었습니다.
  2. 다양한 상태(승인, 대기, 거절)와 대학 조합으로 테스트 데이터를 준비했습니다.
  3. 검색 시나리오를 충분히 커버할 수 있는 픽스처가 마련되었습니다.

94-115: 닉네임 검색 테스트가 올바르게 구현되었습니다.

  1. 검색 조건과 예상 결과가 일치합니다.
  2. ID와 닉네임을 모두 검증하고 있습니다.

117-138: 대학명 검색 테스트가 올바르게 작성되었습니다.

  1. 검색 키워드와 픽스처 데이터가 일치합니다.
  2. 대학명 필드 검증이 정확합니다.

140-161: 지역명 검색 테스트가 정확합니다.

  1. 유럽 지역 검색이 올바른 대학(그라츠)을 반환합니다.
  2. 검색 결과 검증이 적절합니다.

163-184: 나라명 검색 테스트가 올바르게 수정되었습니다.

  1. 오스트리아 검색이 정확한 데이터(그라츠 대학)를 반환합니다.
  2. 이전 리뷰에서 지적된 데이터 불일치가 해결되었습니다.

Comment on lines +186 to +210
@Test
void 모든_조건으로_페이징하여_조회한다() {
// given
String regionKoreanName = "영미권";
MentorApplicationSearchCondition condition = new MentorApplicationSearchCondition(MentorApplicationStatus.PENDING, regionKoreanName, LocalDate.now());
Pageable pageable = PageRequest.of(0, 10);
List<MentorApplication> expectedMentorApplications = List.of(mentorApplication2);

// when
Page<MentorApplicationSearchResponse> response = adminMentorApplicationService.searchMentorApplications(condition, pageable);

// then
assertThat(response.getContent()).hasSize(expectedMentorApplications.size());
assertThat(response.getContent())
.extracting(content -> content.mentorApplicationResponse().id())
.containsOnly(expectedMentorApplications.stream()
.map(MentorApplication::getId)
.toArray(Long[]::new));
assertThat(response.getContent())
.extracting(content -> content.mentorApplicationResponse().mentorApplicationStatus())
.containsOnly(MentorApplicationStatus.PENDING);
assertThat(response.getContent())
.extracting(content -> content.mentorApplicationResponse().region())
.containsOnly(regionKoreanName);
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

시간 의존적인 테스트 코드를 개선해주세요.

  1. Line 190에서 LocalDate.now()를 사용하여 생성일자를 필터링하고 있습니다.
  2. 이 테스트는 픽스처가 오늘 날짜로 데이터를 생성한다고 가정하고 있어 취약합니다.
  3. CI/CD 환경이나 다른 시간대에서 실행 시 간헐적으로 실패할 수 있습니다.

다음 방법 중 하나를 권장합니다:

  • 방법 1: 픽스처에서 명시적인 날짜를 설정하고 테스트에서도 동일한 날짜 사용
  • 방법 2: 날짜를 모킹하거나 테스트용 고정 날짜 사용
  • 방법 3: createdAt 필터를 제외하고 status + keyword만으로 조합 테스트 수행

픽스처의 생성일자 동작을 확인하기 위해 다음 스크립트를 실행해주세요:


🏁 Script executed:

#!/bin/bash
# Description: Verify how MentorApplicationFixture sets creation timestamps

# Check fixture implementation for date/time handling
ast-grep --pattern $'class MentorApplicationFixture {
  $$$
}'

rg -A 10 "대기중_멘토신청|승인된_멘토신청|거절된_멘토신청" --type java -g "**/MentorApplicationFixture.java"

# Check if MentorApplication entity has any default timestamp behavior
rg -A 5 "@CreatedDate|@CreationTimestamp|createdAt" --type java -g "**/MentorApplication.java"

Length of output: 4236


[/run_scripts]


🏁 Script executed:

#!/bin/bash
# Get full MentorApplicationFixtureBuilder to see if createdAt is set by default

rg -A 50 "class MentorApplicationFixtureBuilder" --type java

# Check the test setup - how is mentorApplication2 created?
rg -B 20 "모든_조건으로_페이징하여_조회한다" src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java | head -40

# Check MentorApplication entity for createdAt field definition
rg "class MentorApplication|private.*createdAt|LocalDate.*createdAt" --type java -g "**/MentorApplication.java" -A 3

Length of output: 8172


[/run_scripts]


🏁 Script executed:

#!/bin/bash
# Find BaseEntity to see if @CreatedDate is there
rg "class BaseEntity|@CreatedDate|@CreationTimestamp" --type java -g "**/BaseEntity.java" -A 5

# Find test setup - @BeforeEach or initialization of mentorApplication2
rg -B 5 "mentorApplication2 =" src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java

# Check the full test class setup area (first 100 lines)
rg "private MentorApplication|@BeforeEach" src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java -A 10 | head -60

Length of output: 2009


[/run_scripts]


🏁 Script executed:

#!/bin/bash
# Find MentorApplicationSearchCondition to see what type it expects
rg "class MentorApplicationSearchCondition|private.*createdAt|public.*createdAt" --type java -A 3

# Find the search query implementation to see how it filters by date
rg "searchMentorApplications|createdAt" --type java -B 3 -A 5 -g "**/AdminMentorApplicationService*.java"

Length of output: 12080


[/run_scripts]


🏁 Script executed:

#!/bin/bash
# Find the full implementation of createdAtEq method in MentorApplicationFilterRepositoryImpl
rg -A 10 "private BooleanExpression createdAtEq\(LocalDate" src/main/java/com/example/solidconnection/mentor/repository/custom/MentorApplicationFilterRepositoryImpl.java

# Also check for any timezone or date conversion logic
rg "ZonedDateTime|LocalDate|createdAt" src/main/java/com/example/solidconnection/mentor/repository/custom/MentorApplicationFilterRepositoryImpl.java -A 2 -B 2

Length of output: 1881


[/run_scripts]


🏁 Script executed:

#!/bin/bash
# Check what SYSTEM_ZONE_ID is set to
rg "SYSTEM_ZONE_ID" src/main/java/com/example/solidconnection/mentor/repository/custom/MentorApplicationFilterRepositoryImpl.java -B 5 -A 2

# Also check the full test context around line 186-210
rg -B 50 "모든_조건으로_페이징하여_조회한다" src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java | grep -A 50 "@BeforeEach"

Length of output: 651


테스트의 시간 의존성을 개선할 수 있습니다.

현재 코드를 검토한 결과, createdAtEq 메서드에서 LocalDate를 전체 하루 범위로 정확히 변환하고 있어 대부분의 경우 제대로 작동합니다. 다만 다음과 같은 점을 개선하면 더욱 견고한 테스트가 될 것입니다.

  1. 현재의 잠재적 위험성

    • 테스트 설정과 실행 사이에 자정을 기준으로 날짜가 변경될 가능성 (매우 드물지만 존재)
    • 시스템 타임존에 의존하여 다양한 환경에서 예측 불가능할 수 있음
  2. 개선 방법

    • 픽스처와 테스트에서 동일한 명시적 날짜를 사용하는 것을 권장합니다.
    • 현재: LocalDate.now()
    • 개선: LocalDate.of(2024, 11, 23) 같이 고정된 날짜 사용

이렇게 하면 테스트 실행 시점에 관계없이 일관되게 동작합니다.

🤖 Prompt for AI Agents
In
src/test/java/com/example/solidconnection/admin/service/AdminMentorApplicationServiceTest.java
around lines 186 to 210, replace the time-dependent LocalDate.now() used to
build the MentorApplicationSearchCondition with a fixed explicit date (e.g.
LocalDate.of(2024, 11, 23)) and ensure any related test fixtures that rely on
the same date use the identical fixed date so the createdAtEq range and
assertions remain stable across runs and timezones.

Copy link

@JAEHEE25 JAEHEE25 left a comment

Choose a reason for hiding this comment

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

고생하셨습니다!

Comment on lines +110 to +114
return query.where(
verifyMentorStatusEq(condition.mentorApplicationStatus()),
keywordContains(condition.keyword()),
createdAtEq(condition.createdAt())
);

Choose a reason for hiding this comment

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

함수로 나눠져 있어서 깔끔하네요!
조건이 더 복잡해지면 BooleanBuilder를 사용하는 것도 좋을 것 같습니다

Comment on lines +126 to +129
return siteUser.nickname.containsIgnoreCase(keyword)
.or(university.koreanName.containsIgnoreCase(keyword))
.or(region.koreanName.containsIgnoreCase(keyword))
.or(country.koreanName.containsIgnoreCase(keyword));

Choose a reason for hiding this comment

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

개인적인 생각으로는 일단 컬럼별 우선순위 없이 현재 방식을 유지해도 될 것 같습니다!

@sukangpunch sukangpunch merged commit d052325 into solid-connection:develop Nov 24, 2025
2 checks passed
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: 어드민 멘토 승격 요청 페이징 조회 기능 추가

2 participants