Skip to content

refactor(setting): 수신자 등록이 서버가 준 receiverId 를 버린다 — 호출부마다 스냅샷 diff 우회가 생긴다 #1586

Closed as not planned

Description

@OnlyReadOneBook

작업 유형

refactor — 동작 변경 없는 구조·책임·경계 개선

주 담당 모듈

setting — 설정

개요

수신자 등록이 서버가 준 새 receiverId 를 받아 놓고 버린다. 그래서 등록 화면을 호출한 쪽이 「방금 만든 수신자가 누구인지」를 알 수 없고, 소비자마다 우회를 따로 만들게 된다.

실측 (origin/develop fc8f32cd5)

도메인 계약에는 이미 반환값이 있다.

// core/domain/.../UserReceiverRepository.kt:31
suspend fun createReceiver(name, relation, phone, email, message): ReceiverCreated

// core/model/.../UserModel.kt:30
data class ReceiverCreated(val receiverId: Long, val authCode: String)

버리는 자리는 ViewModel 한 곳이다.

// 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명에서 등록 후 작성 화면 복귀)가 같은 흐름이라 이 우회를 그대로 한 번 더 만들게 된다.

완료 조건

  1. ReceiverRegisterEvent.RegisterSuccess 가 새 receiverId 를 싣는다(또는 그에 준하는 반환 채널).
  2. 등록 화면 호출부가 그 id 를 결과로 돌려받을 수 있다 — 최종 setting Nav3 entry 결과 계약을 사용하며, 폐기될 Nav2 SavedStateHandle 배선을 먼저 구현하지 않는다.
  3. authCode 는 화면에 노출할 값이 아니므로 id 만 흘린다.

자식 이슈

없음

참고

구현 순서

새 receiverId를 실제 소비하는 #1793의 등록 왕복과 결과 전달을 같은 변경에서 완성한다. 현재 설정 자체의 등록 성공·pop 동작에 소비하지 않는 id 필드나 반환 채널을 미리 추가하지 않는다. #1793에서 스냅샷 비교 우회는 제거했으며, 이 이슈와 함께 확정된 Nav3 경계로만 연결한다.

Activity

  1. added
    refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업
    on Aug 30, 2026
  2. OnlyReadOneBook commented on Sep 13, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    착수 전 점검에서 본문 전제가 두 군데 무너진 것을 확인했습니다. 기준 리비전은 origin/develop 86ab223 이고, BE 는 Afternote/Afternote-BE origin/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 입니다.
    • 완료 조건 2 의 "최종 setting Nav3 entry 결과 계약" 은 아직 없습니다. SettingNavGraph.kt 는 Nav2 이고 setting 이관 refactor(setting): 설정 흐름을 Navigation 3 로컬 스택으로 이관 #1695 는 설정 사후 전달 조건 메뉴의 최종 진입 경로 확정 #1998 에 blocked, PR refactor(setting): 설정 로컬 Navigation 3 스택 이관 (#1695) #1962 는 Draft 입니다.

    git log --grep '#1586' origin/develop 0건이고 워크트리도 없습니다. 착수된 적 없습니다.

    제안

    지금 본문대로 착수하면 곧 지워질 엔드포인트의 반환값을 배선하게 됩니다. 두 갈래 중 하나를 정해야 합니다.

    1. 수신자 등록 카톡 초대 전환 — 이메일 등록·인증 대체 #944 의 초대 기반 전환 뒤로 미루고 이 이슈를 그 후속으로 재작성한다. 새 계약에서 "등록 직후 receiverId" 는 수락 응답으로 옮겨 가므로 문제 정의 자체가 달라집니다.
    2. 전환과 무관하게 지금 계약에서 반환값을 살려 둘 값이 있는지만 따로 판정한다. 다만 본문이 든 손해 근거(재구현될 우회)는 이미 없습니다.

    PR #1967 이 ReceiverRegisterViewModel · ReceiverRegisterUiState · ReceiverRegisterScreen 을 고쳐 쓰고 ReceiverRegisterContract 를 새로 만들고 있어, 어느 쪽이든 그 PR 머지 뒤에 손대는 것이 맞습니다.

  3. OnlyReadOneBook commented on Sep 23, 2026

    @OnlyReadOneBook
    CollaboratorAuthor

    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 develop f69332d 의 UserApiService.kt:39 는 아직 @POST("users/receivers") 를 부른다. ReceiverCreated 를 쓰는 프로덕션 코드는 UserMapper·UserReceiverRepositoryImpl·UserReceiverRepository 뿐이고, 화면 계층 소비자는 0건이다.

    완료 조건별 판정

    1. RegisterSuccess 가 새 receiverId 를 싣는다: 새 계약에는 등록 직후의 receiverId 가 없어 FE 가 채울 수 없다.
    2. 호출부가 그 id 를 최종 setting Nav3 결과 계약으로 받는다: 설정 Nav3 이관이 아래 결정을 기다리고 있어 계약이 없다.
    3. authCode 를 흘리지 않는다: 지워진 엔드포인트의 필드라 지킬 대상이 없다.

    닫힌 기록과 기다리는 결정

    이 이슈와 얽힌 이슈는 모두 이미 닫혔다.

    기다리는 결정은 PM 결정 대기 목록(일혁 보관)의 두 항목이다.

    결정이 난 뒤에도 등록한 새 수신자를 곧바로 선택해야 한다는 요구가 있으면, 문제는 초대 수락 뒤 발신자 쪽 목록 갱신과 선택으로 바뀐다. 그때 최신 계약 기준으로 새 이슈를 등록한다.

    #872 가 이 이슈에 blocked_by 로 걸려 있다. 이 이슈가 닫혀도 #872 의 선행 조건이 풀린 것은 아니다. 등록 뒤 작성 화면으로 돌아오는 흐름은 수락 시점에야 receiverId 가 생기는 새 계약과 위 결정을 기준으로 다시 정해야 한다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:setting설정 기능 영역refactor동작 변경 없이 코드 구조·책임·경계를 개선하는 작업

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions