You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
refactor(setting): 수신자 등록이 서버가 준 receiverId 를 버린다 — 호출부마다 스냅샷 diff 우회가 생긴다 #1586
// feature/setting/presentation/.../viewmodel/ReceiverRegisterViewModel.kt:37
runCatching {
userRepository.createReceiver(...)
}.onSuccess { // ← ReceiverCreated 를 받고도 안 쓴다_events.send(ReceiverRegisterEvent.RegisterSuccess) // ← id 없는 성공 신호만 나간다
}
ReceiverCreated 를 실제로 소비하는 곳은 UserMapper · UserRepositoryImpl · 테스트 픽스처뿐이고, 화면 계층 소비자는 0건이다.
이 때문에 생긴 우회
PR #1583(#1427 애프터노트 수신자 0건 CTA)이 등록 화면에서 돌아온 뒤 방금 만든 수신자를 선택 상태로 만들어야 했는데, id 를 못 받아 진입 직전 목록 스냅샷 → 복귀 후 재조회 → 새로 생긴 id 를 diff 로 찾기 를 구현했다. 부작용으로 「같은 사이 새 id 가 둘 이상이면 선택하지 않음」 같은 예외 규칙까지 생겼다(다른 기기에서 동시에 등록한 경우).
#872(타임레터 수신자 0명에서 등록 후 작성 화면 복귀)가 같은 흐름이라 이 우회를 그대로 한 번 더 만들게 된다.
완료 조건
ReceiverRegisterEvent.RegisterSuccess 가 새 receiverId 를 싣는다(또는 그에 준하는 반환 채널).
등록 화면 호출부가 그 id 를 결과로 돌려받을 수 있다 — 최종 setting Nav3 entry 결과 계약을 사용하며, 폐기될 Nav2 SavedStateHandle 배선을 먼저 구현하지 않는다.
#1793에서 스냅샷 diff 우회 복원 계획을 제거했다. 새 receiverId 반환 계약이 완성되기 전 우회를 다시 구현하지 않는다.
도메인·데이터 계층은 손댈 게 없다. 변경은 feature/setting/presentation 안에서 닫힌다.
구현 순서
새 receiverId를 실제 소비하는 #1793의 등록 왕복과 결과 전달을 같은 변경에서 완성한다. 현재 설정 자체의 등록 성공·pop 동작에 소비하지 않는 id 필드나 반환 채널을 미리 추가하지 않는다. #1793에서 스냅샷 비교 우회는 제거했으며, 이 이슈와 함께 확정된 Nav3 경계로만 연결한다.
착수 전 점검에서 본문 전제가 두 군데 무너진 것을 확인했습니다. 기준 리비전은 origin/develop86ab223 이고, BE 는 Afternote/Afternote-BEorigin/main 을 직접 읽었습니다(로컬 체크아웃이 없어 GitHub API 로 조회).
1. 서버가 이 엔드포인트를 지웠다
BE 커밋 7009eed2 "[feat] 카카오톡 초대 기반 수신자 등록 및 받은 기록 조회 전환"(2026-09-08, PR Afternote/Afternote-BE#289 로 main 반영)이 UserController 의 POST /api/v1/users/receivers 핸들러와 UserCreateReceiverRequest.java · UserCreateReceiverResponse.java 를 통째로 지웠습니다. 삭제 직전 리비전 8770ad59 의 UserCreateReceiverResponse 에는 receiverId 와 authCode 가 있었으니, 이 이슈가 말한 "서버가 준 receiverId" 는 작성 시점엔 맞았고 지금은 없습니다.
대체 흐름인 ReceiverInvitationController 의 POST /api/v1/receiver-invitations 는 응답 ReceiverInvitationCreateResponse 에 invitationId · invitationToken · invitationUrl · expiresAt 만 싣습니다. receiverId 는 수락 시점의 ReceiverInvitationAcceptResponse 에서야 생깁니다. 즉 새 계약에는 "등록 직후 새 receiverId" 라는 값 자체가 존재하지 않습니다.
FE develop 은 이 전환을 하나도 반영하지 않았습니다. core/network/.../UserApiService.kt:39-42 가 여전히 @POST("users/receivers") 를 부르고, receiver-invitations · ReceiverInvitation 문자열은 저장소에 0건입니다. 전환은 #944 몫이고 그쪽은 #1948 에 blocked 입니다.
2. 이 이슈를 낳은 우회가 이미 사라졌다
본문은 "PR #1583 이 스냅샷 → 재조회 → diff 우회를 구현했다(머지 대기)" 를 손해 근거로 들었는데, #1583 은 2026-09-04T15:07:38Z 에 머지됐고 같은 PR 안의 커밋 442a72733 이 그 우회를 전부 삭제했습니다. 커밋 메시지가 이유를 적어 뒀습니다. #1793 이 등록 진입 배선을 떼어 간 뒤 core:ui 등록 행과 빈 화면 CTA, onReceiverRegisterStart, refreshAfterReceiverRegister, ON_RESUME 효과가 테스트에서만 참조되고 있었다는 것입니다. 지금 SelectReceiverScreen.kt:81-116 의 빈 상태는 문구 두 줄과 일러스트뿐이고 등록 CTA 가 없습니다.
"#872 가 같은 흐름이라 우회를 한 번 더 만들게 된다" 도 지금은 성립하지 않습니다. #872 와 #1427 둘 다 #1793 의 PM 답변 대기로 묶여 있고, #1427 은 "수신자 등록 진입의 상충된 승인 근거를 확인한다" 로 재작성됐습니다.
3. 살아 있는 사실과 낡은 인용
ReceiverCreated 를 버리는 자리는 여전히 한 곳입니다. 다만 위치는 feature/setting/presentation/.../viewmodel/ReceiverRegisterViewModel.kt:58-67 이고 본문이 쓴 :37 은 지금 이메일 검증 분기입니다. 호출도 runCatching 이 아니라 runCatchingCancellable 입니다.
ViewModel 이 주입받는 것은 UserReceiverRepository 가 아니라 합본 UserRepository 입니다(ReceiverRegisterViewModel.kt:6,22). 본문이 지목한 파일은 VM 이 실제로 보는 계약이 아닙니다.
"화면 계층 소비자 0건" 은 재측정 결과 사실입니다. 프로덕션 참조는 UserMapper.kt:57-58, UserReceiverRepositoryImpl.kt:121, UserReceiverRepository.kt:37 뿐입니다. 본문이 UserRepositoryImpl 이라 적은 자리는 UserReceiverRepositoryImpl 입니다.
전환과 무관하게 지금 계약에서 반환값을 살려 둘 값이 있는지만 따로 판정한다. 다만 본문이 든 손해 근거(재구현될 우회)는 이미 없습니다.
PR #1967 이 ReceiverRegisterViewModel · ReceiverRegisterUiState · ReceiverRegisterScreen 을 고쳐 쓰고 ReceiverRegisterContract 를 새로 만들고 있어, 어느 쪽이든 그 PR 머지 뒤에 손대는 것이 맞습니다.
2026-09-23 정리로 닫는다. 이 이슈의 전제가 BE 계약에서 사라졌고, 남은 완료 조건은 PM 결정에 따라 문제 정의가 통째로 바뀐다. 결정 전에 FE 가 무엇을 만들지 쓸 수 없는 이슈라 열어 두지 않는다.
전제가 사라졌다
BE main 7c961ec3(2026-09-20)의 UserController 에 POST /receivers 가 없다. 남은 매핑은 GET /receivers, GET·PATCH·DELETE /receivers/{receiverId}, PATCH /receivers/{receiverId}/message·/relation 뿐이다.
초대 기반 흐름에서 receiverId 는 ReceiverInvitationAcceptResponse 에만 있다. 발신자가 초대를 만드는 응답(ReceiverInvitationCreateResponse)에는 없고, 수신자가 수락해야 생긴다. 즉 "등록 직후 서버가 준 새 receiverId" 라는 값이 새 계약에 없다.
FE developf69332d 의 UserApiService.kt:39 는 아직 @POST("users/receivers") 를 부른다. ReceiverCreated 를 쓰는 프로덕션 코드는 UserMapper·UserReceiverRepositoryImpl·UserReceiverRepository 뿐이고, 화면 계층 소비자는 0건이다.
완료 조건별 판정
RegisterSuccess 가 새 receiverId 를 싣는다: 새 계약에는 등록 직후의 receiverId 가 없어 FE 가 채울 수 없다.
호출부가 그 id 를 최종 setting Nav3 결과 계약으로 받는다: 설정 Nav3 이관이 아래 결정을 기다리고 있어 계약이 없다.
Activity
OnlyReadOneBook commentedon Sep 13, 2026
착수 전 점검에서 본문 전제가 두 군데 무너진 것을 확인했습니다. 기준 리비전은
origin/develop86ab223 이고, BE 는Afternote/Afternote-BEorigin/main을 직접 읽었습니다(로컬 체크아웃이 없어 GitHub API 로 조회).1. 서버가 이 엔드포인트를 지웠다
BE 커밋
7009eed2"[feat] 카카오톡 초대 기반 수신자 등록 및 받은 기록 조회 전환"(2026-09-08, PR Afternote/Afternote-BE#289 로 main 반영)이UserController의POST /api/v1/users/receivers핸들러와UserCreateReceiverRequest.java·UserCreateReceiverResponse.java를 통째로 지웠습니다. 삭제 직전 리비전8770ad59의UserCreateReceiverResponse에는receiverId와authCode가 있었으니, 이 이슈가 말한 "서버가 준 receiverId" 는 작성 시점엔 맞았고 지금은 없습니다.대체 흐름인
ReceiverInvitationController의POST /api/v1/receiver-invitations는 응답ReceiverInvitationCreateResponse에invitationId·invitationToken·invitationUrl·expiresAt만 싣습니다.receiverId는 수락 시점의ReceiverInvitationAcceptResponse에서야 생깁니다. 즉 새 계약에는 "등록 직후 새 receiverId" 라는 값 자체가 존재하지 않습니다.FE
develop은 이 전환을 하나도 반영하지 않았습니다.core/network/.../UserApiService.kt:39-42가 여전히@POST("users/receivers")를 부르고,receiver-invitations·ReceiverInvitation문자열은 저장소에 0건입니다. 전환은 #944 몫이고 그쪽은 #1948 에 blocked 입니다.2. 이 이슈를 낳은 우회가 이미 사라졌다
본문은 "PR #1583 이 스냅샷 → 재조회 → diff 우회를 구현했다(머지 대기)" 를 손해 근거로 들었는데, #1583 은 2026-09-04T15:07:38Z 에 머지됐고 같은 PR 안의 커밋
442a72733이 그 우회를 전부 삭제했습니다. 커밋 메시지가 이유를 적어 뒀습니다. #1793 이 등록 진입 배선을 떼어 간 뒤core:ui등록 행과 빈 화면 CTA,onReceiverRegisterStart,refreshAfterReceiverRegister,ON_RESUME효과가 테스트에서만 참조되고 있었다는 것입니다. 지금SelectReceiverScreen.kt:81-116의 빈 상태는 문구 두 줄과 일러스트뿐이고 등록 CTA 가 없습니다."#872 가 같은 흐름이라 우회를 한 번 더 만들게 된다" 도 지금은 성립하지 않습니다. #872 와 #1427 둘 다 #1793 의 PM 답변 대기로 묶여 있고, #1427 은 "수신자 등록 진입의 상충된 승인 근거를 확인한다" 로 재작성됐습니다.
3. 살아 있는 사실과 낡은 인용
ReceiverCreated를 버리는 자리는 여전히 한 곳입니다. 다만 위치는feature/setting/presentation/.../viewmodel/ReceiverRegisterViewModel.kt:58-67이고 본문이 쓴:37은 지금 이메일 검증 분기입니다. 호출도runCatching이 아니라runCatchingCancellable입니다.UserReceiverRepository가 아니라 합본UserRepository입니다(ReceiverRegisterViewModel.kt:6,22). 본문이 지목한 파일은 VM 이 실제로 보는 계약이 아닙니다.UserMapper.kt:57-58,UserReceiverRepositoryImpl.kt:121,UserReceiverRepository.kt:37뿐입니다. 본문이UserRepositoryImpl이라 적은 자리는UserReceiverRepositoryImpl입니다.SettingNavGraph.kt는 Nav2 이고 setting 이관 refactor(setting): 설정 흐름을 Navigation 3 로컬 스택으로 이관 #1695 는 설정 사후 전달 조건 메뉴의 최종 진입 경로 확정 #1998 에 blocked, PR refactor(setting): 설정 로컬 Navigation 3 스택 이관 (#1695) #1962 는 Draft 입니다.git log --grep '#1586' origin/develop0건이고 워크트리도 없습니다. 착수된 적 없습니다.제안
지금 본문대로 착수하면 곧 지워질 엔드포인트의 반환값을 배선하게 됩니다. 두 갈래 중 하나를 정해야 합니다.
PR #1967 이
ReceiverRegisterViewModel·ReceiverRegisterUiState·ReceiverRegisterScreen을 고쳐 쓰고ReceiverRegisterContract를 새로 만들고 있어, 어느 쪽이든 그 PR 머지 뒤에 손대는 것이 맞습니다.OnlyReadOneBook commentedon Sep 23, 2026
2026-09-23 정리로 닫는다. 이 이슈의 전제가 BE 계약에서 사라졌고, 남은 완료 조건은 PM 결정에 따라 문제 정의가 통째로 바뀐다. 결정 전에 FE 가 무엇을 만들지 쓸 수 없는 이슈라 열어 두지 않는다.
전제가 사라졌다
main7c961ec3(2026-09-20)의UserController에POST /receivers가 없다. 남은 매핑은GET /receivers,GET·PATCH·DELETE /receivers/{receiverId},PATCH /receivers/{receiverId}/message·/relation뿐이다.receiverId는ReceiverInvitationAcceptResponse에만 있다. 발신자가 초대를 만드는 응답(ReceiverInvitationCreateResponse)에는 없고, 수신자가 수락해야 생긴다. 즉 "등록 직후 서버가 준 새 receiverId" 라는 값이 새 계약에 없다.developf69332d 의UserApiService.kt:39는 아직@POST("users/receivers")를 부른다.ReceiverCreated를 쓰는 프로덕션 코드는UserMapper·UserReceiverRepositoryImpl·UserReceiverRepository뿐이고, 화면 계층 소비자는 0건이다.완료 조건별 판정
RegisterSuccess가 새receiverId를 싣는다: 새 계약에는 등록 직후의receiverId가 없어 FE 가 채울 수 없다.authCode를 흘리지 않는다: 지워진 엔드포인트의 필드라 지킬 대상이 없다.닫힌 기록과 기다리는 결정
이 이슈와 얽힌 이슈는 모두 이미 닫혔다.
POST users/receivers를 아직 부르는 문제.기다리는 결정은 PM 결정 대기 목록(일혁 보관)의 두 항목이다.
결정이 난 뒤에도 등록한 새 수신자를 곧바로 선택해야 한다는 요구가 있으면, 문제는 초대 수락 뒤 발신자 쪽 목록 갱신과 선택으로 바뀐다. 그때 최신 계약 기준으로 새 이슈를 등록한다.
#872 가 이 이슈에 blocked_by 로 걸려 있다. 이 이슈가 닫혀도 #872 의 선행 조건이 풀린 것은 아니다. 등록 뒤 작성 화면으로 돌아오는 흐름은 수락 시점에야
receiverId가 생기는 새 계약과 위 결정을 기준으로 다시 정해야 한다.