Skip to content

Conversation

@whqtker
Copy link
Member

@whqtker whqtker commented Jun 14, 2025

관련 이슈

작업 내용

  • InterestedCountyRepositoryInterestedCountryRepository 로 수정하였습니다.
  • 데이터베이스 레벨에서 같은 사용자가 같은 지역 또는 나라에 관심 표시가 가능했던 문제를 해결하였습니다. 복합 unique 제약 조건을 설정하였습니다. 이에 관한 테스트 코드와 sql 문을 작성하였습니다.

특이 사항

리뷰 요구사항 (선택)

  • 코드 컨벤션을 잘 준수하고 있나요?
  • 제가 찾지 못한 다른 개선 사항이 있다면 알려주세요!

@whqtker whqtker self-assigned this Jun 14, 2025
@whqtker whqtker requested review from lsy1307 and wibaek as code owners June 14, 2025 01:43
@coderabbitai
Copy link

coderabbitai bot commented Jun 14, 2025

Walkthrough

  1. 리포지토리 이름 및 참조 일관성 수정

    • InterestedCountyRepository에서 InterestedCountryRepository로 이름이 일괏하게 수정되었습니다.
    • 관련 서비스(EmailSignUpService, SignUpService, OAuthSignUpService)와 테스트(UniversityRecommendServiceTest)에서 모두 참조명, 생성자, 필드명이 일괏하게 변경되었습니다.
  2. 유니크 제약 조건 추가

    • InterestedCountry 엔티티와 InterestedRegion 엔티티에 각각 site_user_id와 country_code(또는 region_code) 조합에 대한 유니크 제약 조건이 추가되었습니다.
    • 해당 제약 조건은 @table 어노테이션의 uniqueConstraints 속성으로 명시되었습니다.
  3. 데이터베이스 마이그레이션 스크립트 추가

    • interested_country와 interested_region 테이블에 복합 유니크 제약 조건을 추가하는 SQL 마이그레이션 스크립트가 작성되었습니다.
  4. 리포지토리 테스트 클래스 추가

    • InterestedCountryRepositoryTest와 InterestedRegionRepositoryTest가 새로 추가되었습니다.
    • 각 테스트 클래스는 동일 사용자-국가(또는 지역) 조합의 중복 저장 시 예외 발생, 다른 사용자 또는 다른 국가(지역) 조합의 정상 저장을 검증합니다.

Suggested reviewers

  • Gyuhyeok99
  • wibaek
  • lsy1307

📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0212b45 and 8f534a7.

📒 Files selected for processing (1)
  • src/main/resources/db/migration/V16__add_unique_constraint_to_intersted.sql (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/main/resources/db/migration/V16__add_unique_constraint_to_intersted.sql
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

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

🔭 Outside diff range comments (1)
src/main/java/com/example/solidconnection/auth/service/SignUpService.java (1)

80-85: 🛠️ Refactor suggestion

중복 관심 국가 입력 시 DataIntegrityViolation 가능성
signUpRequest.interestedCountries()에 중복 값이 들어오면, 유니크 제약 때문에 테스트 단계에서 바로 예외가 터질 수 있습니다. 사전에 중복 제거 → 불필요한 DB 트래픽·롤백을 줄이는 편이 좋습니다.

 List<String> interestedCountryNames = signUpRequest.interestedCountries();
-List<InterestedCountry> interestedCountries = countryRepository.findByKoreanNames(interestedCountryNames).stream()
-        .map(country -> new InterestedCountry(savedSiteUser, country))
-        .toList();
+List<InterestedCountry> interestedCountries = countryRepository
+        .findByKoreanNames(interestedCountryNames.stream().distinct().toList())
+        .stream()
+        .map(country -> new InterestedCountry(savedSiteUser, country))
+        .toList();
🧹 Nitpick comments (5)
src/main/java/com/example/solidconnection/location/country/repository/InterestedCountryRepository.java (1)

11-13: 1) 인터페이스 명칭 교정은 적절하지만, 읽기 전용 힌트 추가 고려
findAllBySiteUser 는 순수 조회 메서드입니다. @Transactional(readOnly = true) 를 리포지토리 레벨(혹은 서비스 레벨)에 명시하면 플러시 우회·성능 이점이 있습니다.

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

1-7: 4) 마이그레이션 스크립트 두 가지 주의점
 1. 파일명 오타: interstedinterested 로 교정하면 가독성이 좋아집니다.
 2. 제약 추가 전 중복 데이터가 존재하면 실패합니다. 사전 정리 쿼리나 ON CONFLICT DO NOTHING 처리 여부를 검토해 주세요.

src/main/java/com/example/solidconnection/auth/service/EmailSignUpService.java (1)

23-26: 6) 생성자 파라미터 순서 유지 권장
DI 프레임워크는 타입으로 주입하지만, 가독성을 위해 지역·국가 리포지토리 쌍의 순서를 맞추면 읽기 쉽습니다. 작은 리팩터지만 고려해 보세요.

src/test/java/com/example/solidconnection/location/region/repository/RegionRepositoryTest.java (1)

44-46: flush 호출로 예외 시점을 명확히
현재 save()만 호출하면 JPA Flush 타이밍에 따라 예외가 테스트 메서드 밖에서 발생할 수도 있습니다. save()flush()를 명시 호출하면 람다 내부에서 예외가 확실히 터져 테스트 신뢰도가 올라갑니다.

-assertThatCode(() -> interestedRegionRepository.save(secondInterest))
+assertThatCode(() -> {
+    interestedRegionRepository.save(secondInterest);
+    interestedRegionRepository.flush();
+})
         .isInstanceOf(DataIntegrityViolationException.class);

세 테스트 모두 동일 패턴이므로 한 번만 수정해도 무방합니다.

Also applies to: 60-65, 80-84

src/test/java/com/example/solidconnection/location/country/repository/CountryRepositoryTest.java (1)

44-46: Region 테스트와 동일, flush 권장
유니크 제약 예외가 메서드 안에서 확실히 발생하도록 flush() 추가를 권장드립니다.

-assertThatCode(() -> interestedCountryRepository.save(secondInterest))
+assertThatCode(() -> {
+    interestedCountryRepository.save(secondInterest);
+    interestedCountryRepository.flush();
+})
         .isInstanceOf(DataIntegrityViolationException.class);

Also applies to: 60-65, 80-84

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ac0f60e and 342216b.

📒 Files selected for processing (10)
  • src/main/java/com/example/solidconnection/auth/service/EmailSignUpService.java (2 hunks)
  • src/main/java/com/example/solidconnection/auth/service/SignUpService.java (3 hunks)
  • src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpService.java (2 hunks)
  • src/main/java/com/example/solidconnection/location/country/domain/InterestedCountry.java (1 hunks)
  • src/main/java/com/example/solidconnection/location/country/repository/InterestedCountryRepository.java (1 hunks)
  • src/main/java/com/example/solidconnection/location/region/domain/InterestedRegion.java (1 hunks)
  • src/main/resources/db/migration/V15__add_unique_constraint_to_intersted.sql (1 hunks)
  • src/test/java/com/example/solidconnection/location/country/repository/CountryRepositoryTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/location/region/repository/RegionRepositoryTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java (4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
src/main/java/com/example/solidconnection/location/region/domain/InterestedRegion.java (1)
src/main/java/com/example/solidconnection/location/country/domain/InterestedCountry.java (1)
  • Getter (15-40)
src/main/java/com/example/solidconnection/location/country/domain/InterestedCountry.java (1)
src/main/java/com/example/solidconnection/location/region/domain/InterestedRegion.java (1)
  • Getter (15-40)
src/test/java/com/example/solidconnection/location/country/repository/CountryRepositoryTest.java (1)
src/test/java/com/example/solidconnection/location/region/repository/RegionRepositoryTest.java (2)
  • TestContainerSpringBootTest (17-86)
  • Nested (29-85)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (7)
src/main/java/com/example/solidconnection/location/region/domain/InterestedRegion.java (1)

18-23: 2) 유니크 제약 컬럼명 검증 필요
region 필드에 @JoinColumn(name = "region_code") 가 없을 경우, 기본 컬럼명은 region_id 로 생성됩니다. 현재 제약은 region_code 를 지정하고 있어 스키마와 불일치 위험이 있습니다. 매핑 컬럼명을 다시 한 번 확인해 주세요.

src/main/java/com/example/solidconnection/location/country/domain/InterestedCountry.java (1)

