Skip to content

Conversation

@lsy1307
Copy link
Contributor

@lsy1307 lsy1307 commented Aug 25, 2025

관련 이슈

작업 내용

  • 채팅방 신고 기능 추가
  • 테스트 코드 post, chat 분리

특이 사항

  • 변경사항이 짧으므로 가볍게 보시면 될 것 같습니당 추후 다른 Type추가가 용이하게 변경해놓았습니다.

리뷰 요구사항 (선택)

@lsy1307 lsy1307 self-assigned this Aug 25, 2025
@lsy1307 lsy1307 requested a review from wibaek as a code owner August 25, 2025 14:12
@lsy1307 lsy1307 added the 기능 label Aug 25, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 25, 2025

Walkthrough

  1. TargetType에 CHAT 상수를 추가했습니다.
    • 공개 enum에 CHAT이 새로 포함되었습니다.
  2. ReportService에 CHAT 대상 검증을 추가했습니다.
    • ChatMessageRepository를 의존성으로 주입했고 생성자 시그니처가 확장되었습니다.
    • POST와 CHAT을 스위치로 분기해 존재 여부를 확인하게 변경되었습니다.
  3. ReportServiceTest에 채팅 신고 테스트를 추가했습니다.
    • 채팅방과 채팅메시지 픽스처를 생성하고, 정상 신고, 대상 부재, 중복 신고 케이스를 검증했습니다.
    • 기존 포스트 신고 테스트 그룹 명을 정리하고 대상 타입을 명시했습니다.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested reviewers

  • wibaek
  • whqtker
  • nayonsoso
  • Gyuhyeok99

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • 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
🪧 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.
    • 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.
  • 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 the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

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

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

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

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • 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

Caution

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

⚠️ Outside diff range comments (1)
src/main/java/com/example/solidconnection/report/service/ReportService.java (1)

25-33: 데이터 무결성 예외 매핑 추가 안내

  1. Report 엔티티와 마이그레이션에서 이미 (reporter_id, target_type, target_id)에 대한 유니크 제약이 선언되어 있습니다.
    └ 엔티티: src/main/java/com/example/solidconnection/report/domain/Report.java @table(uniqueConstraints… 라인 19
    └ 마이그레이션: V25__create_report_table.sql constraint uk_report_reporter_id_target_type_target_id 라인 10

  2. 그럼에도 불구하고 동시성 상황에서 동시 삽입 경합이 발생할 수 있으므로,
    reportRepository.save(...) 호출부를 try-catch로 감싸 DataIntegrityViolationException를 처리하고
    CustomException(ErrorCode.ALREADY_REPORTED_BY_CURRENT_USER)로 매핑하는 예외 핸들링을 추가해야 합니다.

  3. 아래와 같이 ReportService#createReport 메서드를 수정해 주세요.

    1. org.springframework.dao.DataIntegrityViolationException 임포트 추가
    2. reportRepository.save(report) 호출부를 try { … } catch (DataIntegrityViolationException e) { … } 블록으로 래핑
    @@ src/main/java/com/example/solidconnection/report/service/ReportService.java
    - import com.example.solidconnection.chat.repository.ChatMessageRepository;
    + import com.example.solidconnection.chat.repository.ChatMessageRepository;
    + import org.springframework.dao.DataIntegrityViolationException;
    @@ public void createReport(long reporterId, ReportRequest request) {
          Report report = new Report(reporterId, request.reportType(), request.targetType(), request.targetId());
    -     reportRepository.save(report);
    +     try {
    +         reportRepository.save(report);
    +     } catch (DataIntegrityViolationException e) {
    +         // (reporter_id, target_type, target_id) 유니크 제약 위반 시
    +         throw new CustomException(ErrorCode.ALREADY_REPORTED_BY_CURRENT_USER);
    +     }
🧹 Nitpick comments (4)
src/main/java/com/example/solidconnection/report/domain/TargetType.java (1)

6-6: 2) 명칭 정합성 점검: CHAT은 '채팅방'인지 '채팅메시지'인지 확인이 필요합니다.
PR 제목과 이슈는 ‘채팅방 신고’로 되어 있으나, 실제 로직/테스트는 ChatMessage 기준으로 동작합니다.
혼선을 줄이려면 TargetType을 CHAT_MESSAGE로 명시하거나, JavaDoc에 "CHAT은 ChatMessage를 의미"라고 문서화하는 것이 좋습니다.

필요 시 아래 최소 변경안을 제안드립니다.

-    POST,
-    CHAT
+    POST,
+    CHAT_MESSAGE

서비스/테스트의 참조도 동일하게 변경하면 됩니다.

src/test/java/com/example/solidconnection/report/service/ReportServiceTest.java (2)

60-60: 2) 필드 네이밍 구체화 제안: chatMessage → reportTargetChatMessage.
테스트 가독성을 위해 ‘신고 타겟’임을 드러내면 의도가 더 분명해집니다.
테스트에서 유사 엔티티가 늘어날 때 혼동을 줄여줍니다.


67-69: 3) 불리언 파라미터의 의미를 드러내기: 불리언 트랩 회피.
chatRoomFixture.채팅방(false)에서 false의 의미가 즉시 파악되지 않습니다.
메서드 네이밍을 채팅방_비공개(false)처럼 바꾸거나, 빌더/정적 팩터리로 의도를 노출하는 것을 권합니다.

