Skip to content

fix(afternote): 에디터 수신자 목록을 UserRepository 로 연결 — 죽은 AuthorReceiverRepository 제거 (closes 935) [base: develop] - #971

Merged
OnlyReadOneBook merged 3 commits into
developfrom
fix/935
Aug 24, 2026
Merged

OnlyReadOneBook merged 3 commits into
developfrom
fix/935

Conversation

@OnlyReadOneBook

Copy link
Copy Markdown
Collaborator

Closes #935

AuthorReceiverRepositoryImpl 은 currentAuthorUserId() 가 항상 null 이라 refreshReceivers() 가 늘 실패하고 observeReceivers()·currentReceivers() 는 빈 리스트만 반환하는 죽은 구현이었다. 에디터가 이를 프로덕션 경로에서 소비해 신규 작성 시 수신자 목록이 항상 비었고, 수신자 최소 1명이 서버 필수값(475)이라 등록 자체가 막혔다.

같은 기능을 하는 core:domain 의 UserRepository 로 전환한다. 수신자 목록 소비처 7곳이 이미 이것을 쓰고 있었다.

변경

대상 내용
AfternoteEditorViewModel 죽은 flow 구독을 걷고 refreshAuthorReceivers() 가 userRepository.getReceivers() 로 목록을 채운다
EditorReceiverMapping (rename) AuthorReceiverEntry → core:model 의 Receiver 기준으로 재작성, 수신 타입도 호출처에 맞춰 List 로 좁힘
AfternoteFailureReporting AUTHOR_RECEIVER_LOAD 계측 단계 신설
삭제 AuthorReceiverRepository·Impl·AuthorReceiverEntry, DI 바인딩 bindAuthorReceiverRepository
androidTest 전용 Fake 3종 → 공용 FakeUserRepository

조회 실패는 삼키지 않고 계측하며, runCatchingCancellable 로 취소는 보존한다.

userId 를 폐기한 근거

GET users/receivers 는 파라미터가 없고 서버가 액세스 토큰으로 호출자를 식별한다. 실제로 userId 는 코드베이스 어디에도 저장되지 않는다 — main 소스 전체에서 userId 는 8곳뿐이고 전부 회원가입 응답 경로(AuthDto → AccountRegistration → AuthMapper)와 이 죽은 Impl 이다. TODO 가 안 풀린 건 채울 소스가 없어서가 아니라 채울 필요가 없어서였다.

검증

항목 결과
:feature:afternote:{presentation,data}:compileDebugKotlin BUILD SUCCESSFUL
:app:compileDebugKotlin · :app:compileDebugUnitTestKotlin BUILD SUCCESSFUL
:app:assembleDebug BUILD SUCCESSFUL
ktlintCheck 통과
:app:testDebugUnitTest + afternote presentation·data 전부 통과
:app:compileDebugAndroidTestKotlin 44건 실패 — origin/develop 기준선과 오류 집계가 완전히 동일(파일별 수치까지 일치). 이 브랜치가 추가한 오류 0건이며, 기존 드리프트는 #949 가 처리 중

에뮬레이터 실측 (2026-08-24 02:43~02:45 KST, Pixel_7_Claude_QA)

노트 탭 → FAB → 소셜네트워크 에디터 진입 시:

--> GET https://afternote.kro.kr/api/v1/users/receivers
Authorization: ██
--> END GET
<-- HTTP FAILED: java.net.SocketTimeoutException (10011ms)

미확인: 응답 목록이 replaceReceiversIfEmpty 로 폼에 실제로 채워지는지. dev 서버가 02:45 시점에 이미 무응답이라(메모리상 폐쇄 시간대 03~12시보다 이르게 닫힘) 응답 데이터 검증은 서버 복구 후로 남는다.

시각 검증

시각 변경 없음 — 변경 파일이 ViewModel·매퍼·DI·내비게이션 로직뿐이고 Compose 본문·디자인 토큰·리소스·screenshotTest 커버 대상은 건드리지 않는다. baseline 사이클 skip.

리뷰어에게

…pository 제거

AuthorReceiverRepositoryImpl 은 currentAuthorUserId() 가 항상 null 이라
refreshReceivers() 가 늘 실패하고 observeReceivers()·currentReceivers() 는
빈 리스트만 반환하는 죽은 구현이었다. 에디터가 이를 프로덕션 경로에서 소비해
신규 작성 시 수신자 목록이 항상 비었고, 수신자 최소 1명이 서버 필수값(475)이라
등록 자체가 막혔다.

같은 기능을 하는 core:domain 의 UserRepository 로 전환한다. GET users/receivers
는 파라미터가 없고 서버가 액세스 토큰으로 호출자를 식별하므로 userId 개념 자체가
불필요하다 — 코드베이스 어디에도 저장되지 않던 값이다.

- AfternoteEditorViewModel: 죽은 flow 구독을 걷고 refreshAuthorReceivers() 가
  userRepository.getReceivers() 로 목록을 채운다. 조회 실패는 삼키지 않고
  AUTHOR_RECEIVER_LOAD 단계로 계측하며, runCatchingCancellable 로 취소는 보존한다
