Skip to content

[NO-ISSUE] 같은 기기 토큰 재할당·계정 전환 시 FCM 토큰 unique 충돌 방지#267

Merged
Develop-KIM merged 1 commit into
developfrom
feat/NO-ISSUE-fcm-account-switch
Jun 13, 2026
Merged

[NO-ISSUE] 같은 기기 토큰 재할당·계정 전환 시 FCM 토큰 unique 충돌 방지#267
Develop-KIM merged 1 commit into
developfrom
feat/NO-ISSUE-fcm-account-switch

Conversation

@Develop-KIM

@Develop-KIM Develop-KIM commented Jun 13, 2026

Copy link
Copy Markdown
Member

개요

PR #266 리뷰에서 보류했던 계정 전환 시 (user_id, device_id) unique 충돌(P2) 을 수정합니다.

문제

같은 물리 기기에서 FCM 토큰이 다른 row로 재할당되거나 계정을 전환할 때, findByToken으로 찾은 row의 (user_id, device_id)를 갱신하는 순간 기존 device row와 unique 제약이 충돌해 토큰 등록 API가 500으로 실패.

수정

  • syncExistingToken에서 대상 row 갱신 전에 동일 (userId, deviceId)의 다른 row를 벌크 삭제(@Modifying)하여, Hibernate의 update-before-delete flush 순서로 인한 충돌을 회피
  • FcmTokenRepository.deleteByUserIdAndDeviceIdExcludingId 추가

검증

  • 실제 unique 제약이 적용되는 @DataJpaTest 통합 테스트로 충돌을 재현하고 수정으로 해소됨을 확인 (수정 제거 시 테스트 실패하는 것까지 검증)
  • 전체 410개 테스트 통과

🤖 Generated with Claude Code

Summary by CodeRabbit

릴리스 노트

  • 버그 수정
    • 푸시 알림 토큰 등록 시 디바이스 재인증 및 계정 전환 시나리오에서 발생하던 오류를 해결했습니다.
    • 동일 기기에서 여러 토큰 재할당 상황에서 시스템 안정성을 개선했습니다.

같은 물리 기기에서 FCM 토큰이 다른 row 로 재할당되거나 계정을 전환할 때,
token 기준으로 찾은 row 의 (user_id, device_id) 를 갱신하는 순간 기존 device row 와
unique(user_id, device_id) 제약이 충돌해 등록 API 가 500 으로 실패하던 문제 수정.

- syncExistingToken 에서 대상 row 갱신 전, 동일 (userId, deviceId) 의 다른 row 를
  벌크 삭제(@Modifying)하여 Hibernate update-before-delete flush 순서로 인한 충돌 회피
- FcmTokenRepository.deleteByUserIdAndDeviceIdExcludingId 추가
- 실제 unique 제약이 적용되는 @DataJpaTest 통합 테스트로 재현·검증 (전체 410개 통과)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

FCM 토큰 등록 시 동일한 (userId, deviceId) 조합에서 기존 row를 제외한 다른 레코드를 먼저 삭제하는 로직을 추가하여 unique 제약 위반을 방지합니다. 저장소에 bulk delete 메서드를 정의하고, 서비스에서 이를 호출하며, 두 가지 시나리오를 검증하는 persistence 테스트를 포함합니다.

Changes

FCM Token Unique Constraint Handling

Layer / File(s) Summary
Repository bulk delete method
src/main/java/com/souzip/application/notification/required/FcmTokenRepository.java
Spring Data JPA 어노테이션 import(@Modifying, @Query, @Param)을 추가하고, 지정된 ID를 제외한 (userId, deviceId) 조합의 모든 row를 삭제하는 deleteByUserIdAndDeviceIdExcludingId 메서드를 JPQL DELETE 쿼리로 정의합니다.
Service integration for constraint prevention
src/main/java/com/souzip/application/notification/FcmTokenCommandService.java
syncExistingToken 흐름에서 토큰 업데이트 전에 저장소의 새 bulk delete 메서드를 호출하여 충돌하는 (userId, deviceId) row를 제거하고, 유니크 제약 위반을 방지합니다.
Persistence tests for unique constraint scenarios
src/test/java/com/souzip/application/notification/FcmTokenCommandServicePersistenceTest.java
@DataJpaTest 기반 테스트 클래스로, 동일 사용자/기기에서 토큰 재할당 및 다른 사용자로의 계정 전환 시나리오를 검증하며, 유니크 제약 위반 없이 정확히 하나의 active 토큰 row만 유지되는지 확인합니다.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

  • souzip/souzip-api#227: FcmToken 도메인과 FcmTokenRepository 계약을 도입한 PR이며, 본 PR은 그 위에 bulk delete 메서드 추가 및 unique 제약 처리 로직을 확장합니다.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 22.22% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed PR 제목은 핵심 변경 사항인 FCM 토큰의 unique 제약 충돌 방지를 명확하게 설명하고 있으며, 같은 기기에서의 토큰 재할당과 계정 전환이라는 구체적인 시나리오를 포함하고 있습니다.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/NO-ISSUE-fcm-account-switch

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@Develop-KIM Develop-KIM changed the title fix: 같은 기기 토큰 재할당·계정 전환 시 FCM 토큰 unique 충돌 방지 [NO-ISSUE] 같은 기기 토큰 재할당·계정 전환 시 FCM 토큰 unique 충돌 방지 Jun 13, 2026
@Develop-KIM Develop-KIM merged commit eeb1e1a into develop Jun 13, 2026
3 of 4 checks passed
@Develop-KIM Develop-KIM deleted the feat/NO-ISSUE-fcm-account-switch branch June 13, 2026 11:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant