release: 탈퇴 유저 재가입 허용 및 삭제/스케줄러 정합성 개선#278
Conversation
## 재가입 막힘 수정 - V30이 uq_provider_provider_id_deleted를 추가했지만 V4의 옛 제약 uq_provider_provider_id가 DROP되지 않아 두 제약이 공존했다. 탈퇴 유저 재로그인 시 익명화 UPDATE보다 신규 유저 INSERT가 먼저 flush되면서 옛 제약에 걸려 재가입이 500으로 실패했다. - V44로 옛 제약을 제거해 정책(재가입 = 신규 계정)대로 동작하게 한다. ## 하드 삭제 시 achievement 고아 데이터 정리 - 탈퇴 90일 경과 유저 하드 삭제 시 user_badges/user_missions/user_levels/ weekly_retro_streaks/daily_access_streaks가 남아 고아가 되었다(FK CASCADE 없음). - AchievementDeletionPort/Adapter를 추가해 유저 스코프 achievement 5종을 userId로 함께 삭제한다. ## 스케줄러 트랜잭션 격리 개선 - Cleanup/Mission/Notification 스케줄러가 배치 전체를 단일 트랜잭션으로 처리해, 한 건 실패 시 배치 전체가 롤백되고 나머지도 처리되지 않았다. - 건별 @transactional 헬퍼 빈(CleanupExecutor/MissionFailureProcessor/ ReminderNotificationSender)으로 분리하고, 스케줄러는 건별 runCatching으로 격리하여 한 건 실패가 나머지 처리를 막지 않도록 한다. ## 타임존 일원화 - NotificationScheduler의 인라인 ZoneId.of("Asia/Seoul")를 ServiceTime.ZONE로 통일한다. cron은 앱 규칙(UTC 발화 + ServiceTime 변환)에 따라 그대로 둔다. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…heduler-isolation fix: 탈퇴 유저 재가입 허용 및 삭제/스케줄러 정합성 개선
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 888fd575e6
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| @@ -0,0 +1 @@ | |||
| ALTER TABLE users DROP INDEX uq_provider_provider_id; | |||
There was a problem hiding this comment.
Preserve active-user uniqueness before dropping the legacy index
In the prod/dev MySQL profiles, the remaining UNIQUE(provider, provider_id, deleted_at) from V30 does not replace this key because active users have deleted_at = NULL and MySQL permits multiple NULL values in a unique index. Once this line drops uq_provider_provider_id, a login retry/race can insert two active rows with the same provider identity; AuthService.resolveUser then expects a single active row from findByProviderAndProviderId, so authentication can fail with a non-unique result or operate on the wrong account. Please add a real active-only uniqueness guard before dropping the legacy index.
Useful? React with 👍 / 👎.
develop → main 배포. PR #277 반영.
포함 변경
V44로 레거시 unique 제약(uq_provider_provider_id) 제거 → 재가입(신규 계정) 정상화배포 시 유의
V44마이그레이션이 운영 DB에 적용되어야 재가입이 실제로 풀립니다.🤖 Generated with Claude Code