Conversation
Summary of ChangesHello @lingard1234, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! 이 PR은 사용자가 자신의 계정을 즉시 삭제할 수 있는 기능을 도입합니다. 이 기능은 사용자 계정뿐만 아니라 해당 사용자와 관련된 모든 데이터를 데이터베이스에서 물리적으로 제거하여 데이터 무결성을 유지하고 개인 정보 보호 요구사항을 충족하도록 설계되었습니다. 이를 통해 시스템에서 더 이상 필요 없는 사용자 데이터를 효율적으로 관리할 수 있습니다. Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
유저 즉시 삭제 API를 구현하는 PR입니다. 삭제 로직을 별도 서비스와 트랜잭션 메서드로 분리하여 데이터 일관성을 보장하려는 시도는 좋습니다. 다만, 몇 가지 개선점이 보입니다.
첫째, 브랜드를 소유한 유저의 데이터를 삭제하는 로직이 불완전하여, 해당 브랜드에 연결된 캠페인 등이 있는 경우 서버 오류가 발생할 수 있습니다. 이 부분을 더 안정적으로 처리해야 합니다.
둘째, 리포지토리 메서드에 불필요한 @Transactional 어노테이션이 사용되었습니다. 트랜잭션 관리는 서비스 계층에서 일관되게 처리하는 것이 좋습니다.
전반적으로 좋은 방향의 변경이지만, 기능의 안정성을 위해 지적된 이슈들을 수정하는 것을 권장합니다.
| private void deleteRelatedData(Long userId) { | ||
| tagUserRepository.deleteByUserId(userId); | ||
| userContentCategoryRepository.deleteByUserId(userId); | ||
| userSignupPurposeRepository.deleteByUserId(userId); | ||
| userTermRepository.deleteByUserId(userId); | ||
| notificationSettingRepository.deleteByUserId(userId); | ||
| matchBrandHistoryRepository.deleteByUserId(userId); | ||
| matchCampaignHistoryRepository.deleteByUserId(userId); | ||
| brandLikeRepository.deleteByUserId(userId); | ||
| campaignLikeRepository.deleteByUserId(userId); | ||
| campaignApplyRepository.deleteByUserId(userId); | ||
| campaignProposalRepository.deleteByUserId(userId); | ||
| brandRepository.deleteByUserId(userId); | ||
| authenticationMethodRepository.deleteByUserId(userId); | ||
| } |
There was a problem hiding this comment.
현재 유저 관련 데이터 삭제 구현이 불완전합니다. 특히, 유저가 'Brand'의 소유주일 경우, 해당 브랜드에 'Campaign'과 같은 다른 엔티티가 연결되어 있다면 66라인의 brandRepository.deleteByUserId(userId) 호출 시 데이터베이스 제약 조건 위반으로 실패하게 됩니다. 이는 처리되지 않은 500 에러로 이어져 사용자 경험을 해칩니다.
Swagger 문서에 이 가능성을 언급하셨지만, 애플리케이션 레벨에서 이 경우를 더 안정적으로 처리하는 것이 바람직합니다. 브랜드에 종속된 데이터를 먼저 삭제하거나, 삭제가 불가능한 경우 명확한 에러 메시지(예: 409 Conflict)를 반환하여 유저가 상황을 인지할 수 있도록 해야 합니다.
There was a problem hiding this comment.
"이 API는 개발/테스트용 헬퍼로 실제 프로덕션에서는 사용되지 않습니다. 실제 서비스에서는 soft delete를 사용합니다."
| @Modifying | ||
| @Transactional | ||
| @Query("DELETE FROM CampaignProposal cp WHERE cp.senderUserId = :userId OR cp.receiverUserId = :userId") | ||
| void deleteByUserId(@Param("userId") Long userId); |
There was a problem hiding this comment.
리포지토리 메서드에 있는 @Transactional 어노테이션은 중복되므로 제거하는 것이 좋습니다. 이 메서드를 호출하는 UserDeleteService.deleteUserImmediately 서비스 메서드에 이미 @Transactional이 선언되어 있어, 해당 트랜잭션에 자동으로 참여하게 됩니다.
트랜잭션 경계는 서비스 계층에서 관리하는 것으로 일관성을 유지하면 코드의 트랜잭션 동작을 더 명확하게 파악하고 관리할 수 있습니다.
| @Modifying | |
| @Transactional | |
| @Query("DELETE FROM CampaignProposal cp WHERE cp.senderUserId = :userId OR cp.receiverUserId = :userId") | |
| void deleteByUserId(@Param("userId") Long userId); | |
| @Modifying | |
| @Query("DELETE FROM CampaignProposal cp WHERE cp.senderUserId = :userId OR cp.receiverUserId = :userId") | |
| void deleteByUserId(@Param("userId") Long userId); |
Summary
유저 삭제 시 연관된 모든 데이터를 즉시 삭제하는 API를 구현했습니다.
Changes
DELETE /api//me/delete-immediately엔드포인트 추가CampaignProposalRepository.deleteByUserId()메서드 관련@Query사용하여 senderUserId, receiverUserId 모두 처리Type of Change
Related Issues
Closes #365
참고 사항