- AuthorReceiverEntry 를 core:model 의 Receiver 로 통합하고 매퍼를
  EditorReceiverMapping 으로 옮긴다 (수신 타입도 호출처에 맞춰 List 로 좁힘)
- AuthorReceiverRepository·Impl·Entry 와 DI 바인딩 삭제, androidTest 전용 Fake
  3종은 공용 FakeUserRepository 로 교체

수신자 선택 화면 라우팅(#540)은 #791 선행이 남아 별건이다.
@OnlyReadOneBook

Copy link
Copy Markdown
Collaborator Author

실서버 QA 완료 — 미검증으로 남겨 뒀던 항목 해소 (2026-08-24 13:22~13:32 KST)

PR 본문에 "서버 복구 후로 남는다" 고 적어 둔 응답 데이터 검증을 마쳤다. 커밋 9434cff7 APK, AVD Pixel_7_Claude_QA, QA823 계정.

1. 수신자 목록이 실제로 폼에 채워진다

GET /api/v1/users/receivers → 200

{"status":200,"code":200,"message":"성공","data":[{"receiverId":14,"name":"QA수신자","relation":"DAUGHTER","authCode":"683fec31-..."}]}

노트 탭 → FAB → 소셜네트워크 에디터 진입 시 "수신자 추가" 섹션에 QA수신자 / DAUGHTER 행이 렌더됐다. 새벽 1차 실측에서 비어 있던 자리다. refreshAuthorReceivers() → getReceivers() → replaceReceiversIfEmpty 경로가 실동작한다.

2. 저장까지 완주 — 475 데드엔드가 실제로 풀린다

서비스명(인스타그램)·계정정보·처리방법을 채우고 등록:

POST /api/v1/afternotes
{"category":"SOCIAL","title":"인스타그램","actions":["delete account"],
 "credentials":{"id":"qa935_dummy_id","password":"qa935_dummy_pw"},
 "receivers":[{"receiverId":14}]}
<-- 200

receivers 에 receiverId: 14 가 실려 나갔고 응답 200. 목록에 인스타그램 / 최종 작성일 2026.08.24 생성 확인. #540 이 P0 로 추적하던 "수신자를 지정할 수 없어 등록이 막힌다" 는 증상이 신규 작성 경로에서 해소됐다.

부수 확인 — 화면의 DAUGHTER 는 결함이 아니다

스크린샷에서 관계가 영문으로 보이길래 확인했는데, BE Receiver.relation 이 private String 자유 문자열이고 enum 정규화가 없다(Swagger example = "DAUGHTER" 는 예시일 뿐). 앱 등록 화면 선택지는 한글("어머니","아버지","아들","딸")이고 설정·타임레터도 relation 을 그대로 표시한다. QA 수신자를 curl 로 만들 때 영문이 들어간 데이터 탓이다.

여전히 남는 것

"수신자 추가" + 버튼은 그대로 무동작이다 — 선택 화면 라우팅은 #540 이고 #791 선행이 남아 이 PR 범위 밖이다. 이 PR 이 푸는 것은 "수신자 전원 자동 지정 → 저장 가능" 까지다.

증거 대장: .codex/qa-evidence/emulator/9434cff751927d36117b27f8d58c6bd986d801f4.json (result: pass 로 갱신)

#1005(추모 미디어 업로드 경로 통합)가 먼저 develop 에 들어가 사진 전용
MemorialPhotoUpload* 가 MemorialMediaUpload* 로 바뀌었고, 이 브랜치는
AuthorReceiverRepository 를 지우고 UserRepository 로 갈아끼우는 쪽이라
DI 모듈 import 가 양쪽에서 갈렸다. 남는 쪽(MediaUpload)만 두고 지워진
쪽(PhotoUpload·AuthorReceiver) 은 모두 뺀다.

androidTest editorViewModel() 헬퍼는 develop 의 itemId(Long) 형태를 취한다 —
#949 가 String→Long 드리프트를 고친 결과이고 같은 파일의 다른 호출부도
Long 이다. 수신자 주입만 이 브랜치의 FakeUserRepository 로 남긴다.

:app:compileDebugUnitTestKotlin 통과. androidTest 오류 21건은 develop 에서
그대로 물려받은 것으로 오류 집합이 develop 과 동일하다.
@OnlyReadOneBook
OnlyReadOneBook merged commit af3f461 into develop Aug 24, 2026
12 of 13 checks passed
@OnlyReadOneBook
OnlyReadOneBook deleted the fix/935 branch August 24, 2026 09:35
@github-actions

Copy link
Copy Markdown
Contributor

🚀 QA 배포 권장

QA 포인트

이 판단은 배포를 자동 실행하지 않습니다. deploy일 때 Release Distribution을 수동 실행하세요.

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.

AuthorReceiverRepository 가 동작하지 않음 — 에디터 수신자 목록이 항상 빈 리스트

2 participants