18-23: 3) Country 도 동일 이슈 가능성
country 필드의 실제 FK 컬럼명이 country_code 가 맞는지 확인이 필요합니다. 매핑이 다르면 마이그레이션 시점에 제약 생성이 실패합니다.

src/main/java/com/example/solidconnection/auth/service/EmailSignUpService.java (1)

6-7: 5) 리포지토리 임포트 교정 완료 확인
InterestedCountryRepository 임포트 정상 반영되었습니다. 추가 이슈 없습니다.

src/main/java/com/example/solidconnection/auth/service/oauth/OAuthSignUpService.java (1)

23-28: 이름 정정 반영 확인 완료
InterestedCountryRepository로의 리네이밍이 컨스트럭터·슈퍼 호출 모두에 정확히 반영되었습니다. 추가 이슈 없습니다.

src/main/java/com/example/solidconnection/auth/service/SignUpService.java (1)

34-45: Repository 명칭 정정 OK
필드·생성자 모두에서 interestedCountryRepository로 일관성 있게 교체되었습니다. 컴파일 오류 우려 없음.

src/test/java/com/example/solidconnection/university/service/UniversityRecommendServiceTest.java (2)

37-38: 리포지토리 타입 교체 정상 반영
InterestedCountryRepository로의 교체로 테스트 컴파일 오류가 사라집니다. 추가 수정 사항 없습니다.


100-111: 테스트 동작 검증만 확인
저장·조회 로직 모두 새 Repository를 사용하므로 동작 자체는 그대로 유지됩니다. 별도 이슈 없습니다.

Also applies to: 118-132

Copy link
Contributor

@Gyuhyeok99 Gyuhyeok99 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 61 to 65
assertThatCode(() -> {
InterestedRegion saved = interestedRegionRepository.save(secondInterest);
assertThat(saved.getId()).isNotNull();
}).doesNotThrowAnyException();
}
Copy link
Contributor

@Gyuhyeok99 Gyuhyeok99 Jun 14, 2025

Choose a reason for hiding this comment

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

성공케이스에 doesNotThrowAnyException로 검증하신 이유가 있나요? 이건 순수 궁금증입니다!
보통 성공 케이스에 저는 저장하고 검증만 assertThat(saved.getId()).isNotNull(); 이런식으로 했었거든요!

Copy link
Member Author

Choose a reason for hiding this comment

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

제가 작성한 테스트 코드가 예외 발생에 주안점을 두고 작성한 코드라 doesNotThrowAnyException 을 명시적으로 작성하였습니다!

Copy link
Collaborator

@nayonsoso nayonsoso left a comment

Choose a reason for hiding this comment

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

image
오타... 저도 몰랐습니다...

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 (5)
src/test/java/com/example/solidconnection/location/region/repository/InterestedRegionRepositoryTest.java (2)

61-64: 테스트 로직을 더 명확하게 개선할 수 있습니다.

현재 assertThatCode() 내부에서 검증을 수행하고 있는데, 이는 예외가 발생하지 않았을 때만 실행되므로 테스트 의도가 명확하지 않을 수 있습니다.

다음과 같이 개선해보세요:

// when & then
-assertThatCode(() -> {
-    InterestedRegion saved = interestedRegionRepository.save(secondInterest);
-    assertThat(saved.getId()).isNotNull();
-}).doesNotThrowAnyException();
+assertThatCode(() -> interestedRegionRepository.save(secondInterest))
+        .doesNotThrowAnyException();
+
+InterestedRegion saved = interestedRegionRepository.save(secondInterest);
+assertThat(saved.getId()).isNotNull();

80-83: 테스트 로직을 더 명확하게 개선할 수 있습니다.

위의 테스트와 동일한 구조적 개선이 필요합니다.

다음과 같이 개선해보세요:

// when & then
-assertThatCode(() -> {
-    InterestedRegion saved = interestedRegionRepository.save(secondInterest);
-    assertThat(saved.getId()).isNotNull();
-}).doesNotThrowAnyException();
+assertThatCode(() -> interestedRegionRepository.save(secondInterest))
+        .doesNotThrowAnyException();
+
+InterestedRegion saved = interestedRegionRepository.save(secondInterest);
+assertThat(saved.getId()).isNotNull();
src/test/java/com/example/solidconnection/location/country/repository/InterestedCountryRepositoryTest.java (3)

