-
Notifications
You must be signed in to change notification settings - Fork 3
[Refactor/#404][jjaeroong]: 회원 탈퇴 API 수정 #407
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the 워크스루사용자 삭제 흐름과 포트 연관 데이터 삭제 로직이 확장됐고, 피드 변환기에 작성자 닉네임 및 댓글 수 계산이 추가되었으며, 여러 저장소에 대량 삭제/조회용 메서드가 도입되고 ErrorStatus에 새 에러 상수가 추가되었습니다. 변경 사항
시퀀스 다이어그램(s)sequenceDiagram
participant Caller as API / Service
participant UserCmd as UserCommandServiceImpl
participant PotRepo as PotRepository
participant PotAppRepo as PotApplicationRepository
participant PotMemRepo as PotMemberRepository
participant ChatInfoRepo as ChatRoomInfoRepository
participant PotSaveRepo as PotSaveRepository
participant PotRecruitRepo as PotRecruitmentDetailsRepository
participant PotCommentRepo as PotCommentRepository
Caller->>UserCmd: deleteUser(user)
UserCmd->>PotSaveRepo: deleteUserSavedPots(user)
alt user is creator
UserCmd->>PotRepo: find pots by user & statuses
PotRepo-->>UserCmd: pot id lists
UserCmd->>PotRecruitRepo: deleteByPotIds(recruitmentIds)
UserCmd->>PotAppRepo: deleteByPotIds(appIds)
UserCmd->>UserCmd: deletePotAndRelatedData(potIds)
UserCmd-->>Caller: success or throw POT_OWNERSHIP_TRANSFER_REQUIRED
else normal user
UserCmd->>PotMemRepo: find ONGOING pot members
UserCmd->>ChatInfoRepo: deleteByPotMemberIdAndChatRoomIds(...)
UserCmd->>PotAppRepo: delete applications by user
end
UserCmd->>UserCmd: soft-delete user (when applicable)
추정된 코드 리뷰 노력🎯 4 (Complex) | ⏱️ ~45분 관련 가능한 PR들
제안된 레이블
제안된 리뷰어
토끼의 시
✨ Finishing Touches🧪 Generate unit tests
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
Status, Documentation and Community
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 9
🧹 Nitpick comments (6)
src/main/java/stackpot/stackpot/pot/entity/Pot.java (1)
32-32: cascade ALL + orphanRemoval 활성화에 따른 삭제 전략 정합성 확인
recruitmentDetails에cascade = CascadeType.ALL, orphanRemoval = true를 설정하면 Pot 엔티티 삭제/컬렉션 제거 시 자식이 자동 삭제됩니다. 동시에 PR에서PotRecruitmentDetailsRepository.deleteByPotIds(...)같은 벌크 삭제도 도입되어 있습니다.
- 동일 데이터에 대해 cascade 삭제와 벌크 삭제를 혼용하면 영속성 컨텍스트 정합성 문제나 중복 삭제 시도가 발생할 수 있습니다.
- 서비스 레이어에서 한 가지 경로만 사용하도록 통일(예: Pot 삭제 시에는 cascade, 개별 정리 시에는 벌크)하는 룰을 정의해 주세요.
또한 벌크 삭제 사용 시
@Modifying(clearAutomatically = true)또는EntityManager.clear()로 1차 캐시 정리를 권장합니다.src/main/java/stackpot/stackpot/pot/repository/PotSaveRepository.java (1)
51-56: 빈 컬렉션 가드 및 벌크 삭제 후 컨텍스트 정리
pots가 빈 리스트면 IN () 오류가 날 수 있으므로, 서비스 레벨에서 조기 반환을 권장합니다.- 벌크 삭제 후 1차 캐시 정리를 위해 clear/flush 자동화를 설정하는 것을 권장합니다.
- @Modifying - @Transactional + @Modifying(clearAutomatically = true, flushAutomatically = true) + @Transactional @Query("DELETE FROM PotSave ps WHERE ps.user = :user AND ps.pot IN :pots") void deleteAllByUserAndPots(@Param("user") User user, @Param("pots") List<Pot> pots);파생 메서드(
deleteAllByUserAndPotIn)로도 구현 가능하니 팀 컨벤션에 맞게 선택해 주세요.src/main/java/stackpot/stackpot/feed/converter/FeedConverter.java (2)
33-39: 댓글 수 N+1 발생 가능성 — 상위 레이어에서 일괄 전달 고려
feedDto내부에서 매 호출마다countByFeedId를 호출하면 목록 변환 시 N+1 문제가 발생할 수 있습니다.toAuthorizedFeedDto처럼 상위 서비스에서commentCount를 계산(또는 일괄 조회)해 파라미터로 전달하도록 API를 통일하는 것을 고려해 주세요.
113-118: 작성자 표기 로직 통일 적용 LGTM + 추가 적용 제안
toAuthorizedFeedDto에서getWriterNickname을 사용하도록 통일한 점 좋습니다. 동일 로직을toSearchDto(),toFeedCacheDto()등 다른 빌더에서도 일관되게 사용하면 UI 표기가 통일됩니다.src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java (2)
406-408: 주석 처리된 코드 정리 필요주석 처리된 코드가 불완전한 상태로 남아있습니다. 사용하지 않는다면 완전히 제거하는 것이 좋습니다.
- // 2) 완료된 Pot → 현재 유저의 PotMember만 일괄 소프트 딜리트 (배치 UPDATE) -// if (!completedPotIds.isEmpty()) { -// potMemberRepository.softDeleteByPotIdsAndUserId(completedPotIds, userId); -// } -//
349-361: 불필요한 중간 단계 제거 가능
deleteUserSavedPots메서드에서PotSave를 먼저 조회한 후Pot을 추출하지만, 실제로Pot리스트는 사용되지 않고 있습니다.더 간단한 구현을 제안합니다:
@Transactional public void deleteUserSavedPots(User user) { - // 사용자가 저장한 PotSave 목록을 조회 - List<PotSave> userSavedPots = potSaveRepository.findByUser(user); - - // 해당 PotSave 엔티티에서 Pot만 추출 - List<Pot> potsToDelete = userSavedPots.stream() - .map(PotSave::getPot) // PotSave에서 Pot만 추출 - .collect(Collectors.toList()); - - // 사용자가 저장한 PotSave만 삭제 - potSaveRepository.deleteAllByUserAndPots(user, potsToDelete); + // 사용자가 저장한 모든 PotSave 삭제 + potSaveRepository.deleteAllByUser(user); }
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
src/main/java/stackpot/stackpot/apiPayload/code/status/ErrorStatus.java(1 hunks)src/main/java/stackpot/stackpot/chat/repository/ChatRoomInfoRepository.java(1 hunks)src/main/java/stackpot/stackpot/feed/converter/FeedConverter.java(4 hunks)src/main/java/stackpot/stackpot/pot/entity/Pot.java(1 hunks)src/main/java/stackpot/stackpot/pot/repository/PotApplicationRepository.java(2 hunks)src/main/java/stackpot/stackpot/pot/repository/PotMemberRepository.java(2 hunks)src/main/java/stackpot/stackpot/pot/repository/PotRecruitmentDetailsRepository.java(1 hunks)src/main/java/stackpot/stackpot/pot/repository/PotRepository.java(2 hunks)src/main/java/stackpot/stackpot/pot/repository/PotSaveRepository.java(1 hunks)src/main/java/stackpot/stackpot/user/entity/User.java(1 hunks)src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java(6 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
src/main/java/stackpot/stackpot/feed/converter/FeedConverter.java (1)
src/main/java/stackpot/stackpot/feed/dto/FeedResponseDto.java (1)
FeedResponseDto(11-85)
src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java (5)
src/main/java/stackpot/stackpot/chat/service/chatroominfo/ChatRoomInfoCommandService.java (1)
Service(12-49)src/main/java/stackpot/stackpot/common/util/AuthService.java (1)
Service(13-48)src/main/java/stackpot/stackpot/apiPayload/exception/handler/PotHandler.java (1)
PotHandler(6-10)src/main/java/stackpot/stackpot/apiPayload/exception/handler/TokenHandler.java (1)
TokenHandler(6-10)src/main/java/stackpot/stackpot/apiPayload/exception/handler/UserHandler.java (1)
UserHandler(6-10)
🔇 Additional comments (3)
src/main/java/stackpot/stackpot/user/entity/User.java (1)
114-116: 리뷰 코멘트 오류:User.java파일을 찾을 수 없습니다
현재 코드베이스에는src/main/java/stackpot/stackpot/user/entity/TempUser.java만 존재하며, 리뷰 코멘트에서 언급된User.java는 없습니다.
원본 코멘트는 잘못된 파일을 대상으로 하고 있으니 무시해 주세요.Likely an incorrect or invalid review comment.
src/main/java/stackpot/stackpot/pot/repository/PotApplicationRepository.java (1)
27-30: 벌크 삭제 트랜잭션·컨텍스트 문제 없음, 빈 리스트 가드만 권장UserCommandServiceImpl의 deleteByPotIds 호출부가 모두 메서드 단위 @transactional 안에서 실행되고 있어 트랜잭션 경계는 확보되어 있습니다. 따라서
@Modifying(clearAutomatically=true, flushAutomatically=true)는 필수가 아니며, JPA가 커밋 시점에 자동 flush/clear를 수행합니다.
다만 빈 리스트가 들어올 때 SQL IN () 구문 오류를 방지하려면 서비스 레이어에서 조기 반환을 추가해주세요.검토 포인트:
- 파일: src/main/java/stackpot/stackpot/pot/repository/PotApplicationRepository.java
- 수정 제안: 빈 리스트인 경우 deleteByPotIds 호출 전 리턴
public void removeApplicationsByPotIds(List<Long> potIds) { if (CollectionUtils.isEmpty(potIds)) { return; } potApplicationRepository.deleteByPotIds(potIds); // 필요 시 추가 비즈니스 로직… }src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java (1)
425-426: soft delete 구현 확인 완료
User.deleteUser()메서드가isDeleted = true로 설정하고,nickname,role,kakaoId,interests등을 초기화하여 soft delete를 올바르게 수행함이 확인되었습니다.
src/main/java/stackpot/stackpot/apiPayload/code/status/ErrorStatus.java
Outdated
Show resolved
Hide resolved
src/main/java/stackpot/stackpot/chat/repository/ChatRoomInfoRepository.java
Show resolved
Hide resolved
src/main/java/stackpot/stackpot/pot/repository/PotMemberRepository.java
Outdated
Show resolved
Hide resolved
src/main/java/stackpot/stackpot/pot/repository/PotRecruitmentDetailsRepository.java
Show resolved
Hide resolved
src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java
Outdated
Show resolved
Hide resolved
src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java
Outdated
Show resolved
Hide resolved
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
|
@coderabbitai resolve |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 2
♻️ Duplicate comments (4)
src/main/java/stackpot/stackpot/pot/repository/PotMemberRepository.java (1)
94-96: 이전 리뷰 지적사항이 아직 해결되지 않음이전 리뷰에서 지적된 중복 메서드 문제가 여전히 존재합니다.
deleteByPotIdsAndUserId메서드(93-96번 줄)가 잘못된 필드pm.pot.id를 참조하고 있으며, 새로 추가된deleteByUserIdAndPotIdIn메서드와 기능이 중복됩니다.다음 중 하나를 선택하여 해결하세요:
deleteByPotIdsAndUserId메서드를 삭제하고deleteByUserIdAndPotIdIn만 유지deleteByPotIdsAndUserId의 필드 참조를pm.pot.potId로 수정하고 중복 메서드 제거@Modifying @Query(""" DELETE FROM PotMember pm - WHERE pm.pot.id IN :potIds + WHERE pm.pot.potId IN :potIds AND pm.user.id = :userId """) void deleteByPotIdsAndUserId(@Param("potIds") List<Long> potIds, @Param("userId") Long userId); -@Modifying -@Query("DELETE FROM PotMember pm WHERE pm.pot.potId IN :potIds AND pm.user.id = :userId") -void deleteByUserIdAndPotIdIn(@Param("userId") Long userId, @Param("potIds") List<Long> potIds);src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java (3)
394-428: Creator 삭제 로직에서 트랜잭션 관리 개선 필요
handleCreatorPotDeletion메서드에@Transactional어노테이션이 추가되었지만, 여전히 데이터 일관성 문제가 있을 수 있습니다. 특히POT_OWNERSHIP_TRANSFER_REQUIRED예외가 발생할 경우 이전 작업들이 롤백되어야 합니다.롤백 처리를 명시적으로 지정하는 것을 고려해보세요:
-@Transactional +@Transactional(rollbackFor = Exception.class) public void handleCreatorPotDeletion(User user) {
515-522: ChatRoomInfo 삭제 호출에서 잘못된 매개변수 사용이전 리뷰에서 지적된 문제가 여전히 존재합니다.
deleteByPotMemberIdAndChatRoomId메서드를 올바른 매개변수로 호출해야 합니다.현재 코드가
potId를chatRoomId로 사용하고 있는데, 이는 부정확할 수 있습니다. ChatRoom ID를 올바르게 조회하여 사용해야 합니다:// 2) 진행 중인 팟 ID와 매칭되는 potMemberId마다 삭제 호출 userMemberDtos.stream() .filter(dto -> ongoingPotIds.contains(dto.getPotId())) .forEach(dto -> { + // ChatRoom ID를 정확히 조회 + Optional<Long> chatRoomId = chatRoomRepository.selectChatRoomIdByPotId(dto.getPotId()); + if (chatRoomId.isPresent()) { chatRoominfoRepository.deleteByPotMemberIdAndChatRoomId( dto.getPotMemberId(), - dto.getPotId() // 채팅방 ID가 potId와 동일하다고 가정 + chatRoomId.get() ); + } });
503-534: Normal User 삭제 로직에서 트랜잭션 관리 누락
handleNormalUserPotDeletion메서드에도@Transactional어노테이션이 추가되었지만, 이전 리뷰에서 지적된 트랜잭션 관리 문제가 완전히 해결되지 않았습니다.롤백 처리를 명시적으로 지정하세요:
-@Transactional +@Transactional(rollbackFor = Exception.class) public void handleNormalUserPotDeletion(User user) {
📜 Review details
Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
src/main/java/stackpot/stackpot/apiPayload/code/status/ErrorStatus.java(1 hunks)src/main/java/stackpot/stackpot/chat/repository/ChatRoomInfoRepository.java(2 hunks)src/main/java/stackpot/stackpot/chat/repository/ChatRoomRepository.java(1 hunks)src/main/java/stackpot/stackpot/pot/repository/PotMemberRepository.java(2 hunks)src/main/java/stackpot/stackpot/pot/repository/PotRecruitmentDetailsRepository.java(1 hunks)src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- src/main/java/stackpot/stackpot/apiPayload/code/status/ErrorStatus.java
- src/main/java/stackpot/stackpot/pot/repository/PotRecruitmentDetailsRepository.java
- src/main/java/stackpot/stackpot/chat/repository/ChatRoomInfoRepository.java
🧰 Additional context used
🧬 Code Graph Analysis (1)
src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java (4)
src/main/java/stackpot/stackpot/search/service/SearchServiceImpl.java (1)
Service(30-133)src/main/java/stackpot/stackpot/chat/service/chatroom/ChatRoomCommandService.java (1)
Service(12-32)src/main/java/stackpot/stackpot/chat/service/chatroominfo/ChatRoomInfoCommandService.java (1)
Service(12-49)src/main/java/stackpot/stackpot/apiPayload/exception/handler/PotHandler.java (1)
PotHandler(6-10)
🔇 Additional comments (4)
src/main/java/stackpot/stackpot/chat/repository/ChatRoomRepository.java (1)
17-17: JPQL 생성자 표현식 수정이 올바릅니다.중첩 클래스 참조를
ChatRoomDto.ChatRoomNameDto로 정확히 수정하여 JPQL 문법에 맞게 개선되었습니다.src/main/java/stackpot/stackpot/pot/repository/PotMemberRepository.java (1)
42-42: 이모지 제거로 코드 가독성 향상주석에서 이모지를 제거하여 코드의 전문성과 가독성이 향상되었습니다.
src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java (2)
69-69: 새로운 의존성 추가 확인ChatRoomInfoRepository, PotSaveRepository, PotCommentRepository가 새로 추가되어 회원 탈퇴 시 관련 데이터를 정리할 수 있게 되었습니다.
Also applies to: 77-77, 79-79
325-327: 사용자 저장 Pot 삭제 로직 추가회원 탈퇴 시 사용자가 저장한 PotSave 데이터를 정리하는 로직이 추가되어 데이터 일관성이 향상되었습니다.
src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java
Outdated
Show resolved
Hide resolved
src/main/java/stackpot/stackpot/user/service/UserCommandServiceImpl.java
Outdated
Show resolved
Hide resolved
✅ Actions performedComments resolved. |
[MERGE] dev -> main
…efactor/#404-withdrawal
|
@coderabbitai resolve |
✅ Actions performedComments resolved. |
PR 타입(하나 이상의 PR 타입을 선택해주세요)
반영 브랜치
Refactor/#404 withdrawal -> dev
작업 내용
1.. 회원 탈퇴 기능을 구현했습니다.
accessToken을 통해 사용자를 인증하고, 해당 사용자의 정보를 조회했습니다.PotSave내역만 삭제하고, Pot 자체는 삭제하지 않도록 처리했습니다.PotSaveRepository를 사용하여 해당 데이터를 삭제했습니다.PotSaveRepository에 관련 메서드 추가PotSaveRepository에 추가하여, 탈퇴 시 PotSave 내역만 삭제되도록 구현했습니다.테스트 결과
Summary by CodeRabbit
신규 기능
개선
변경 사항