feat: 회원 탈퇴 기능 구현 - #175
Conversation
|
Warning Review limit reached
Next review available in: 35 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthrough회원 탈퇴 요청 DTO와 Changes회원 탈퇴
Estimated code review effort: 3 (Moderate) | ~20 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant UserController
participant AuthenticatedUserResolver
participant UserProfileService
participant PushDeviceTokenRepository
Client->>UserController: DELETE /api/v1/users/me + currentPassword
UserController->>AuthenticatedUserResolver: resolveActiveUser(Authorization)
AuthenticatedUserResolver-->>UserController: 활성 사용자
UserController->>UserProfileService: withdraw(User, UserWithdrawalRequest)
UserProfileService->>PushDeviceTokenRepository: 활성 푸시 토큰 조회 및 소프트 삭제
UserProfileService-->>UserController: 탈퇴 완료
UserController-->>Client: USER_WITHDRAWAL_SUCCESS
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/main/java/com/gachi/be/domain/user/entity/User.java`:
- Around line 126-132: User 엔티티의 withdraw, changeLanguage,
changeNotificationPreference 동시 변경 경로에 일관된 동시성 제어를 적용하세요. `@Version` 기반 낙관적 잠금을
User에 추가하거나 모든 변경 메서드가 동일한 비관적 잠금으로 최신 엔티티를 읽고 저장하도록 통일해, 탈퇴 커밋 이후 오래된 엔티티가
status와 deletedAt을 덮어쓰지 않게 하세요.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 18fc053c-f359-47dc-a0cd-61f2ff3fdf06
📒 Files selected for processing (6)
src/main/java/com/gachi/be/domain/user/api/controller/UserController.javasrc/main/java/com/gachi/be/domain/user/dto/request/UserWithdrawalRequest.javasrc/main/java/com/gachi/be/domain/user/entity/User.javasrc/main/java/com/gachi/be/domain/user/service/UserProfileService.javasrc/main/java/com/gachi/be/global/code/SuccessCode.javasrc/test/java/com/gachi/be/domain/user/api/controller/UserControllerIntegrationTest.java
| public void withdraw(OffsetDateTime withdrawnAt) { | ||
| if (withdrawnAt == null) { | ||
| throw new IllegalArgumentException("withdrawnAt은 비어 있을 수 없습니다."); | ||
| } | ||
| this.status = UserStatus.WITHDRAWN; | ||
| this.deletedAt = withdrawnAt; | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# User 엔티티의 버전/동적 업데이트 설정과 사용자 변경 경로의 잠금 사용 여부를 확인합니다.
ast-grep outline src/main/java/com/gachi/be/domain/user/entity/User.java --items all
rg -n -C3 '`@Version`|`@DynamicUpdate`|findByIdWithLock|changeLanguage|changeNotificationPreference' \
src/main/java/com/gachi/be/domain/userRepository: GACHI-Project/GACHI-BE
Length of output: 4609
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "== User.java relevant section =="
sed -n '1,220p' src/main/java/com/gachi/be/domain/user/entity/User.java
echo "== UserProfileService relevant sections =="
sed -n '1,260p' src/main/java/com/gachi/be/domain/user/service/UserProfileService.java
echo "== UserRepository =="
sed -n '1,90p' src/main/java/com/gachi/be/domain/user/repository/UserRepository.java
echo "== Controller relevant sections =="
sed -n '70,150p' src/main/java/com/gachi/be/domain/user/api/controller/UserController.java
echo "== Search all user state/status persistence paths =="
rg -n -C2 'setLanguage|setNotification|Status|deletedAt|withdraw|updateProfile|changeEmail|updateLanguage|updateNotification|resolvedActiveUser|findAllById|save\(|getOne|getReference' \
src/main/java/com/gachi/be/domain/user || true
echo "== Behavioral probe for SQL UPDATE semantics in code if JPA annotations exist =="
python3 - <<'PY'
from pathlib import Path
p = Path('src/main/java/com/gachi/be/domain/user/service/UserProfileService.java')
text = p.read_text()
for name in ['changeLanguage', 'changeNotificationPreference', 'findActiveUserWithLock']:
idx=text.find(name)
print(f'--- {name} @ {idx} ---')
print(text[idx:idx+1200])
PYRepository: GACHI-Project/GACHI-BE
Length of output: 43986
탈퇴 상태가 동시 프로필 변경으로 되돌아갈 수 있습니다.
withdraw는 비관적 잠금으로 다시 읽지만, changeLanguage·changeNotificationPreference는 잠금/버전 검사 없이 먼저 읽은 User를 저장합니다. @Version도 없어 탈퇴 커밋 뒤 오래된 엔티티의 flush가 status=ACTIVE, deletedAt=null을 덮어써 계정을 재활성화될 수 있습니다. @Version 기반 낙관적 잠금을 추가하거나 모든 사용자 변경 경로를 동일한 잠금 전략으로 통일하세요.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/main/java/com/gachi/be/domain/user/entity/User.java` around lines 126 -
132, User 엔티티의 withdraw, changeLanguage, changeNotificationPreference 동시 변경 경로에
일관된 동시성 제어를 적용하세요. `@Version` 기반 낙관적 잠금을 User에 추가하거나 모든 변경 메서드가 동일한 비관적 잠금으로 최신
엔티티를 읽고 저장하도록 통일해, 탈퇴 커밋 이후 오래된 엔티티가 status와 deletedAt을 덮어쓰지 않게 하세요.
📌 작업 요약
🌿 브랜치 정보
feat/#174-user-withdrawaldevelop✅ 체크리스트
feat/refac/hotfix/chore/design/bugfix)feat/fix/refactor/docs/style/chore)🧪 테스트 결과
./gradlew.bat --no-daemon spotlessCheck통과UserControllerIntegrationTest전체 통과./gradlew.bat --no-daemon test전체 통과Summary by CodeRabbit