61-64: 테스트 로직 개선이 필요합니다.

InterestedRegionRepositoryTest와 동일한 개선점이 적용됩니다.

다음과 같이 개선해보세요:

// when & then
-assertThatCode(() -> {
-    InterestedCountry saved = interestedCountryRepository.save(secondInterest);
-    assertThat(saved.getId()).isNotNull();
-}).doesNotThrowAnyException();
+assertThatCode(() -> interestedCountryRepository.save(secondInterest))
+        .doesNotThrowAnyException();
+
+InterestedCountry saved = interestedCountryRepository.save(secondInterest);
+assertThat(saved.getId()).isNotNull();

80-83: 테스트 로직 개선이 필요합니다.

위의 테스트와 동일한 구조적 개선이 필요합니다.

다음과 같이 개선해보세요:

// when & then
-assertThatCode(() -> {
-    InterestedCountry saved = interestedCountryRepository.save(secondInterest);
-    assertThat(saved.getId()).isNotNull();
-}).doesNotThrowAnyException();
+assertThatCode(() -> interestedCountryRepository.save(secondInterest))
+        .doesNotThrowAnyException();
+
+InterestedCountry saved = interestedCountryRepository.save(secondInterest);
+assertThat(saved.getId()).isNotNull();

1-87: 테스트 코드 중복 제거를 고려해보세요.

두 테스트 클래스가 거의 동일한 구조를 가지고 있어 향후 유지보수 시 중복 수정이 발생할 수 있습니다.

다음과 같은 방법으로 중복을 줄일 수 있습니다:

1. 공통 테스트 베이스 클래스 생성
2. 제네릭을 활용한 추상 테스트 클래스 구현
3. 테스트 유틸리티 메소드 분리

향후 비슷한 엔티티가 추가될 때 재사용 가능한 구조를 고려해보세요.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 342216b and 4060e54.

📒 Files selected for processing (2)
  • src/test/java/com/example/solidconnection/location/country/repository/InterestedCountryRepositoryTest.java (1 hunks)
  • src/test/java/com/example/solidconnection/location/region/repository/InterestedRegionRepositoryTest.java (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: build
🔇 Additional comments (2)
src/test/java/com/example/solidconnection/location/region/repository/InterestedRegionRepositoryTest.java (1)

1-87: 잘 구성된 테스트 클래스입니다.

복합 유니크 제약 조건을 체계적으로 테스트하는 구조가 잘 설계되어 있습니다. 네스티드 클래스를 사용한 테스트 그룹핑과 한국어 메소드명으로 가독성을 높인 점이 좋습니다.

1. 테스트 시나리오가 완전함: 동일 사용자+동일 지역, 다른 사용자+동일 지역, 동일 사용자+다른 지역
2. Spring Boot 테스트 설정이 적절함
3. 픽스쳐 사용으로 테스트 데이터 생성이 체계적임
src/test/java/com/example/solidconnection/location/country/repository/InterestedCountryRepositoryTest.java (1)

1-87: 일관성 있는 테스트 구현이 잘 되어 있습니다.

InterestedRegionRepositoryTest와 동일한 패턴으로 구현되어 프로젝트 전반에 걸친 일관성이 유지되고 있습니다. 복합 유니크 제약 조건 테스트가 체계적으로 구성되어 있습니다.

1. 지역 테스트와 동일한 구조로 일관성 확보
2. 국가 도메인에 특화된 픽스쳐 사용
3. 모든 제약 조건 시나리오 커버

@Gyuhyeok99
Copy link
Contributor

제가 놓친 부분들 잘 확인해주셔서 감사합니다 영서님 ㅎㅎ

Copy link
Collaborator

@nayonsoso nayonsoso left a comment

Choose a reason for hiding this comment

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

approve 합니다 🤗

InterestedCountryRepositoryTest 클래스와 InterestedRegionRepositoryTest클래스의 assert문에 대해서 이 코멘트#338 (comment)
에 대한 내용 적용해주시면 좋을 것 같아요!

그 후에 머지하시면 됩니다~

@whqtker whqtker merged commit e086e8c into solid-connection:develop Jun 24, 2025
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor: Location 도메인 리팩터링

3 participants