src/main/java/com/example/solidconnection/report/service/ReportService.java (1)

41-46: 2) 스위치 식 기반 존재 검증: 현재 스코프에서는 가장 단순하고 명확합니다.
열거형 기반이라 새로운 타입이 추가되면 컴파일 타임에 누락을 잡을 수 있습니다.
다만 타입이 늘어날 가능성이 높다면 전략 패턴(타입→existence 체크 함수 매핑)으로의 리팩터도 고려할 수 있습니다.

예시(개념 스케치):

// Map<TargetType, LongPredicate> existences = Map.of(
//   POST, postRepository::existsById,
//   CHAT, chatMessageRepository::existsById
// );
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 3f8c493 and 08a2a28.

📒 Files selected for processing (3)
  • src/main/java/com/example/solidconnection/report/domain/TargetType.java (1 hunks)
  • src/main/java/com/example/solidconnection/report/service/ReportService.java (3 hunks)
  • src/test/java/com/example/solidconnection/report/service/ReportServiceTest.java (3 hunks)
⏰ 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/main/java/com/example/solidconnection/report/domain/TargetType.java (1)

5-7: 1) CHAT 타겟 타입 추가: 구현 방향과 호환성 모두 양호합니다.
컴파일 타임에 스위치 식이 열거형을 모두 소진하도록 강제되므로 추후 누락 리스크가 낮습니다.
현재 변경으로 기존 POST 흐름과 충돌이 없고, 서비스/테스트와도 일관되게 동작합니다.

src/test/java/com/example/solidconnection/report/service/ReportServiceTest.java (2)

6-9: 1) 채팅 픽스처 주입: 테스트 구성 명확하고 가독성 좋습니다.
ChatRoomFixture와 ChatMessageFixture로 도메인 맥락을 분리해, POST/CHAT 테스트를 독립적으로 유지한 점이 좋습니다.
중복 설정을 최소화하고 시나리오 확장이 용이합니다.

Also applies to: 52-57


113-153: 4) 채팅 신고 시나리오 3종 테스트: 커버리지와 기대 동작 모두 적합합니다.
정상, 대상 부재, 중복 신고 예외까지 핵심 경로가 잘 검증되어 있습니다.
중복 신고 케이스는 저장소에 중복 레코드가 남지 않음을 추가로 검증하면 더 견고합니다.

아래 보강 테스트를 고려해 주세요.

  • 목적: 중복 신고 예외 후에도 동일 키 조합의 레코드 수가 1건임을 검증.

가능하다면 ReportRepository에 카운트 쿼리가 있다 가정하고 예시를 첨부합니다.

@Test
void 이미_신고한_경우_예외_발생하며_중복_저장은_없다() {
    // given
    reportFixture.신고(siteUser.getId(), TargetType.CHAT, chatMessage.getId());
    ReportRequest request = new ReportRequest(ReportType.INSULT, TargetType.CHAT, chatMessage.getId());

    // when & then
    assertThatCode(() -> reportService.createReport(siteUser.getId(), request))
            .isInstanceOf(CustomException.class)
            .hasMessageContaining(ErrorCode.ALREADY_REPORTED_BY_CURRENT_USER.getMessage());

    // then
    // 예: countBy... API가 없으면, findBy... 로 목록 크기 검증으로 대체
    // assertThat(reportRepository.countByReporterIdAndTargetTypeAndTargetId(...)).isEqualTo(1);
}

또한 공통 검증으로 “신고자 미존재” 케이스를 한 번 추가하면 방어력이 올라갑니다.

@Nested
class 공통_검증 {
    @Test
    void 신고자가_존재하지_않으면_예외가_발생한다() {
        long notExistingUserId = 999_999L;
        ReportRequest request = new ReportRequest(ReportType.INSULT, TargetType.CHAT, chatMessage.getId());
        assertThatCode(() -> reportService.createReport(notExistingUserId, request))
                .isInstanceOf(CustomException.class)
                .hasMessageContaining(ErrorCode.USER_NOT_FOUND.getMessage());
    }
}
src/main/java/com/example/solidconnection/report/service/ReportService.java (2)

23-24: 1) 의존성 주입 확장: ChatMessageRepository 추가는 타당합니다.
타겟 존재 여부 검증 경로에 필요한 최소 의존성만 주입되어 SRP 관점에서도 깔끔합니다.
테스트에서 실제로 해당 경로가 실행되므로 배선도 정상으로 보입니다.


41-46: 4) 소프트 삭제/차단 정책과 존재 검증의 일치성 확인.
Post/ChatMessage가 소프트 삭제되거나 차단 상태일 때도 existsById가 true를 반환한다면, 신고가 허용되는지가 정책적으로 모호할 수 있습니다.
필요 시 existsByIdAndDeletedFalse 같은 조건형 존재 검증으로 맞춰 주세요.

Copy link
Member

@whqtker whqtker left a comment

Choose a reason for hiding this comment

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

확인했습니다 !

@whqtker whqtker self-requested a review August 25, 2025 18:02
@lsy1307 lsy1307 merged commit 2675fa3 into solid-connection:develop Aug 27, 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: 채팅방 신고 기능 구현

3 participants