Skip to content

Develop#264

Merged
gisu1102 merged 72 commits intomainfrom
develop
Oct 7, 2025
Merged

Develop#264
gisu1102 merged 72 commits intomainfrom
develop

Conversation

@gisu1102
Copy link
Contributor

@gisu1102 gisu1102 commented Oct 7, 2025

#️⃣ 연관된 이슈

#263
#242

Summary by CodeRabbit

  • 신규 기능

    • 게시글 목록/상세에 투표 정보가 포함되어 표시됩니다(해당 카테고리일 경우).
    • 인기글 상위 3개 및 페이징 인기글 조회 품질 개선.
    • 댓글/대댓글 알림 및 소유자 검증 강화.
  • 리팩터링

    • 게시글·댓글·대댓글·투표 기능을 명령/조회로 분리하여 응답 구조를 일관화했습니다.
    • 수정/삭제 등 변경 API는 빈 페이로드(Void)로 응답합니다.
    • 게시글 아이템/페이지 응답 DTO 구조를 정비했습니다.
  • 문서

    • README에서 “전체 아키텍처” 섹션 제거.
  • 테스트

    • 게시글, 댓글/대댓글, 인기글, 투표, 스케줄러 등 단위 테스트 대폭 추가.

gisu1102 added 30 commits July 8, 2025 23:49
- PostDetailResponseDTO, PollInfoResponseDTO를 포함하는 PostPageItemResponseDTO 래퍼 도입
- 목록/상세/베스트 등 모든 게시글 응답을 래퍼 DTO(List<PostPageItemResponseDTO> 등)로 일원화
- 중복 DTO 변환 로직 toPageItemDTO로 통합, Object 반환/instanceof 분기 제거
- 이전 postDetailResponse 변경 전파 사항
- PostService의 이미지, 조회수, 베스트, 투표 등 부가 기능/서브 로직을 SeperatedPostService로 분리
- PostService는 핵심 비즈니스 흐름/응답 조립에만 집중하도록 응집도(cohesion) 강화
- 부가 기능은 별도 서비스로 위임하여 결합도(coupling) 낮춤
- 테스트 코드도 DI 구조에 맞게 리팩토링
- post, comment, reply 의 user 정보 mapping
- 댓글/대댓글 추가/삭제 시 댓글 수 및 BestScore 반영 순서 정비
- 조회 로직 내 사용자 정보 매핑, 응답 DTO 생성 등 책임 분리
- 중복 제거 및 성능 고려  유저 정보 조회 방식 적용
- 상위 도메인 Repository 직접 참조 제거 (Comment → Post 등)
- 상위 도메인 쿼리 서비스(PostQueryService 등)에서 유효성 검사 처리
- 의존성 순환 문제 발생 → Query/Command 분리로 해결
- Post 도메인 내 Scheduler 및 ErrorCode 의존성 정리
- 도메인 계층별로 올바른 ErrorCode 및 예외 처리 방식 적용
- 각 서비스내 redisBestService 호출 Best Domain으로 책임 이동
gisu1102 and others added 20 commits September 20, 2025 17:54
221 Refactor Post 및 하위 도메인 PR 머지
feat : 투표 이벤트 관련 API 비로그인 유저 접근 허용
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 7, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

이 PR은 게시판/댓글/대댓글/투표 전반에 CQRS(명령/조회) 구조로 리팩터링하고, DTO/예외/스케줄러/베스트 포스트/보안 유틸을 재구성했습니다. 다수의 컨트롤러 시그니처가 Void 응답으로 변경되었고, 엔티티 팩토리 메서드 도입, 패키지 경로 정리, 테스트 스위트 대거 추가 및 기존 서비스(단일 Post/Comment/Poll 등) 제거가 포함됩니다.

Changes

