Conversation
|
Caution Review failedThe pull request is closed. Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. Summary by CodeRabbit릴리스 노트Bug Fixes
Refactor
Chores
✏️ Tip: You can customize this high-level summary in your review settings. Walkthrough미사용 API와 관련 인프라를 제거하고 일부 DTO를 resumebased 패키지로 이동하는 리팩터링입니다. Kakao 전용 로그아웃/탈퇴 엔드포인트, Kafka 프로듀서/프로듀서 사용 코드, Bedrock 클라이언트, 인터뷰 진행 관련 API/테스트 등이 삭제되었습니다. Changes
Sequence Diagram(s)(조건 불충족 — 변경은 주로 제거/리팩터링이며 새로운 다중 컴포넌트 제어 흐름 추가가 아니므로 다이어그램을 생략합니다.) Estimated code review effort🎯 4 (Complex) | ⏱️ ~40 minutes Possibly related PRs
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Comment |
Summary of ChangesHello @unifolio0, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request focuses on a significant refactoring effort to clean up the codebase by eliminating unused API endpoints and their underlying service logic. It also removes integrations with Kafka and Bedrock, suggesting a simplification or evolution of the system's external dependencies. A major DTO package reorganization for resume-based interview features further enhances the project's structure and maintainability. Highlights
🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console. Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Unused code, now gone, Kafka streams, no longer run, Cleaned up, new dawn. Footnotes
|
Test Results 40 files 40 suites 58s ⏱️ Results for commit 581cd2f. |
There was a problem hiding this comment.
Code Review
이 Pull Request는 사용하지 않는 API와 관련 코드를 제거하는 리팩토링을 주로 다루고 있습니다. Kafka 및 Bedrock 클라이언트 관련 로직, 특정 소셜 로그아웃/탈퇴 엔드포인트, 그리고 여러 컨트롤러의 미사용 API들이 성공적으로 제거되었습니다. 또한, DTO 패키지 구조 개선 및 코드 스타일 개선 등 전반적인 코드 품질 향상을 위한 변경 사항들이 포함되어 있습니다. 코드베이스에서 불필요한 부분을 덜어내어 유지보수성을 높이는 좋은 변경이라고 생각합니다. 몇 가지 추가 개선을 위한 제안 사항을 코멘트로 남겼습니다.
| @@ -3,4 +3,7 @@ | |||
| public abstract class AwsConstant { | |||
There was a problem hiding this comment.
| LocalDate yesterday = today.minusDays(1); | ||
| LocalDate twoDaysAgo = today.minusDays(2); | ||
| today.minusDays(2); |
There was a problem hiding this comment.
Actionable comments posted: 5
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
api/src/main/java/com/samhap/kokomen/auth/service/AuthService.java (1)
66-75: 동일한 쿼리를 두 번 호출하고 있습니다.
memberSocialLoginRepository.findByMember_Id(member.getId())가 KAKAO용과 GOOGLE용으로 각각 한 번씩 호출됩니다.logout()메서드(Line 85-91)처럼 한 번의 쿼리로 처리할 수 있습니다.♻️ 개선 제안
`@Transactional` public void withdraw(MemberAuth memberAuth) { Member member = memberService.readById(memberAuth.memberId()); - // 카카오 소셜로그인 정보 조회하여 카카오 연동해제 - memberSocialLoginRepository.findByMember_Id(member.getId()).stream() - .filter(socialLogin -> socialLogin.getProvider() == SocialProvider.KAKAO) - .findFirst() - .ifPresent(kakaoLogin -> kakaoOAuthClient.unlinkKakaoUser(Long.valueOf(kakaoLogin.getSocialId()))); - - // 구글 소셜로그인 정보 조회하여 구글 연동해제 - memberSocialLoginRepository.findByMember_Id(member.getId()).stream() - .filter(socialLogin -> socialLogin.getProvider() == SocialProvider.GOOGLE) - .findFirst() - .ifPresent(googleLogin -> googleOAuthClient.revokeGoogleToken(googleLogin.getSocialId())); + // 모든 소셜로그인 제공자에 대해 연동해제 처리 + memberSocialLoginRepository.findByMember_Id(member.getId()).forEach(socialLogin -> { + if (socialLogin.getProvider() == SocialProvider.KAKAO) { + kakaoOAuthClient.unlinkKakaoUser(Long.valueOf(socialLogin.getSocialId())); + } else if (socialLogin.getProvider() == SocialProvider.GOOGLE) { + googleOAuthClient.revokeGoogleToken(socialLogin.getSocialId()); + } + }); memberService.withdraw(member); }api/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV2Test.java (1)
253-253: REST Docs 문서 식별자 불일치이 테스트는
TTS_PENDING상태를 테스트하지만, 문서 식별자가"interview-getPolling-LLM-PENDING-V2"로 되어 있습니다."interview-getPolling-TTS-PENDING-V2"로 수정해야 합니다.동일한 문제가 304번 라인의
TTS_FAILED테스트에도 있습니다 ("interview-getPolling-LLM-FAILED-V2"→"interview-getPolling-TTS-FAILED-V2").🐛 문서 식별자 수정 제안
Line 253:
- .andDo(document("interview-getPolling-LLM-PENDING-V2", + .andDo(document("interview-getPolling-TTS-PENDING-V2",Line 304:
- .andDo(document("interview-getPolling-LLM-FAILED-V2", + .andDo(document("interview-getPolling-TTS-FAILED-V2",api/src/test/java/com/samhap/kokomen/interview/repository/InterviewRepositoryTest.java (1)
78-115: Line 86의 no-op 호출 제거 필요
today.minusDays(2);는 반환값을 사용하지 않아 테스트 의도가 불명확합니다. 필요 없다면 제거하고, 필요하면 변수로 저장해 사용하세요.🧹 제안 수정
- today.minusDays(2);
🤖 Fix all issues with AI agents
In `@api/src/main/java/com/samhap/kokomen/global/constant/AwsConstant.java`:
- Around line 3-8: The AwsConstant class is incorrectly declared abstract while
also having a private constructor; change it to follow the static-utility
pattern by making the class final (class AwsConstant -> final class AwsConstant)
and keeping the private constructor, or better yet remove this duplicate class
entirely and reference the existing AwsConstant in the common module (ensure api
depends on common and uses common.AwsConstant.CLOUD_FRONT_DOMAIN_URL) so there’s
a single source of truth for CLOUD_FRONT_DOMAIN_URL.
In
`@api/src/test/java/com/samhap/kokomen/answer/controller/AnswerControllerTest.java`:
- Around line 211-213: In AnswerControllerTest update the AssertJ assertions for
consistency: replace any uses of isEqualTo(1) with the idiomatic isOne() (e.g.,
the assertion around the like-count check in the test method that currently uses
isEqualTo(1)) and keep the existing isZero() used for the zero check; locate
these assertions inside the test method(s) in the AnswerControllerTest class
(the blocks referencing answerRepository.findById(...).get().getLikeCount() and
answerLikeRepository.existsByMemberIdAndAnswerId(...)) and change the numeric
equality assertions to isOne()/isZero() accordingly.
In
`@api/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV2Test.java`:
- Around line 449-452: Remove the leftover debug print by deleting the
System.out.println(...) call that prints
questionRepository.findTop2ByInterviewIdOrderByIdDesc(interview.getId()); keep
the QuestionFixtureBuilder save as-is; this means removing the
System.out.println statement referencing findTop2ByInterviewIdOrderByIdDesc and
interview.getId() so no debug output remains in InterviewControllerV2Test.
- Around line 385-388: Remove the leftover debug print in the test: delete the
System.out.println(...) call in InterviewControllerV2Test (the call that prints
questionRepository.findTop2ByInterviewIdOrderByIdDesc(interview.getId())).
Ensure no other System.out or similar debug logging remains in the test method
after you removed the unused question3 assignment, so test runs produce no
extraneous console output.
In
`@api/src/test/java/com/samhap/kokomen/member/repository/MemberRepositoryTest.java`:
- Around line 31-33: The three saved members in MemberRepositoryTest are created
with MemberFixtureBuilder but no explicit nicknames, which can mask intent and
break future unique constraints; update the three save calls to supply distinct
nicknames via MemberFixtureBuilder.nickname(...) (e.g., "ranker1", "ranker2",
"ranker3"), ensuring the second saved instance assigned to Member ranker2 also
receives a unique nickname so the test behavior and future uniqueness
constraints remain clear and robust.
♻️ Duplicate comments (3)
api/src/test/java/com/samhap/kokomen/interview/service/InterviewViewCountServiceTest.java (3)
88-89: 동일 이슈 반복: 기본 빌더로 동일 데이터 저장Line 50-51 코멘트와 동일한 우려가 적용됩니다(기본값 중복에 따른 제약/로직 충돌 가능성).
127-128: 동일 이슈 반복: 기본 빌더로 동일 데이터 저장Line 50-51 코멘트와 동일한 우려가 적용됩니다(기본값 중복에 따른 제약/로직 충돌 가능성).
211-212: 동일 이슈 반복: 기본 빌더로 동일 데이터 저장Line 50-51 코멘트와 동일한 우려가 적용됩니다(기본값 중복에 따른 제약/로직 충돌 가능성).
| public abstract class AwsConstant { | ||
|
|
||
| public static final String CLOUD_FRONT_DOMAIN_URL = "https://dhtg8wzvkbfxr.cloudfront.net/"; | ||
|
|
||
| private AwsConstant() { | ||
| } |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Search for all AwsConstant.java files in the repository
echo "=== Searching for AwsConstant.java files ==="
fd -t f "AwsConstant.java"Repository: samhap-soft/kokomen-backend
Length of output: 258
🏁 Script executed:
#!/bin/bash
# Get file contents of all AwsConstant files found
echo "=== Contents of AwsConstant.java files ==="
for file in $(fd -t f "AwsConstant.java"); do
echo "File: $file"
echo "---"
cat -n "$file"
echo ""
doneRepository: samhap-soft/kokomen-backend
Length of output: 780
🏁 Script executed:
#!/bin/bash
# Verify the repository structure to understand modules
echo "=== Repository structure ==="
git ls-files | head -30Repository: samhap-soft/kokomen-backend
Length of output: 1266
🏁 Script executed:
#!/bin/bash
# Search for imports of AwsConstant to understand usage
echo "=== Imports of AwsConstant ==="
rg "import.*AwsConstant" --type java
echo ""
echo "=== Direct usage of AwsConstant (not imports) ==="
rg "AwsConstant\." --type java | head -20
echo ""
echo "=== Check for subclasses of AwsConstant ==="
rg "extends AwsConstant" --type javaRepository: samhap-soft/kokomen-backend
Length of output: 2252
🏁 Script executed:
#!/bin/bash
# Check if common module is a dependency of api module
echo "=== Build configuration files ==="
find . -name "build.gradle" -o -name "pom.xml" | grep -E "(api|common)" | xargs ls -la
echo ""
echo "=== Check api's build.gradle for common dependency ==="
if [ -f "api/build.gradle" ]; then
echo "Looking for common module dependency..."
grep -i "common" api/build.gradle || echo "No common dependency found"
fi
echo ""
echo "=== Check common's build.gradle ==="
if [ -f "common/build.gradle" ]; then
echo "common/build.gradle exists"
head -30 common/build.gradle
fiRepository: samhap-soft/kokomen-backend
Length of output: 1257
abstract와 private 생성자의 조합이 모순입니다.
abstract 클래스는 이미 직접 인스턴스화가 불가능합니다. private 생성자를 추가하면 서브클래싱이 차단되어 abstract의 의미가 사라집니다. 정적 상수만 포함하는 유틸리티 클래스의 경우, Java 표준 패턴은 final class와 private 생성자 조합입니다.
♻️ 권장 수정안
-public abstract class AwsConstant {
+public final class AwsConstant {
public static final String CLOUD_FRONT_DOMAIN_URL = "https://dhtg8wzvkbfxr.cloudfront.net/";
private AwsConstant() {
}
}추가로, common 모듈에도 동일한 AwsConstant 클래스가 존재합니다. api 모듈이 이미 common에 의존하고 있으므로, 중복을 제거하고 common 모듈의 버전을 통합하여 사용하는 것을 권장합니다. 현재 두 버전의 구현이 일치하지 않아 유지보수상 문제가 될 수 있습니다.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| public abstract class AwsConstant { | |
| public static final String CLOUD_FRONT_DOMAIN_URL = "https://dhtg8wzvkbfxr.cloudfront.net/"; | |
| private AwsConstant() { | |
| } | |
| public final class AwsConstant { | |
| public static final String CLOUD_FRONT_DOMAIN_URL = "https://dhtg8wzvkbfxr.cloudfront.net/"; | |
| private AwsConstant() { | |
| } |
🤖 Prompt for AI Agents
In `@api/src/main/java/com/samhap/kokomen/global/constant/AwsConstant.java` around
lines 3 - 8, The AwsConstant class is incorrectly declared abstract while also
having a private constructor; change it to follow the static-utility pattern by
making the class final (class AwsConstant -> final class AwsConstant) and
keeping the private constructor, or better yet remove this duplicate class
entirely and reference the existing AwsConstant in the common module (ensure api
depends on common and uses common.AwsConstant.CLOUD_FRONT_DOMAIN_URL) so there’s
a single source of truth for CLOUD_FRONT_DOMAIN_URL.
| () -> assertThat( | ||
| answerLikeRepository.existsByMemberIdAndAnswerId(member.getId(), answer.getId())).isFalse(), | ||
| () -> assertThat(answerRepository.findById(answer.getId()).get().getLikeCount()).isZero() |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
LGTM! AssertJ 관용적 표현 사용 개선
isEqualTo(0) 대신 isZero()를 사용한 것은 AssertJ의 관용적 표현으로, 테스트 의도가 더 명확하게 전달됩니다. 라인 90의 isEqualTo(1) 체크도 동일하게 isOne()으로 변경하면 일관성이 높아질 수 있습니다.
♻️ 선택적 개선 제안
- () -> assertThat(answerRepository.findById(answer.getId()).get().getLikeCount()).isEqualTo(1)
+ () -> assertThat(answerRepository.findById(answer.getId()).get().getLikeCount()).isOne()🤖 Prompt for AI Agents
In
`@api/src/test/java/com/samhap/kokomen/answer/controller/AnswerControllerTest.java`
around lines 211 - 213, In AnswerControllerTest update the AssertJ assertions
for consistency: replace any uses of isEqualTo(1) with the idiomatic isOne()
(e.g., the assertion around the like-count check in the test method that
currently uses isEqualTo(1)) and keep the existing isZero() used for the zero
check; locate these assertions inside the test method(s) in the
AnswerControllerTest class (the blocks referencing
answerRepository.findById(...).get().getLikeCount() and
answerLikeRepository.existsByMemberIdAndAnswerId(...)) and change the numeric
equality assertions to isOne()/isZero() accordingly.
| questionRepository.save( | ||
| QuestionFixtureBuilder.builder().interview(interview).content("오상훈의 위 부피를 계산해주세요.").build()); | ||
|
|
||
| System.out.println(questionRepository.findTop2ByInterviewIdOrderByIdDesc(interview.getId())); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
사용하지 않는 변수 제거 - LGTM!
question3 변수가 사용되지 않아 할당을 제거한 것은 적절합니다.
단, 388번 라인의 System.out.println 디버그 문도 함께 제거하는 것을 권장합니다. 테스트 코드에 디버그 출력이 남아있으면 테스트 실행 시 불필요한 로그가 출력됩니다.
🧹 디버그 문 제거 제안
questionRepository.save(
QuestionFixtureBuilder.builder().interview(interview).content("오상훈의 위 부피를 계산해주세요.").build());
- System.out.println(questionRepository.findTop2ByInterviewIdOrderByIdDesc(interview.getId()));
-
String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| questionRepository.save( | |
| QuestionFixtureBuilder.builder().interview(interview).content("오상훈의 위 부피를 계산해주세요.").build()); | |
| System.out.println(questionRepository.findTop2ByInterviewIdOrderByIdDesc(interview.getId())); | |
| questionRepository.save( | |
| QuestionFixtureBuilder.builder().interview(interview).content("오상훈의 위 부피를 계산해주세요.").build()); |
🤖 Prompt for AI Agents
In
`@api/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV2Test.java`
around lines 385 - 388, Remove the leftover debug print in the test: delete the
System.out.println(...) call in InterviewControllerV2Test (the call that prints
questionRepository.findTop2ByInterviewIdOrderByIdDesc(interview.getId())).
Ensure no other System.out or similar debug logging remains in the test method
after you removed the unused question3 assignment, so test runs produce no
extraneous console output.
| questionRepository.save( | ||
| QuestionFixtureBuilder.builder().interview(interview).content("오상훈의 위 부피를 계산해주세요.").build()); | ||
|
|
||
| System.out.println(questionRepository.findTop2ByInterviewIdOrderByIdDesc(interview.getId())); |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial
사용하지 않는 변수 제거 - LGTM!
위와 동일하게 사용하지 않는 변수 할당 제거는 적절합니다.
452번 라인의 System.out.println 디버그 문도 함께 정리해주세요.
🧹 디버그 문 제거 제안
questionRepository.save(
QuestionFixtureBuilder.builder().interview(interview).content("오상훈의 위 부피를 계산해주세요.").build());
- System.out.println(questionRepository.findTop2ByInterviewIdOrderByIdDesc(interview.getId()));
-
String interviewProceedStateKey = InterviewFacadeService.createInterviewProceedStateKey(interview.getId(),📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| questionRepository.save( | |
| QuestionFixtureBuilder.builder().interview(interview).content("오상훈의 위 부피를 계산해주세요.").build()); | |
| System.out.println(questionRepository.findTop2ByInterviewIdOrderByIdDesc(interview.getId())); | |
| questionRepository.save( | |
| QuestionFixtureBuilder.builder().interview(interview).content("오상훈의 위 부피를 계산해주세요.").build()); |
🤖 Prompt for AI Agents
In
`@api/src/test/java/com/samhap/kokomen/interview/controller/InterviewControllerV2Test.java`
around lines 449 - 452, Remove the leftover debug print by deleting the
System.out.println(...) call that prints
questionRepository.findTop2ByInterviewIdOrderByIdDesc(interview.getId()); keep
the QuestionFixtureBuilder save as-is; this means removing the
System.out.println statement referencing findTop2ByInterviewIdOrderByIdDesc and
interview.getId() so no debug output remains in InterviewControllerV2Test.
| memberRepository.save(MemberFixtureBuilder.builder().score(100).build()); | ||
| Member ranker2 = memberRepository.save(MemberFixtureBuilder.builder().score(50).build()); | ||
| memberRepository.save(MemberFixtureBuilder.builder().score(0).build()); |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
# 먼저 Member 엔티티 파일 찾기
find . -name "Member.java" -o -name "Member.kt" | grep -v test | head -20Repository: samhap-soft/kokomen-backend
Length of output: 138
🏁 Script executed:
# MemberFixtureBuilder 찾기
find . -name "*MemberFixtureBuilder*" -type f | head -20Repository: samhap-soft/kokomen-backend
Length of output: 157
🏁 Script executed:
# 테스트 파일 확인
find . -path "*member/repository/MemberRepositoryTest.java"Repository: samhap-soft/kokomen-backend
Length of output: 153
🏁 Script executed:
cat -n ./common/src/main/java/com/samhap/kokomen/member/domain/Member.javaRepository: samhap-soft/kokomen-backend
Length of output: 2232
🏁 Script executed:
cat -n ./api/src/test/java/com/samhap/kokomen/global/fixture/member/MemberFixtureBuilder.javaRepository: samhap-soft/kokomen-backend
Length of output: 1284
🏁 Script executed:
cat -n ./api/src/test/java/com/samhap/kokomen/member/repository/MemberRepositoryTest.javaRepository: samhap-soft/kokomen-backend
Length of output: 4095
테스트 의도를 명확하게 하기 위해 고유 닉네임 지정 권장
현재 코드베이스의 Member 엔티티에는 nickname 필드에 unique constraint가 없으므로, 동일한 닉네임으로 저장해도 즉시 문제가 발생하지 않습니다. 그러나 다른 테스트 메서드(line 46-49)와의 일관성을 위해, 그리고 향후 unique constraint 추가 시 대비하기 위해 각 회원의 고유 닉네임을 명시하는 것이 좋습니다.
수정 제안
- memberRepository.save(MemberFixtureBuilder.builder().score(100).build());
- Member ranker2 = memberRepository.save(MemberFixtureBuilder.builder().score(50).build());
- memberRepository.save(MemberFixtureBuilder.builder().score(0).build());
+ memberRepository.save(MemberFixtureBuilder.builder().nickname("100점 회원").score(100).build());
+ Member ranker2 = memberRepository.save(MemberFixtureBuilder.builder().nickname("50점 회원").score(50).build());
+ memberRepository.save(MemberFixtureBuilder.builder().nickname("0점 회원").score(0).build());🤖 Prompt for AI Agents
In
`@api/src/test/java/com/samhap/kokomen/member/repository/MemberRepositoryTest.java`
around lines 31 - 33, The three saved members in MemberRepositoryTest are
created with MemberFixtureBuilder but no explicit nicknames, which can mask
intent and break future unique constraints; update the three save calls to
supply distinct nicknames via MemberFixtureBuilder.nickname(...) (e.g.,
"ranker1", "ranker2", "ranker3"), ensuring the second saved instance assigned to
Member ranker2 also receives a unique nickname so the test behavior and future
uniqueness constraints remain clear and robust.
closed #323
작업 내용
스크린샷
참고 사항