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
enhancement(afternote): 애프터노트 상세를 App Link 목적지로 연다 #2088
App Link 계약에 애프터노트 상세 /afternote/{id} 를 더하고, 브라우저에서 온 그 링크가 지문 관문 뒤 상세 화면에 서게 한다.
왜 지금은 없나
#924 가 세우는 계약은 목적지 다섯 개만 받는다. 상세는 계약에서 뺐고 intent-filter 에서도 그 경로를 잡지 않으며, 파서 테스트가 그 상태를 못으로 박았다. AfternoteAppLinkParserTest 의 "애프터노트 상세 경로는 아직 목적지가 아니다" 가 /afternote/42 를 AppLinkRejectionReason.UNKNOWN_PATH 거절로 고정한다. 도착할 자리가 없는 경로를 계약에만 실으면 링크가 앱을 열고 홈으로 떨어지는 반쪽 활성화가 되는데, #924 본문이 그것을 머지하지 말라고 못 박아 뒀다.
자리가 없는 이유는 애프터노트 피처의 로컬 Navigation 3 스택이다. AfternoteNavHost 가 rememberNavBackStack(AfternoteRoute.FingerprintLoginRoute) 로 스택 바닥을 지문 관문에 고정하고, 밖에서 상세를 지목해 넣을 인자가 없다. 그 파일을 고쳐야 자리가 열린다.
해야 할 것
AfternoteNavHost 가 초기 엔트리를 받는다. 바닥이 지문 관문이라는 성질은 유지하고, 관문을 지난 뒤 상세가 그 위에 얹히게 한다. 관문을 건너뛰는 경로를 새로 만들지 않는다.
NavigationTarget 에 상세 목적지를 더한다. requiredGates 는 LOGIN 과 BIOMETRIC 이고, 정규 경로는 /afternote/{id}, ID 형식은 타임레터 상세와 같은 양의 10진 정수다.
파서 계약 표에 그 행을 더하고, 지금 거절을 고정한 테스트를 해석되는 쪽으로 뒤집는다. 잘못된 ID 거절은 타임레터 상세와 같은 기준으로 남긴다.
manifest intent-filter 에 pathPrefix="/afternote/" 를 더한다. 기존 path="/afternote" 와 겹치지 않는다. 한 요소에 속성을 묶지 않는 규칙(IntentFilterUniqueDataAttributes)을 지킨다.
앱 루트의 navigator adapter(AppState.navigateToAppLinkTarget)가 그 목적지를 배선한다. 애프터노트 탭은 navigateToBottomBarRoute 가 restoreState 를 끄는 유일한 라우트다. 저장된 스택으로 복원되어 지문 관문을 건너뛰는 일이 없어야 한다는 이 성질을 깨지 않는다.
순서 제약
AfternoteNavHost 를 열린 PR 세 건이 물고 있다. #2021(#1968), #2001(#1999), #1962(#1695). #924 가 이 목적지를 범위에서 뺀 이유 절반이 그것이다. 셋의 이슈를 blocked_by 로 걸어 둔다.
완료 조건
/afternote/{id} 가 목적지로 해석되고, ID 형식 거절과 정규 URL 왕복이 단위 테스트에 있다.
지문 관문을 통과한 뒤에만 상세가 열린다. 관문 앞에서는 목적지를 들고 대기했다가 통과 후 한 번만 재개한다.
링크로 들어온 애프터노트 탭이 저장된 스택을 복원해 관문을 건너뛰지 않는다. 이 성질을 고정하는 테스트가 있다.
#924의 PR #2093(c896a857559ddd0ca82ee57e1fd12936584bb97a)에만 현재 NavigationTarget, AppLinkIntentContract, MainViewModel pending 목적지, AppState.navigateToAppLinkTarget 배선이 있습니다. 현재 parser와 manifest는 /afternote/42를 여전히 계약 밖으로 남깁니다. #2087의 새 기기 실측에서도 이 주소는 Chrome으로 열립니다.
애프터노트의 최종 로컬 스택 소비는 #1968의 PR #2021(b13a7026e312c037edfd223b089b50817faee640)이 변경하며, 상세·홈의 Intent/Effect 소비를 포함합니다. 기존 develop의 직접 ViewModel 소비를 기준으로 초기 상세 진입을 구현하면 이 최종 소비 흐름으로 다시 연결해야 합니다. #1999와 #1695는 CLOSED지만 #924와 #1968은 여전히 OPEN입니다.
두 선행 PR은 각각 자신의 현재 base에서 독립적으로 리뷰·병합될 수 있도록 유지합니다. 어느 한쪽 PR을 다른 쪽에 새로 종속시키거나 후속 diff에 선행 전체를 중복 노출하지 않습니다. 선행 두 결과가 함께 있는 실제 base가 준비되면 이 이슈의 확정된 양의 정수 ID, LOGIN+BIOMETRIC 관문, 1회 재개, restoreState=false 조건을 한 소비 흐름으로 구현할 수 있습니다. 지금 파서만 먼저 열거나 미래 목적지 타입만 추가하는 변경은 만들지 않습니다.
#924 와 같은 이유로 보류해 닫는다. 애프터노트 상세 경로는 ID 를 싣는데, 그 ID 가 무엇인지는 링크를 만드는 쪽이 정한다. 서버에 App Link 발급처가 없고 Afternote/Afternote-BE#261 도 결정 전이라 #2093 을 머지하지 않고 닫았다. 결정이 나면 그 계약으로 다시 연다.
Activity
1hyok commentedon Sep 20, 2026
2026-09-20 실제 선행 코드 기준으로 착수 경계를 다시 확인했습니다.
#924의 PR #2093(
c896a857559ddd0ca82ee57e1fd12936584bb97a)에만 현재 NavigationTarget, AppLinkIntentContract, MainViewModel pending 목적지, AppState.navigateToAppLinkTarget 배선이 있습니다. 현재 parser와 manifest는/afternote/42를 여전히 계약 밖으로 남깁니다. #2087의 새 기기 실측에서도 이 주소는 Chrome으로 열립니다.애프터노트의 최종 로컬 스택 소비는 #1968의 PR #2021(
b13a7026e312c037edfd223b089b50817faee640)이 변경하며, 상세·홈의 Intent/Effect 소비를 포함합니다. 기존 develop의 직접 ViewModel 소비를 기준으로 초기 상세 진입을 구현하면 이 최종 소비 흐름으로 다시 연결해야 합니다. #1999와 #1695는 CLOSED지만 #924와 #1968은 여전히 OPEN입니다.두 선행 PR은 각각 자신의 현재 base에서 독립적으로 리뷰·병합될 수 있도록 유지합니다. 어느 한쪽 PR을 다른 쪽에 새로 종속시키거나 후속 diff에 선행 전체를 중복 노출하지 않습니다. 선행 두 결과가 함께 있는 실제 base가 준비되면 이 이슈의 확정된 양의 정수 ID, LOGIN+BIOMETRIC 관문, 1회 재개, restoreState=false 조건을 한 소비 흐름으로 구현할 수 있습니다. 지금 파서만 먼저 열거나 미래 목적지 타입만 추가하는 변경은 만들지 않습니다.
1hyok commentedon Sep 26, 2026
#924 와 같은 이유로 보류해 닫는다. 애프터노트 상세 경로는 ID 를 싣는데, 그 ID 가 무엇인지는 링크를 만드는 쪽이 정한다. 서버에 App Link 발급처가 없고 Afternote/Afternote-BE#261 도 결정 전이라 #2093 을 머지하지 않고 닫았다. 결정이 나면 그 계약으로 다시 연다.