Conversation
Walkthrough변경 사항은 신고(Report) 처리 로직의 구조적 리팩토링과 신고 대상 확장에 집중되어 있다, 풀리퀘스트에서는 신고 프로세서(ReportProcessor) 패턴 도입, 신고 타입의 다양화, 서비스 및 도메인 수정이 이루어졌어! 또한 시음노트(TastingNote) 관련 서비스와 코멘트 서비스가 tastingnote 패키지로 이동 및 생성됐고, 일상생활(DailyLife) 코멘트 서비스도 신설됐지. 신고 엔티티와 요청 객체는 신고 대상 필드가 사용자에서 컨텐츠 ID로 변경됐어. 에러 코드도 추가 및 수정됐지, 바보야! Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant ReportService
participant ReportProcessorFactory
participant ReportProcessor
participant DomainService
Client->>ReportService: createReport(reporterId, ReportCreateRequest)
ReportService->>ReportProcessorFactory: getProcessor(request.type)
ReportProcessorFactory->>ReportService: ReportProcessor
ReportService->>ReportProcessor: process(request)
ReportProcessor->>DomainService: findById(request.reportedContentId)
DomainService-->>ReportProcessor: (존재 확인/예외)
ReportProcessor-->>ReportService: (처리 완료)
ReportService->>ReportRepository: save(Report)
ReportRepository-->>ReportService: (저장 완료)
ReportService-->>Client: (응답)
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
✨ Finishing Touches
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Nitpick comments (7)
src/main/java/com/juu/juulabel/tastingnote/service/TastingNoteCommentService.java (1)
10-19: 서비스 구현은 좋지만 어노테이션 하나 빠졌다, 이 바보야!이 서비스 구현은 깔끔하고 표준을 잘 따르고 있어! 근데 내가 하나 발견했어! DailyLifeCommentService에는 @transactional(readOnly = true) 어노테이션이 있는데 여기는 빠졌잖아! 일관성을 위해 추가해! 안 그러면 내가 널 완전 불쌍하게 여길 거야!
@Service @RequiredArgsConstructor +@Transactional(readOnly = true) public class TastingNoteCommentService { private final TastingNoteCommentJpaRepository tastingNoteCommentJpaRepository; public TastingNoteComment findById(long id) { return tastingNoteCommentJpaRepository.findById(id) .orElseThrow(() -> new BaseException(ErrorCode.TASTING_NOTE_COMMENT_NOT_FOUND)); } }src/main/java/com/juu/juulabel/report/processor/DailyLifeReportProcessor.java (1)
9-24: 프로세서 구현이 깔끔하지만 너무 최소한의 기능만 있다!이 프로세서 구현은 간결하고 다른 프로세서들과 패턴이 일치해서 좋아! 하지만 지금은 그냥 존재 여부만 확인하고 있어! 진짜 멋진 프로세서를 원한다면 추가 처리 로직도 고려해봐! 예를 들어 신고된 컨텐츠에 플래그 표시나 관리자 알림 같은 것 말이야! 난 기능 확장성 생각 안 하는 바보들이 불쌍해!
향후 확장을 위해 추가 로직을 고려해보는 건 어때?:
@Override public void process(ReportCreateRequest request) { dailyLifeService.findById(request.reportedContentId()); + // 추가 처리 로직 예시: + // 1. 신고된 컨텐츠에 플래그 설정 + // 2. 관리자에게 알림 전송 + // 3. 신고 횟수 집계 등 }src/main/java/com/juu/juulabel/dailylife/service/DailyLifeCommentService.java (1)
17-20: 에러 메시지 향상 가능성을 놓치지 마! 바보 같은 짓 하지 말라고!findById 메소드에서 더 명확한 에러 메시지를 제공하면 어떨까? 어떤 ID를 찾지 못했는지 디버깅에 도움이 될 거야.
public DailyLifeComment findById(long id) { return dailyLifeCommentJpaRepository.findById(id) - .orElseThrow(() -> new BaseException(ErrorCode.DAILY_LIFE_COMMENT_NOT_FOUND)); + .orElseThrow(() -> new BaseException(ErrorCode.DAILY_LIFE_COMMENT_NOT_FOUND, "ID: " + id)); }src/main/java/com/juu/juulabel/common/exception/code/ErrorCode.java (1)
77-108: 일관성 있는 HTTP 상태 코드 사용! 하지만 개선 여지가 있어, 바보같이 놓치지 마!NOT_FOUND 상태를 일부 에러 코드에만 적용했어. TASTING_NOTE_NOT_FOUND, COMMENT_NOT_FOUND 같은 다른 "찾을 수 없음" 에러도 동일하게 NOT_FOUND로 변경하는 것이 더 일관성 있을 거야!
COMMENT_NOT_FOUND(HttpStatus.BAD_REQUEST, "댓글을 찾을 수 없습니다."), ... DAILY_LIFE_NOT_FOUND(HttpStatus.NOT_FOUND, "일상생활 게시글을 찾을 수 없습니다."), ... -TASTING_NOTE_NOT_FOUND(HttpStatus.BAD_REQUEST, "시음노트 게시글을 찾을 수 없습니다."), +TASTING_NOTE_NOT_FOUND(HttpStatus.NOT_FOUND, "시음노트 게시글을 찾을 수 없습니다."),src/main/java/com/juu/juulabel/report/ReportService.java (1)
21-24: 좋은 구조 변경이다! 이젠 바보같은 하드코딩 없이 확장 가능하게 됐군!팩토리에서 프로세서를 가져와서 처리하도록 변경한 것은 아주 현명한 선택이야! 이제 신고 유형이 추가돼도 이 서비스 코드는 수정할 필요가 없어.
근데 한 가지 더 개선할 점이 있어:
Member reporter = MemberService.findById(reporterId); +// 여기서 중복 신고 체크 로직을 추가하는 것이 좋겠다! +// reportRepository.findByReporterIdAndReportedContentIdAndType(reporterId, request.reportedContentId(), request.type()) ReportProcessor processor = reportProcessorFactory.getProcessor(request.type()); processor.process(request);동일 사용자가 같은 콘텐츠를 여러 번 신고하는 것을 막는 바보 방지 로직이 필요해!
src/main/java/com/juu/juulabel/tastingnote/service/TastingNoteService.java (2)
71-81: 주석 방치는 용납 못해! Clean 코드, fool!
SliceResponseFactory사용 흔적이 주석으로 남아있다네. 주석은 기술 부채를 키우는 법!
필요 없다면 과감히 제거하고, 필요하다면 실제 로직으로 복원하도록 하게. I pity the fool who leaves dead code!
149-194: 중복 검증 메서드, 단순화가 필요하다네!
getValidColorOrElseThrow,getValidScentsOrElseThrow,getValidSensoryLevelsOrElseThrow,getValidFlavorLevelsOrElseThrow
네 개가 거의 동일한 패턴을 반복 중. 제네릭 + 함수형으로 공통화하면 유지보수성이 확 올라간다네.I pity the fool who copies code!
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (18)
src/main/java/com/juu/juulabel/alcohol/controller/TastingNoteController.java(1 hunks)src/main/java/com/juu/juulabel/alcohol/service/TastingNoteService.java(0 hunks)src/main/java/com/juu/juulabel/common/exception/code/ErrorCode.java(2 hunks)src/main/java/com/juu/juulabel/dailylife/service/DailyLifeCommentService.java(1 hunks)src/main/java/com/juu/juulabel/dailylife/service/DailyLifeService.java(3 hunks)src/main/java/com/juu/juulabel/report/Report.java(1 hunks)src/main/java/com/juu/juulabel/report/ReportCreateRequest.java(1 hunks)src/main/java/com/juu/juulabel/report/ReportService.java(2 hunks)src/main/java/com/juu/juulabel/report/ReportType.java(1 hunks)src/main/java/com/juu/juulabel/report/processor/DailyLifeCommentReportProcessor.java(1 hunks)src/main/java/com/juu/juulabel/report/processor/DailyLifeReportProcessor.java(1 hunks)src/main/java/com/juu/juulabel/report/processor/MemberReportProcessor.java(1 hunks)src/main/java/com/juu/juulabel/report/processor/ReportProcessor.java(1 hunks)src/main/java/com/juu/juulabel/report/processor/ReportProcessorFactory.java(1 hunks)src/main/java/com/juu/juulabel/report/processor/TastingNoteCommentReportProcessor.java(1 hunks)src/main/java/com/juu/juulabel/report/processor/TastingNoteReportProcessor.java(1 hunks)src/main/java/com/juu/juulabel/tastingnote/service/TastingNoteCommentService.java(1 hunks)src/main/java/com/juu/juulabel/tastingnote/service/TastingNoteService.java(1 hunks)
💤 Files with no reviewable changes (1)
- src/main/java/com/juu/juulabel/alcohol/service/TastingNoteService.java
🧰 Additional context used
🧬 Code Graph Analysis (6)
src/main/java/com/juu/juulabel/tastingnote/service/TastingNoteCommentService.java (1)
src/main/java/com/juu/juulabel/dailylife/service/DailyLifeCommentService.java (1)
Service(11-21)
src/main/java/com/juu/juulabel/dailylife/service/DailyLifeCommentService.java (2)
src/main/java/com/juu/juulabel/tastingnote/service/TastingNoteCommentService.java (1)
Service(10-19)src/main/java/com/juu/juulabel/dailylife/service/DailyLifeService.java (1)
Service(36-367)
src/main/java/com/juu/juulabel/report/processor/DailyLifeReportProcessor.java (5)
src/main/java/com/juu/juulabel/report/processor/DailyLifeCommentReportProcessor.java (1)
Component(9-24)src/main/java/com/juu/juulabel/report/processor/MemberReportProcessor.java (1)
Component(9-24)src/main/java/com/juu/juulabel/report/processor/ReportProcessorFactory.java (1)
Component(13-29)src/main/java/com/juu/juulabel/report/processor/TastingNoteCommentReportProcessor.java (1)
Component(9-24)src/main/java/com/juu/juulabel/report/processor/TastingNoteReportProcessor.java (1)
Component(9-24)
src/main/java/com/juu/juulabel/report/processor/ReportProcessorFactory.java (5)
src/main/java/com/juu/juulabel/report/processor/DailyLifeCommentReportProcessor.java (1)
Component(9-24)src/main/java/com/juu/juulabel/report/processor/DailyLifeReportProcessor.java (1)
Component(9-24)src/main/java/com/juu/juulabel/report/processor/MemberReportProcessor.java (1)
Component(9-24)src/main/java/com/juu/juulabel/report/processor/TastingNoteCommentReportProcessor.java (1)
Component(9-24)src/main/java/com/juu/juulabel/report/processor/TastingNoteReportProcessor.java (1)
Component(9-24)
src/main/java/com/juu/juulabel/report/processor/TastingNoteReportProcessor.java (5)
src/main/java/com/juu/juulabel/report/processor/DailyLifeCommentReportProcessor.java (1)
Component(9-24)src/main/java/com/juu/juulabel/report/processor/DailyLifeReportProcessor.java (1)
Component(9-24)src/main/java/com/juu/juulabel/report/processor/MemberReportProcessor.java (1)
Component(9-24)src/main/java/com/juu/juulabel/report/processor/ReportProcessorFactory.java (1)
Component(13-29)src/main/java/com/juu/juulabel/report/processor/TastingNoteCommentReportProcessor.java (1)
Component(9-24)
src/main/java/com/juu/juulabel/tastingnote/service/TastingNoteService.java (4)
src/main/java/com/juu/juulabel/common/exception/InvalidParamException.java (1)
InvalidParamException(6-23)src/main/java/com/juu/juulabel/dailylife/service/DailyLifeCommentService.java (1)
Service(11-21)src/main/java/com/juu/juulabel/tastingnote/service/TastingNoteCommentService.java (1)
Service(10-19)src/main/java/com/juu/juulabel/dailylife/service/DailyLifeService.java (1)
Service(36-367)
🔇 Additional comments (16)
src/main/java/com/juu/juulabel/alcohol/controller/TastingNoteController.java (1)
8-8: 임포트 변경이 좋아 보이는군!이 임포트 변경은 시음노트 서비스를 알코올 패키지에서 전용 패키지로 옮긴 리팩토링을 반영하고 있어! 이런 구조적 개선은 코드 조직을 명확히 하는데 도움이 되니 이건 좋은 변화야, 이 바보야!
src/main/java/com/juu/juulabel/report/ReportCreateRequest.java (1)
8-10: 신고 대상 필드 이름 변경이 좋아 보이는군!
reportedUserId에서reportedContentId로 필드명 변경과 메시지 수정은 사용자 중심의 신고에서 컨텐츠 중심의 신고로 변경한 리팩토링을 잘 반영하고 있어! 이제 다양한 타입의 컨텐츠를 신고할 수 있게 됐어, 이 바보야!src/main/java/com/juu/juulabel/report/processor/ReportProcessor.java (1)
1-10: 전략 패턴 도입이 현명한 선택이군!이 새로운
ReportProcessor인터페이스는 각 신고 유형별로 다른 구현체를 가질 수 있는 전략 패턴을 도입했어! 이런 설계는 신고 유형별 처리 로직을 모듈화하고 확장성을 높여주니 아주 좋은 접근법이야, 이 바보야!src/main/java/com/juu/juulabel/dailylife/service/DailyLifeService.java (2)
12-14: 와일드카드 임포트가 코드를 더 간결하게 만들었군!개별 도메인 클래스 임포트에서 와일드카드 임포트로 변경한 것은 코드를 더 간결하게 만들어 줬어! JPA 리포지토리 임포트도 잘 추가됐어, 이 바보야!
52-52: 의존성 주입이 잘 이루어졌군!
DailyLifeJpaRepository필드가 추가된 것은 좋아 보여! 이 리포지토리는 아래에서 사용되는findById메서드를 위한 것이니 필요한 추가야, 이 바보야!src/main/java/com/juu/juulabel/report/Report.java (1)
27-28: 이것이 바로 멋진 아키텍처 리팩토링이로다!이봐 이것 좀 봐! ManyToOne 관계에서 단순 ID로 변경한 것은 명쾌한 전략이야! 난 이런 유연한 설계 안 하는 바보들이 불쌍해! 이제 신고 대상이 유저에만 국한되지 않고 어떤 컨텐츠 타입도 처리할 수 있게 됐어. 이렇게 해서 ReportProcessor 패턴의 기반을 마련했다고! 훌륭해!
src/main/java/com/juu/juulabel/report/ReportType.java (1)
7-11: 타입 세분화가 아주 좋아, 바보들이여 배워라!이런 세분화된 타입 설계야말로 진짜 프로가 하는 일이야! USER를 MEMBER로 바꾸고, 일반 COMMENT를 구체적인 코멘트 타입으로 나눈 건 완전 정확한 판단이야! 이렇게 해야 각 신고 타입별로 적절한 프로세서를 연결할 수 있지! 난 도메인 특화 코드 작성 안 하는 바보들이 불쌍하다고!
src/main/java/com/juu/juulabel/report/processor/MemberReportProcessor.java (1)
1-24: 코드가 깔끔하고 설계가 탄탄하군! 이걸 만든 사람 바보 아니야!ReportProcessor 인터페이스를 잘 구현했네! 보고된 회원 ID를 검증하는 간단한 프로세서 구현이 눈에 띄는군. 각 보고 유형별로 분리된 프로세서 패턴을 사용하는 좋은 접근 방식이야.
src/main/java/com/juu/juulabel/dailylife/service/DailyLifeCommentService.java (1)
1-21: 간결한 서비스 클래스 설계! 이런 게 바로 내가 좋아하는 코드야!일상생활 댓글을 ID로 찾는 깔끔한 서비스 메소드를 구현했군.
@Transactional(readOnly = true)로 읽기 전용 트랜잭션 설정한 것도 좋아! 존재하지 않는 댓글에 대한 예외 처리도 적절하게 구현됐어.src/main/java/com/juu/juulabel/report/processor/TastingNoteReportProcessor.java (1)
1-24: 깔끔한 프로세서 구현! 모듈화 좋아, 바보 같은 중복 코드 없어!TastingNoteService를 잘 활용하여 시음노트 ID를 검증하는 프로세서를 잘 구현했군. 동일한 패턴으로 모든 프로세서를 일관되게 구현한 점이 마음에 들어!
src/main/java/com/juu/juulabel/common/exception/code/ErrorCode.java (4)
77-77: HTTP 상태 코드 변경 잘했어! 바보가 아니라 현명한 선택이야!DAILY_LIFE_NOT_FOUND의 HTTP 상태를 BAD_REQUEST에서 NOT_FOUND로 변경한 것 좋아! 404 NOT_FOUND가 리소스를 찾을 수 없을 때 훨씬 더 적절한 상태 코드야.
80-80: 새로운 에러 코드 추가 잘했어! 바보도 이제 에러 원인을 알 수 있겠군!DAILY_LIFE_COMMENT_NOT_FOUND 에러 코드를 추가한 것 좋아! 이 에러 코드는 DailyLifeCommentService의 findById 메소드와 잘 연동되어 있군.
101-103: 시음노트 관련 에러 코드 추가! 에러 처리는 철저해야지, 바보 같은 에러 메시지는 이제 그만!시음노트 작성자 검증과 댓글 조회 실패에 대한 에러 코드를 추가한 것 좋아! 이런 명확한 에러 코드는 클라이언트에게 더 자세한 정보를 제공하지.
105-108: 신고 처리 에러 코드 섹션 추가 좋아! 바보처럼 에러 코드 난잡하게 관리하지 않았군!신고 처리 관련 에러 코드를 별도 섹션으로 구분한 것 좋아! 코드 구성이 잘 정리되었고, REPORT_PROCESSOR_NOT_FOUND는 ReportProcessorFactory와 잘 연동될 거야.
src/main/java/com/juu/juulabel/report/processor/ReportProcessorFactory.java (1)
1-29: 팩토리 패턴을 잘 구현했군! 바보같은 하드코딩은 없다!내가 보기에 이 팩토리 클래스는 딱 좋게 설계됐어! 스프링의 의존성 주입을 활용해 모든 ReportProcessor 구현체를 자동으로 수집하고, 타입에 따라 적절한 프로세서를 찾아주는 구조야. 이런 설계는 새로운 ReportType이 추가될 때마다 팩토리 코드를 수정할 필요 없이 새 프로세서만 만들면 되니까 확장성이 좋아!
특히 아래 부분이 맘에 든다:
private final Map<ReportType, ReportProcessor> processorMap; public ReportProcessorFactory(List<ReportProcessor> reportProcessors) { this.processorMap = reportProcessors.stream() .collect(Collectors.toMap(ReportProcessor::getReportType, Function.identity())); }바보같은 null 체크도 제대로 했군! 프로세서가 없을 때 명확한 예외 처리까지 완벽해!
src/main/java/com/juu/juulabel/report/ReportService.java (1)
28-28: 이제 제대로 콘텐츠 ID를 저장하는군! 좋아!이전에는 특정 유저만 신고할 수 있었는데, 이제 다양한 콘텐츠 타입을 신고할 수 있도록 변경됐군. 바보도 알아볼 수 있는 좋은 개선이야!
.reportedContentId(request.reportedContentId())이 변경으로 유연성이 크게 향상됐어. 나 미스터 T는 이런 확장성 있는 설계를 좋아해!
Suspect IssuesThis pull request was deployed and Sentry observed the following issues:
Did you find this useful? React with a 👍 or 👎 |
작업
신고 유형에 따라 컨텐츠 처리
Summary by CodeRabbit
신규 기능
버그 수정
리팩터링