Cohort / File(s) Summary
Docs
README.md
“전체 아키텍처” 섹션 및 이미지 제거
Security utils
.../common/security/util/SecurityUtils.java
@slf4j 추가, 익명가드, getCurrentUserIdOrNull, validateOwners 추가
Block service guard
.../domain/block/service/BlockService.java
비인증 시 차단목록 조회 빈 리스트 반환 처리
Notice uses Command
.../board/notice/controller/NoticeController.java
PostService → PostCommandService 의존성 교체
Like/Notification imports
.../like/service/LikeService.java, .../notification/service/NotificationService.java
Reply 관련 패키지 경로 정리(리팩터)
Post Controller CQRS 전환
.../post/controller/PostController.java
PostService → Command/Query 분리, 여러 엔드포인트 응답을 Void/새 DTO로 변경
Best posts service (신규)
.../post/domain/best/BestService.java
Top3 ID 조회, 페이지 조회, 삭제, 점수 적용 로직 추가
Comment CQRS
.../comment/controller/CommentController.java, .../comment/service/CommentCommandService.java, .../comment/service/CommentQueryService.java, .../comment/service/CommentService.java (삭제)
서비스 분리, 컨트롤러 Void 응답화, 댓글 조회/소유권/좋아요 정보 조립, 구 서비스 삭제
Reply CQRS 및 패키지 정리
.../comment/reply/controller/ReplyCommentController.java, .../comment/reply/service/ReplyCommandService.java, .../comment/reply/service/ReplyQueryService.java, .../comment/domain/reply/service/ReplyCommentService.java (삭제), .../comment/reply/...
Reply 서비스 분리, 컨트롤러 Void 응답화, 엔티티/DTO/이벤트/리포지토리 패키지 경로 정리 및 팩토리 메서드 도입
Comment/Reply DTOs 변경
.../comment/dto/response/CommentResponseDTO.java, .../post/dto/UserDto.java (신규), .../post/dto/UserInfo.java (신규), .../post/dto/response/UserDto.java (삭제)
UserDto/UserInfo 도메인 DTO 도입, 메서드 시그니처 변경, 내부 UserInfo 제거, Reply 리스트 처리 조정
Comment/Reply Exceptions (신규)
.../comment/exception/CommentErrorCode.java, .../comment/exception/CommentException.java, .../comment/reply/exception/ReplyErrorCode.java, .../comment/reply/exception/ReplyException.java
표준 에러코드/예외 추가
Comment/Reply Entities/Repo
.../comment/entity/CommentEntity.java, .../comment/repository/CommentRepository.java, .../comment/reply/entity/ReplyCommentEntity.java, .../comment/reply/repository/ReplyCommentRepository.java
생성자 단순화, 정적 팩토리 추가, @repository 추가, 패키지 경로 정리
Poll CQRS 및 도메인 개편
.../poll/controller/PollController.java, .../poll/service/PollCommandService.java, .../poll/service/PollQueryService.java, .../poll/service/PollService.java (삭제), .../poll/entity/PollEntity.java, .../poll/entity/PollVoteEntity.java, .../poll/repository/PollRepository.java, .../poll/exception/* (에러코드/예외 추가, 기존 RuntimeException 삭제)
Command/Query 분리, 엔티티 생성자/팩토리 리팩터, 옵션 카운트 증감 쿼리 추가, 표준화된 예외로 통일
Post 도메인 분리(CQRS)
.../post/service/PostCommandService.java (신규), .../post/service/PostQueryService.java (신규), .../post/service/PostDtoAssembler.java (신규), .../post/service/PostInteractionService.java (신규), .../post/service/PostService.java (삭제)
생성/수정/삭제와 조회/DTO조립/이미지/조회수 증가를 역할별 서비스로 분리
Post 엔티티/예외/익명처리
.../post/entity/PostEntity.java, .../post/entity/PostAnonymous.java, .../post/exception/PostErrorCode.java (신규), .../post/exception/PostException.java (신규), .../post/exception/SchedulerException.java (삭제), .../post/exception/StateUpdateException.java (삭제)
생성자/팩토리 도입, 이미지 리스트 처리 변경, 상태/익명 중복시 표준 예외 사용, 댓글 카운트 감소 추가, 익명번호 API 단순화(ObjectId 기반)
Scheduler 재구성
.../post/schedular/PostsScheduler.java (삭제), .../post/scheduler/PostsScheduler.java (신규), .../post/scheduler/exception/SchedulerErrorCode.java (신규), .../post/scheduler/exception/SchedulerException.java (신규)
패키지 정리, 공통 실행 메서드 도입, 표준 에러코드/예외 채택
Hits 보완
.../hits/service/HitsService.java, .../hits/exception/HitsErrorCode.java (신규), .../hits/exception/HitsException.java (신규)
비인증 사용자 처리 주석/로직 보완, 표준 예외 추가
Report 리팩터
.../report/controller/ReportController.java, .../report/service/ReportService.java, .../report/dto/response/ReportListResponseDto.java, .../report/dto/response/ReportedPostDetailResponseDTO.java
Post/Comment/Reply 조회 경로를 QueryService로 교체, Post 응답을 합성(composition) 구조로 변경
User 서비스 의존성 교체
.../user/service/UserService.java
PostService → PostDtoAssembler 사용으로 변경
Post DTOs 개편
.../post/dto/request/PostCreateRequestDTO.java, .../post/dto/response/PostDetailResponseDTO.java, .../post/dto/response/PostPageItemResponseDTO.java (신규), .../post/dto/response/PostPageResponse.java, .../post/dto/response/PostPollDetailResponseDTO.java, .../post/dto/response/PollInfoResponseDTO.java (신규)
빌더/합성 기반 구조로 전환, Page 아이템에 Poll 포함, 여러 팩토리 시그니처 변경
Misc/Resources
src/main/resources
서브모듈 커밋 포인터 갱신
Tests 추가/수정
src/test/java/... 다수
신규 CQRS/서비스/어셈블러/스케줄러/히츠 테스트 추가, 일부 import 경로 정리

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant PC as PostController
  participant PCS as PostCommandService
  participant PQS as PostQueryService
  participant OA as OwnershipPolicy
  participant PI as PostInteractionService
  participant PR as PostRepository
  Note over PC,PCS: 생성/수정(Delete 포함) = Command 흐름
  U->>PC: createPost(request, images)
  PC->>PCS: createPost(...)
  PCS->>PI: handleImageUpload(images)
  PCS->>PR: save(PostEntity.create(...))
  PR-->>PCS: Post saved
  PCS-->>PC: void
  PC-->>U: 201 Created (Void)

  Note over PC,PQS: 조회 = Query 흐름
  U->>PC: getPostWithDetail(postId)
  PC->>PQS: getPostWithDetail(postId)
  PQS->>PR: findByIdAndNotDeleted
  PR-->>PQS: PostEntity
  PQS->>PI: increaseHits(post, currentUser)
  PQS-->>PC: PostPageItemResponseDTO
  PC-->>U: 200 OK (DTO)
Loading
sequenceDiagram
  autonumber
  actor U as User
  participant PollC as PollController
  participant PollCS as PollCommandService
  participant PollQS as PollQueryService
  participant PoR as PostRepository
  participant PlR as PollRepository
  participant PVR as PollVoteRepository

  Note over PollC,PollCS: 투표 생성 (Command)
  U->>PollC: createPoll(dto)
  PollC->>PollCS: createPoll(dto)
  PollCS->>PoR: save(PostEntity.create(...))
  PollCS->>PlR: save(PollEntity.from(...))
  PlR-->>PollCS: Poll saved
  PollCS-->>PollC: void
  PollC-->>U: 201 Created (Void)

  Note over PollC,PollCS: 투표하기 (Command)
  U->>PollC: votingPoll(postId, selections)
  PollC->>PollCS: votingPoll(...)
  PollCS->>PlR: findByPostId(postId)
  PollCS->>PVR: existsByPollIdAndUserId
  PollCS->>PlR: incOption / validate
  PollCS->>PVR: save(PollVoteEntity.from(...))
  PollCS-->>PollC: void
  PollC-->>U: 201 Created (Void)

  Note over PollC,PollQS: 투표 정보 조회 (Query)
  U->>PollC: getPollInfo(postId)
  PollC->>PollQS: getPollInfo(post, userId)
  PollQS->>PlR: findByPostId
  PollQS->>PVR: countByPollId / findByPollIdAndUserId
  PollQS-->>PollC: PollInfoResponseDTO
  PollC-->>U: 200 OK (DTO)
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested labels

🔨 Refactor, ✅ Test, Priority : High, Status: Pending

Suggested reviewers

  • BHC-Chicken
  • doma17
  • X1n9fU

Poem

(\/)
( •
•) 제가 쿼럭쿼럭 CQRS!
명령은 이쪽, 조회는 저쪽—
당근처럼 가지런히 정렬됐죠.
댓글도 척, 투표도 척,
스케줄러는 딱-딱-딱!
오늘도 코드밭에 바람 솔솔… 🥕

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch develop

📜 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 dfd2154 and aacf077.

📒 Files selected for processing (91)
  • README.md (0 hunks)
  • src/main/java/inu/codin/codin/common/security/util/SecurityUtils.java (3 hunks)
  • src/main/java/inu/codin/codin/domain/block/service/BlockService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/board/notice/controller/NoticeController.java (4 hunks)
  • src/main/java/inu/codin/codin/domain/like/service/LikeService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/notification/service/NotificationService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/controller/PostController.java (5 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/best/BestService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/controller/CommentController.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/domain/reply/service/ReplyCommentService.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/dto/response/CommentResponseDTO.java (3 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/entity/CommentEntity.java (2 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/exception/CommentErrorCode.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/exception/CommentException.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/controller/ReplyCommentController.java (2 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/dto/event/ReplyNotificationEvent.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/dto/request/ReplyAnonnymousUpdateRequestDTO.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/dto/request/ReplyCreateRequestDTO.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/dto/request/ReplyUpdateRequestDTO.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/entity/ReplyCommentEntity.java (2 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/exception/ReplyErrorCode.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/exception/ReplyException.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/repository/ReplyCommentRepository.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/service/ReplyCommandService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/service/ReplyEventListener.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/reply/service/ReplyQueryService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/repository/CommentRepository.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/service/CommentCommandService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/service/CommentQueryService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/comment/service/CommentService.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/hits/exception/HitsErrorCode.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/hits/exception/HitsException.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/hits/service/HitsService.java (2 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/controller/PollController.java (2 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/entity/PollEntity.java (2 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/entity/PollVoteEntity.java (2 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/exception/PollDuplicateVoteException.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/exception/PollErrorCode.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/exception/PollException.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/exception/PollOptionChoiceException.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/exception/PollTimeFailException.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/repository/PollRepository.java (2 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/service/PollCommandService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/service/PollQueryService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/domain/poll/service/PollService.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/post/dto/UserDto.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/dto/UserInfo.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/dto/request/PostCreateRequestDTO.java (2 hunks)
  • src/main/java/inu/codin/codin/domain/post/dto/response/PollInfoResponseDTO.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/dto/response/PostDetailResponseDTO.java (4 hunks)
  • src/main/java/inu/codin/codin/domain/post/dto/response/PostPageItemResponseDTO.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/dto/response/PostPageResponse.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/dto/response/PostPollDetailResponseDTO.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/dto/response/UserDto.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/post/entity/PostAnonymous.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/entity/PostEntity.java (5 hunks)
  • src/main/java/inu/codin/codin/domain/post/exception/PostErrorCode.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/exception/PostException.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/exception/SchedulerException.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/post/exception/StateUpdateException.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/post/schedular/PostsScheduler.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/post/scheduler/PostsScheduler.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/scheduler/exception/SchedulerErrorCode.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/scheduler/exception/SchedulerException.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/security/OwnershipPolicy.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/service/PostCommandService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/service/PostDtoAssembler.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/service/PostInteractionService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/service/PostQueryService.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/post/service/PostService.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/report/controller/ReportController.java (0 hunks)
  • src/main/java/inu/codin/codin/domain/report/dto/response/ReportListResponseDto.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/report/dto/response/ReportedPostDetailResponseDTO.java (1 hunks)
  • src/main/java/inu/codin/codin/domain/report/service/ReportService.java (5 hunks)
  • src/main/java/inu/codin/codin/domain/user/service/UserService.java (6 hunks)
  • src/main/resources (1 hunks)
  • src/test/java/inu/codin/codin/domain/email/service/JoinEmailAuthServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/email/service/PasswordResetEmailServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/PostCommandServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/PostDtoAssemblerTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/PostInteractionServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/PostQueryServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/domain/best/BestServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/domain/comment/CommentCommandServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/domain/comment/CommentQueryServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/domain/comment/reply/ReplyCommandServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/domain/comment/reply/ReplyQueryServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/domain/hits/HitsServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/domain/poll/PollCommandServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/domain/poll/PollQueryServiceTest.java (1 hunks)
  • src/test/java/inu/codin/codin/domain/post/scheduler/PostsSchedulerTest.java (1 hunks)

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.

@gisu1102 gisu1102 merged commit b7ca3bd into main Oct 7, 2025
1 check was pending
@coderabbitai coderabbitai bot added Priority : High 우선순위 상 Status: Pending 보류 중인 이슈 ✅ Test test 관련 🔨 Refactor 코드 리팩토링 labels Oct 7, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Priority : High 우선순위 상 🔨 Refactor 코드 리팩토링 Status: Pending 보류 중인 이슈 ✅ Test test 관련

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant