Skip to content

Conversation

@stoneTiger0912
Copy link
Member

@stoneTiger0912 stoneTiger0912 commented Aug 12, 2025

📝 변경 내용


✅ 체크리스트

  • 코드가 정상적으로 동작함
  • 테스트 코드 통과함
  • 문서(README 등)를 최신화함
  • 코드 스타일 가이드 준수

💬 기타 참고 사항

Summary by CodeRabbit

  • 신규 기능
    • 그룹 상세 조회 API 추가: 그룹 ID로 상세 정보를 확인할 수 있으며, 본인이 소속된 그룹만 조회 가능합니다.
  • 변경 사항
    • 삭제 방식이 소프트 삭제로 전환되어 삭제된 그룹/그룹원은 목록과 상세에서 자동 제외됩니다.
  • 오류 처리
    • 삭제된 그룹 또는 미가입 상태로 조회할 때 적절한 오류 응답을 반환합니다.
  • 테스트
    • 그룹 생성 및 상세 조회의 성공/실패 경로를 확대한 단위 테스트 추가되었습니다.

@stoneTiger0912 stoneTiger0912 self-assigned this Aug 12, 2025
@coderabbitai
Copy link

coderabbitai bot commented Aug 12, 2025

Walkthrough

그룹 상세 조회 GET 엔드포인트 추가, Group/GroupMember 엔티티에 소프트 삭제 도입(@SQLDelete/@SQLRestriction, deletedAt), 레포지토리 조회 메서드가 soft-delete를 반영하도록 변경, 서비스에 사용자/그룹/멤버십 검증 및 상세조회 로직·테스트 추가, GroupDetailResponse DTO 도입.

Changes

Cohort / File(s) Change Summary
Controller: 그룹 상세 조회 API
src/main/java/project/flipnote/group/controller/GroupController.java
GET /v1/groups/{groupId} 엔드포인트 추가; 인증 주체와 path 변수 수신, groupService.findGroupDetail 위임, 200과 GroupDetailResponse 반환.
Service: 검증·상세 조회 및 이름 변경
src/main/java/project/flipnote/group/service/GroupService.java
findUser → validateUser로 이름 변경. validateGroupInUser, validateGroup, findGroupDetail, deleteGroup 추가. 생성 흐름이 validateUser 반환값 사용으로 조정됨. GroupJoinErrorCode 연계 로직 추가.
Entity: 소프트 삭제 도입
src/main/java/project/flipnote/group/entity/Group.java, src/main/java/project/flipnote/group/entity/GroupMember.java
deletedAt 필드(Group), @SQLDelete@SQLRestriction 추가로 소프트 삭제 적용(삭제 시 deleted_at 업데이트, 기본 조회에서 제외).
Repository: soft-delete 반영 조회 변경
src/main/java/project/flipnote/group/repository/GroupRepository.java
기존 findById 제거/대체: findByIdAndDeletedAtIsNull(Long) 추가(포괄적 조회는 삭제된 행 제외).
Model/DTO: 상세 응답
src/main/java/project/flipnote/group/model/GroupDetailResponse.java
GroupDetailResponse 레코드 추가 및 Group → DTO 변환용 static from(Group) 제공.
Tests: 서비스 시나리오 확장
src/test/java/project/flipnote/group/service/GroupServiceTest.java
그룹 생성 성공/실패(음수/초과), 상세 조회 성공/실패(미가입/삭제됨) 테스트 추가. AuthPrinciple 생성자 시그니처 변경 반영 및 목 설정 확장.

Sequence Diagram(s)

sequenceDiagram
  actor User
  participant Controller as GroupController
  participant Service as GroupService
  participant URepo as UserProfileRepository
  participant GRepo as GroupRepository
  participant GMRepo as GroupMemberRepository

  User->>Controller: GET /v1/groups/{groupId}
  Controller->>Service: findGroupDetail(authPrincipal, groupId)
  Service->>URepo: validateUser(authPrincipal)
  URepo-->>Service: UserProfile
  Service->>GRepo: findByIdAndDeletedAtIsNull(groupId)
  GRepo-->>Service: Group or empty
  Service->>GMRepo: existsByGroupIdAndUserId(groupId, userId)
  GMRepo-->>Service: boolean
  Service-->>Controller: GroupDetailResponse or throw
  Controller-->>User: 200 OK (GroupDetailResponse) / Error
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

enhancement

Suggested reviewers

  • dungbik

Poem

깡총 깡총, 새 API 문을 노크해요 🐇
삭제는 살짝 숨겨두고, 기록은 남겨요.
회원이면 문을 열어주고, 아니면 설명을 달아요.
DTO엔 이름과 시간, 서비스엔 검증이 반짝—
오늘도 풀밭에 코드 향기가 퍼지네.


📜 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 ef217d1 and 1870b3f.

📒 Files selected for processing (3)
  • src/main/java/project/flipnote/group/entity/Group.java (3 hunks)
  • src/main/java/project/flipnote/group/service/GroupService.java (4 hunks)
  • src/test/java/project/flipnote/group/service/GroupServiceTest.java (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/project/flipnote/group/service/GroupService.java
  • src/main/java/project/flipnote/group/entity/Group.java
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/test/java/project/flipnote/group/service/GroupServiceTest.java (2)
src/test/java/project/flipnote/fixture/UserFixture.java (1)
  • UserFixture (7-26)
src/main/java/project/flipnote/groupjoin/service/GroupJoinService.java (1)
  • Slf4j (30-244)
🔇 Additional comments (7)
src/test/java/project/flipnote/group/service/GroupServiceTest.java (7)

115-119: 이전 리뷰 개선사항이 적용됨

BizException을 캐치하여 구체적인 에러 코드를 검증하도록 개선되었습니다. 정확한 테스트 구현입니다.


176-176: 모의 객체 설정 개선 완료

이전 리뷰에서 지적된 하드코딩된 ID 1L 대신 userProfile.getId()를 사용하여 일관성을 맞췄습니다.


200-200: 모의 객체 설정 개선 완료

이전 리뷰에서 지적된 문제가 해결되었습니다. groupRepository.findByIdAndDeletedAtIsNull(1L)에 대해 Optional.empty()를 반환하도록 올바르게 설정되었습니다.


137-160: 그룹 상세 조회 성공 테스트 검증

테스트 로직이 올바르게 구현되어 있습니다. 사용자 검증, 그룹 조회, 멤버십 확인이 모두 적절하게 모킹되었고, 응답 검증도 정확합니다.


163-185: 사용자 미가입 시나리오 테스트 확인

그룹에 가입하지 않은 사용자가 그룹 상세를 조회할 때의 예외 처리가 올바르게 테스트되었습니다. GroupJoinErrorCode.USER_NOT_IN_GROUP 에러 코드 검증도 정확합니다.


188-207: 소프트 삭제된 그룹 조회 테스트 확인

소프트 삭제 기능이 도입된 상황에서 삭제된 그룹 조회 시 GROUP_NOT_FOUND 에러가 발생하는지 올바르게 테스트하고 있습니다.


74-74: AuthPrinciple 생성자 업데이트 확인

AuthPrinciple 생성자에 첫 번째 파라미터로 id가 추가된 새로운 API에 맞게 올바르게 업데이트되었습니다.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/find-group-detail

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: 4

🔭 Outside diff range comments (1)
src/main/java/project/flipnote/group/entity/GroupMember.java (1)

29-53: deletedAt 필드가 누락됨

GroupMember 엔티티에 소프트 삭제를 위한 @SQLDelete 애노테이션은 추가되었지만, 실제 deletedAt 필드가 엔티티에 정의되어 있지 않습니다. Group 엔티티(Line 60-61)처럼 deletedAt 필드를 추가해야 합니다.

다음과 같이 deletedAt 필드를 추가하세요:

 	private String imageUrl;
 
+	@Column(name = "deleted_at")
+	private LocalDateTime deletedAt;
+
 	@Builder

또한 필요한 import도 추가해야 합니다:

 import org.hibernate.annotations.SQLDelete;
 import org.hibernate.annotations.SQLRestriction;
+
+import java.time.LocalDateTime;
🧹 Nitpick comments (8)
src/main/java/project/flipnote/group/entity/Group.java (1)

7-7: 사용되지 않는 import 제거 필요

@Where 애노테이션이 import되어 있지만 실제로 사용되지 않습니다. 대신 @SQLRestriction이 사용되고 있으므로 불필요한 import를 제거해야 합니다.

 import org.hibernate.annotations.SQLDelete;
 import org.hibernate.annotations.SQLRestriction;
-import org.hibernate.annotations.Where;
src/main/java/project/flipnote/group/service/GroupService.java (5)

63-63: 오타: valiateGroupvalidateGroup으로 수정 필요

메서드명에 오타가 있습니다. 일관성을 위해 validateGroup으로 수정해야 합니다.

-public Group valiateGroup(Long groupId) {
+public Group validateGroup(Long groupId) {

56-58: validateGroupInUser 메서드명 개선 제안

메서드명이 의미를 명확하게 전달하지 못합니다. isUserInGroup 또는 isMemberOfGroup과 같이 더 직관적인 이름을 사용하는 것이 좋겠습니다.

-public boolean validateGroupInUser(UserProfile user, Long groupId) {
-    return groupMemberRepository.existsByGroup_idAndUser_id(groupId, user.getId());
+public boolean isUserInGroup(UserProfile user, Long groupId) {
+    return groupMemberRepository.existsByGroup_idAndUser_id(groupId, user.getId());

167-167: 메서드명 변경에 따른 호출부 수정 필요

validateGroupInUserisUserInGroup으로 변경한다면, 이 부분도 함께 수정해야 합니다.

-if (!validateGroupInUser(user, groupId)) {
+if (!isUserInGroup(user, groupId)) {

44-51: 주석 스타일 통일 필요

다른 메서드들과 달리 여러 줄 주석(/* */)을 사용하고 있습니다. 일관성을 위해 한 줄 주석(//)으로 통일하는 것이 좋겠습니다.

-/*
-유저 정보 조회
- */
+// 유저 정보 조회
public UserProfile validateUser(AuthPrinciple authPrinciple) {

86-86: 메서드 파라미터 순서 일관성 검토

saveGroupOwner(group, user) 메서드는 group을 먼저 받는 반면, validateGroupInUser(user, groupId)는 user를 먼저 받습니다. 파라미터 순서를 일관되게 유지하는 것이 좋습니다.

src/test/java/project/flipnote/group/service/GroupServiceTest.java (2)

3-4: 중복된 assertion 라이브러리 import

AssertJ와 JUnit의 assertion을 모두 import하고 있습니다. 일관성을 위해 하나로 통일하는 것이 좋겠습니다. AssertJ가 더 풍부한 API를 제공하므로 AssertJ로 통일을 권장합니다.

import static org.assertj.core.api.Assertions.*;
-import static org.junit.jupiter.api.Assertions.*;

이후 assertEquals 사용 부분도 AssertJ로 변경:

-assertEquals("그룹1", res.name());
+assertThat(res.name()).isEqualTo("그룹1");

73-75: 테스트 데이터 설정 명확화

AuthPrinciple 생성 시 첫 번째 파라미터로 1L을 사용하고 있는데, 이것이 무엇을 의미하는지 명확하지 않습니다. 의미를 명확하게 하기 위해 변수로 추출하거나 주석을 추가하는 것이 좋겠습니다.

-authPrinciple = new AuthPrinciple(1L, userProfile.getId(), userProfile.getEmail(), AccountRole.USER, 1L);
+// AuthPrinciple(accountId, userId, email, role, tokenVersion)
+authPrinciple = new AuthPrinciple(1L, userProfile.getId(), userProfile.getEmail(), AccountRole.USER, 1L);
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between ef8f71b and ef217d1.

📒 Files selected for processing (7)
  • src/main/java/project/flipnote/group/controller/GroupController.java (3 hunks)
  • src/main/java/project/flipnote/group/entity/Group.java (3 hunks)
  • src/main/java/project/flipnote/group/entity/GroupMember.java (2 hunks)
  • src/main/java/project/flipnote/group/model/GroupDetailResponse.java (1 hunks)
  • src/main/java/project/flipnote/group/repository/GroupRepository.java (1 hunks)
  • src/main/java/project/flipnote/group/service/GroupService.java (4 hunks)
  • src/test/java/project/flipnote/group/service/GroupServiceTest.java (4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (4)
src/main/java/project/flipnote/group/model/GroupDetailResponse.java (7)
src/main/java/project/flipnote/group/model/GroupCreateResponse.java (1)
  • GroupCreateResponse (3-9)
src/main/java/project/flipnote/group/model/GroupInfoResponse.java (1)
  • GroupInfoResponse (3-9)
src/main/java/project/flipnote/groupjoin/model/GroupJoinResponse.java (1)
  • GroupJoinResponse (5-11)
src/main/java/project/flipnote/group/model/GroupMemberInfoResponse.java (1)
  • GroupMemberInfoResponse (3-9)
src/main/java/project/flipnote/groupjoin/model/GroupJoinListResponse.java (1)
  • GroupJoinListResponse (7-13)
src/main/java/project/flipnote/groupjoin/model/GroupJoinRespondResponse.java (1)
  • GroupJoinRespondResponse (3-9)
src/main/java/project/flipnote/groupjoin/model/FindGroupJoinListMeResponse.java (1)
  • FindGroupJoinListMeResponse (7-13)
src/main/java/project/flipnote/group/entity/GroupMember.java (1)
src/main/java/project/flipnote/common/entity/SoftDeletableEntity.java (2)
  • SoftDeletableEntity (8-21)
  • softDelete (14-16)
src/main/java/project/flipnote/group/entity/Group.java (1)
src/main/java/project/flipnote/common/entity/SoftDeletableEntity.java (2)
  • SoftDeletableEntity (8-21)
  • softDelete (14-16)
src/test/java/project/flipnote/group/service/GroupServiceTest.java (1)
src/test/java/project/flipnote/fixture/UserFixture.java (1)
  • UserFixture (7-26)
🔇 Additional comments (13)
src/main/java/project/flipnote/group/entity/GroupMember.java (2)

3-4: 올바른 Hibernate 소프트 삭제 애노테이션 추가

GroupMember 엔티티에 소프트 삭제 기능이 올바르게 추가되었습니다. @SQLDelete@SQLRestriction 애노테이션을 통해 실제 삭제가 아닌 deleted_at 컬럼을 업데이트하는 방식으로 구현되어 있습니다.


27-28: 일관성 있는 소프트 삭제 구현

@SQLDelete@SQLRestriction 애노테이션이 올바르게 적용되었습니다. Group 엔티티와 동일한 패턴으로 소프트 삭제가 구현되어 일관성이 유지됩니다.

src/main/java/project/flipnote/group/entity/Group.java (3)

3-3: 필요한 import 추가됨

소프트 삭제 기능을 위한 필요한 import들이 올바르게 추가되었습니다.

Also applies to: 5-7


30-31: 올바른 소프트 삭제 애노테이션 구현

@SQLDelete@SQLRestriction 애노테이션이 올바르게 적용되어 있습니다. 삭제 시 실제 레코드를 제거하지 않고 deleted_at 컬럼을 현재 시간으로 업데이트하며, 조회 시 삭제되지 않은 레코드만 반환합니다.


60-61: deletedAt 필드 추가

소프트 삭제를 위한 deletedAt 필드가 올바르게 추가되었습니다. @Column 애노테이션을 통해 데이터베이스의 deleted_at 컬럼과 매핑됩니다.

src/main/java/project/flipnote/group/repository/GroupRepository.java (1)

17-17: 소프트 삭제에 맞는 repository 메서드로 변경

기존 findById 메서드가 findByIdAndDeletedAtIsNull로 변경되어 소프트 삭제된 그룹을 제외하고 조회할 수 있게 되었습니다. 이는 Group 엔티티의 소프트 삭제 구현과 일치합니다.

src/main/java/project/flipnote/group/controller/GroupController.java (2)

6-7: 새로운 엔드포인트를 위한 import 추가

그룹 상세 조회 API를 위한 필요한 import들이 올바르게 추가되었습니다.

Also applies to: 18-18


35-42: 그룹 상세 조회 API 엔드포인트 추가

새로운 GET 엔드포인트가 올바르게 구현되었습니다. @PathVariable을 통해 groupId를 받고, 인증된 사용자 정보를 @AuthenticationPrincipal로 받아 서비스 계층에 전달합니다.

src/main/java/project/flipnote/group/model/GroupDetailResponse.java (3)

8-27: 그룹 상세 정보를 위한 응답 DTO 정의

그룹의 상세 정보를 담는 record가 올바르게 정의되었습니다. 필요한 모든 필드들이 포함되어 있고 타입도 적절합니다.


28-40: 정적 팩토리 메서드 구현

Group 엔티티로부터 GroupDetailResponse를 생성하는 정적 팩토리 메서드가 올바르게 구현되었습니다. 다른 Response 클래스들과 일관된 패턴을 따르고 있습니다.


24-26: 필드명 일관성 확인 완료
BaseEntity(src/main/java/project/flipnote/common/entity/BaseEntity.java)에서 createdAtmodifiedAt 필드명이 GroupDetailResponse와 완전히 일치함을 확인했습니다. 추가 수정은 필요 없습니다.

src/main/java/project/flipnote/group/service/GroupService.java (1)

158-172: 트랜잭션 읽기 전용 설정 확인

findGroupDetail 메서드는 조회만 수행하므로 클래스 레벨의 @Transactional(readOnly = true) 설정이 적절합니다.

src/test/java/project/flipnote/group/service/GroupServiceTest.java (1)

133-156: 테스트 메서드 네이밍 일관성

그룹_상세_조회_성공 테스트는 잘 작성되었습니다. 검증 로직이 명확하고 필요한 모든 모의 객체 설정이 포함되어 있습니다.

@stoneTiger0912 stoneTiger0912 merged commit 088d44f into develop Aug 12, 2025
3 checks passed
@stoneTiger0912 stoneTiger0912 deleted the feat/find-group-detail branch August 12, 2025 13:19
@stoneTiger0912 stoneTiger0912 added the enhancement New feature or request label Sep 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants