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
#470의 구독 유도 화면에서 구독 후 기록하기를 눌러도 현재는 팝업만 닫히며 실제 상품 조회, 구매, 복원, 서버 권한 동기화가 없습니다.
BE #223은 현재 플랜·타임레터 한도와 provider-neutral entitlement 경계를 제공하고, Afternote/Afternote-BE#224는 Google Play 구매 검증·RTDN을 담당합니다. Android 앱은 Google Play Billing으로 구매를 시작하되, 클라이언트 결과만으로 권한을 부여하지 않고 서버 검증 결과를 다시 조회해야 합니다.
08-23 회의에서 Play스토어 인앱 결제 수수료 30%를 이유로 외부 결제 경로 검토가 시작됐습니다(회의록: "수수료 사이트 플레이스토어 30프로인데 결제 사이트 알아보기" — PM 액션).
이 이슈는 Google Play Billing 전제이고 "대체 결제와 외부 결제 프로그램"을 제외 범위로 못박고 있어, 결제 경로 결론에 따라 전제가 바뀔 수 있습니다. 착수 전 PM 결론 확인 필요 — BE 측 전제(Afternote/Afternote-BE#224 Google Play 검증·RTDN)도 같은 영향권입니다.
참고: 구독 상품이 아니라 기록 책 인쇄 같은 단건 결제는 BM 문서 기준 실물 상품이라 Play Billing 의무 대상이 아니므로, 외부 결제 검토가 구독에 적용될지 단건에 적용될지도 결론에서 갈립니다.
기준은 origin/develop7d87aa3f 와 GitHub API 실조회입니다. 결론부터 적으면, 지금 이 이슈에서 코드로 뗄 수 있는 독립 범위가 없습니다. 완료 조건 두 항목이 모두 블로커 산출물에서 나오는데 셋 다 열려 있고, BE 쪽은 미배포가 아니라 코드 부재입니다. 다만 develop 실코드가 본문 전제와 어긋나는 지점이 있어 그것을 남깁니다.
Afternote-BEmain(3593aa30) 트리를 전수로 훑으면 파일 482건 중 subscription, entitlement, billing, purchase, plan 이 이름에 들어가는 파일 0건입니다.
BE 열린 PR 0건입니다.
유일한 구현 브랜치 1hyok/feat/223-entitlement-foundation 은 main 대비 3 커밋 앞, 66 커밋 뒤이고 마지막 커밋이 85abc9cb(2026-08-22 18:19 UTC)입니다. 담긴 파일은 SubscriptionEntitlementEvent.java, UserEntitlement.java, EntitlementEventServiceTest.java 셋뿐이라 컨트롤러가 없습니다.
그래서 선행 조건 1번(GET /api/v1/subscriptions/me 병합·배포)과 2번(검증 API 내부 테스트 환경 사용 가능)은 근거를 연결할 대상 자체가 아직 없습니다. 완료 조건 1번의 "준비 근거 연결" 과 2번의 "확정 계약 기준 범위 확정" 도 같은 산출물이 원천이라, 항목을 쪼개도 지금 닫히는 게 없습니다.
2. develop 실측: "BE 계약이 오면 조회만 갈아끼우면 된다" 는 전제가 틀렸습니다
무료 한도 게이트가 세는 축이 BE#223 확정 정책과 다릅니다. 값만 바꾸는 문제가 아니라 판정 주체를 걷어내야 하는 문제입니다.
게이트는 TimeLetterWriteViewModel.kt:172-186 이고 상수는 같은 파일 :708 의 FREE_PLAN_REGISTER_LIMIT = 3 입니다. 세는 값의 출처는 timeLetterRepository.getTimeLetters().totalCount 인데, 그 엔드포인트는 TimeLetterApiService.kt:18-20 주석대로 SCHEDULED 목록입니다. 즉 FE 가 세는 것은 "지금 SCHEDULED 로 남아 있는 건수" 이지 달력월 누적이 아닙니다.
TimeletterViewModel.kt:82-98 에서 등록건 삭제가 성공하면 load() 가 목록을 다시 읽으므로 카운트가 줄고, 무료 슬롯이 로컬에서 되살아납니다. BE#223 의 "삭제하거나 DRAFT 로 되돌려도 이미 사용한 월 등록 건수는 복구하지 않습니다" 와 정면으로 어긋납니다.
구독 중 등록분도 월 사용량에 기록한다는 BE 규칙 역시 잔존 건수 축으로는 표현되지 않습니다.
결과적으로 이 게이트를 그대로 두고 서버 계약만 붙이면, 같은 사용자에게 클라이언트 판정과 서버 403 / 2800 이 서로 다른 답을 냅니다.
한 가지는 우연히 맞습니다. 게이트가 originalEditingStatus != SCHEDULED 일 때만 검사하므로, 기존 SCHEDULED 수정은 재차감하지 않는다는 BE 규칙과 결과가 같습니다.
develop 전체에서 FREE_PLAN, freePlanLimit 을 grep 하면 걸리는 파일이 feature/timeletter 5개뿐이고, feature/afternote 와 feature/home 에는 한도 게이트도 구독 팝업도 0건입니다(두 모듈의 "구독" 문자열은 전부 Flow 구독 관련 주석입니다). 본문의 "구매 후 복귀" 질문을 정할 때, 현재 코드 기준 복귀 지점이 하나라는 것을 전제로 놓아야 합니다.
4. core 는 선행 작업이 없고, Play Billing 의존성도 없습니다
core/network 는 이미 준비돼 있습니다. ApiErrorCallAdapterFactory.kt:115-134 가 HTTP 400..599 본문의 code 를 그대로 실어 ApiException(status, code, serverMessage, fallbackMessage) 로 올리므로, 2800 식별에 core 변경이 필요 없습니다.
gradle/libs.versions.toml 에 Play Billing 의존성이 없습니다(play 매치는 credentials-play-services-auth 하나뿐). develop 전체에서 billing, subscription, entitlement 는 프로덕션·설정 코드 0건이고, 생성물인 baseline profile 의 Compose 클래스명만 걸립니다. "이미 부분적으로 돼 있는가" 는 아니오입니다.
5. 이 이슈를 무는 열린 PR 은 없습니다
열린 PR 62건 본문을 전수로 훑어 881 이 걸린 것은 #2008 하나인데, 그마저 커밋 SHA fc881bf... 안의 우연한 문자열이라 Closes 가 아닙니다. 타임레터를 만지는 #1365(base develop)도 TimeLetterWriteViewModel.kt 를 수정하지만 diff 에 한도 게이트·구독 관련 변경은 0건입니다. 다만 그 PR 이 병합되면 위 줄 번호는 밀리므로, 인용은 7d87aa3f 기준으로 읽어 주세요.
본문에서 고쳐야 할 전제
본문은 아직 고치지 않았습니다. 완료 조건을 좁히는 편집이 아니라 서술 정정이라, 아래 네 가지를 기록으로만 남깁니다.
"BE #223은 현재 플랜·타임레터 한도와 provider-neutral entitlement 경계를 제공하고" 는 현재형으로 쓰여 있지만 제공되고 있지 않습니다. 근거는 위 1번입니다.
본문과 BE#223 의 무료 한도는 KST 달력월 3건인데 develop 게이트는 잔존 SCHEDULED 건수를 셉니다. 본문이 이 차이를 반영하지 않아, 읽는 사람이 "조회 API 만 갈아끼우면 되는 작업" 으로 오해할 여지가 있습니다. 근거는 위 2번입니다.
"#470의 구독 유도 화면" 이 가리키는 대상이 바뀌었습니다. 등록 한도 도달 시 구독 유도·구매 후 복귀를 PM에게 확인한다 #470 은 2026-09-13 정리로 미확정 구현 예약을 걷어낸 PM 확인 이슈가 됐습니다. 실제 유도 팝업 코드는 feature/timeletter 에 있고, 그 버튼이 갈 구독·결제 화면은 시안에도 없습니다. 본문에 없는 세 번째 게이트인데 #470 의 2026-08-31 코멘트에만 기록돼 있습니다. 정본 페이지 TEXT 6,482건 전수에서 990, 무제한, 결제, subscription, billing 이 각 0건이고, 선행 조건 3번의 1안 4327:66610 과 2안 4327:66687 은 둘 다 살아 있어 정본도 아직 안 갈렸습니다.
Google Play Billing 전제는 아직 확정이 아닙니다. 위 08-23 코멘트의 외부 결제 경로 재검토가 결론나지 않았습니다. 여기서 다시 논하지는 않고, 전제가 열려 있다는 사실만 표시해 둡니다.
다음 착수자에게
BE#223 이 병합·배포돼도 이 이슈는 바로 열리지 않습니다. 구독·결제 목적지 화면이 시안에 없고(위 3번), 한도 판정 주체를 FE 에서 걷어내는 작업이 별도로 필요합니다(위 2번). BE 대기와 병렬로 먼저 풀 수 있는 것은 시안 요청 쪽이고, 그건 #470 이 추적합니다.
Activity
1hyok commentedon Aug 23, 2026
08-23 회의에서 Play스토어 인앱 결제 수수료 30%를 이유로 외부 결제 경로 검토가 시작됐습니다(회의록: "수수료 사이트 플레이스토어 30프로인데 결제 사이트 알아보기" — PM 액션).
이 이슈는 Google Play Billing 전제이고 "대체 결제와 외부 결제 프로그램"을 제외 범위로 못박고 있어, 결제 경로 결론에 따라 전제가 바뀔 수 있습니다. 착수 전 PM 결론 확인 필요 — BE 측 전제(Afternote/Afternote-BE#224 Google Play 검증·RTDN)도 같은 영향권입니다.
참고: 구독 상품이 아니라 기록 책 인쇄 같은 단건 결제는 BM 문서 기준 실물 상품이라 Play Billing 의무 대상이 아니므로, 외부 결제 검토가 구독에 적용될지 단건에 적용될지도 결론에서 갈립니다.
[-]feat(subscription): Google Play Billing 구매·복원 및 구독 화면 연결[/-][+]Google Play Billing 구매·복원 및 구독 화면 연결[/+][-]Google Play Billing 구매·복원 및 구독 화면 연결[/-][+]Google Play 구매·복원 구현에 필요한 서버·상품·화면 계약을 확인한다[/+]1hyok commentedon Sep 13, 2026
착수 가능 여부 재실측 (2026-09-13)
기준은
origin/develop7d87aa3f와 GitHub API 실조회입니다. 결론부터 적으면, 지금 이 이슈에서 코드로 뗄 수 있는 독립 범위가 없습니다. 완료 조건 두 항목이 모두 블로커 산출물에서 나오는데 셋 다 열려 있고, BE 쪽은 미배포가 아니라 코드 부재입니다. 다만 develop 실코드가 본문 전제와 어긋나는 지점이 있어 그것을 남깁니다.1. 블로커 3건은 항목별로 따져도 전부 미충족
blocked_by 에 #470, Afternote/Afternote-BE#223, Afternote/Afternote-BE#224 셋이 걸려 있고 전부 OPEN 입니다.
BE 쪽은 "병합은 됐는데 배포가 안 됐다" 가 아니라 코드가 없는 상태입니다.
Afternote-BEmain(3593aa30) 트리를 전수로 훑으면 파일 482건 중 subscription, entitlement, billing, purchase, plan 이 이름에 들어가는 파일 0건입니다.1hyok/feat/223-entitlement-foundation은 main 대비 3 커밋 앞, 66 커밋 뒤이고 마지막 커밋이85abc9cb(2026-08-22 18:19 UTC)입니다. 담긴 파일은SubscriptionEntitlementEvent.java,UserEntitlement.java,EntitlementEventServiceTest.java셋뿐이라 컨트롤러가 없습니다.그래서 선행 조건 1번(
GET /api/v1/subscriptions/me병합·배포)과 2번(검증 API 내부 테스트 환경 사용 가능)은 근거를 연결할 대상 자체가 아직 없습니다. 완료 조건 1번의 "준비 근거 연결" 과 2번의 "확정 계약 기준 범위 확정" 도 같은 산출물이 원천이라, 항목을 쪼개도 지금 닫히는 게 없습니다.2. develop 실측: "BE 계약이 오면 조회만 갈아끼우면 된다" 는 전제가 틀렸습니다
무료 한도 게이트가 세는 축이 BE#223 확정 정책과 다릅니다. 값만 바꾸는 문제가 아니라 판정 주체를 걷어내야 하는 문제입니다.
TimeLetterWriteViewModel.kt:172-186이고 상수는 같은 파일:708의FREE_PLAN_REGISTER_LIMIT = 3입니다. 세는 값의 출처는timeLetterRepository.getTimeLetters().totalCount인데, 그 엔드포인트는TimeLetterApiService.kt:18-20주석대로 SCHEDULED 목록입니다. 즉 FE 가 세는 것은 "지금 SCHEDULED 로 남아 있는 건수" 이지 달력월 누적이 아닙니다.TimeletterViewModel.kt:82-98에서 등록건 삭제가 성공하면load()가 목록을 다시 읽으므로 카운트가 줄고, 무료 슬롯이 로컬에서 되살아납니다. BE#223 의 "삭제하거나 DRAFT 로 되돌려도 이미 사용한 월 등록 건수는 복구하지 않습니다" 와 정면으로 어긋납니다.2800이 서로 다른 답을 냅니다.originalEditingStatus != SCHEDULED일 때만 검사하므로, 기존 SCHEDULED 수정은 재차감하지 않는다는 BE 규칙과 결과가 같습니다.팝업 확인 버튼은 여전히 닫기만 합니다.
TimeLetterNavGraph.kt:89-92에// TODO: 구독 화면 및 관련 플로우 구현 시 구독 화면 이동으로 변경이 남아 있고, 문구는TimeLetterWriteScreen.kt:456-466입니다.3. 진입점은 코드상 한 곳뿐입니다
develop 전체에서
FREE_PLAN,freePlanLimit을 grep 하면 걸리는 파일이feature/timeletter5개뿐이고,feature/afternote와feature/home에는 한도 게이트도 구독 팝업도 0건입니다(두 모듈의 "구독" 문자열은 전부 Flow 구독 관련 주석입니다). 본문의 "구매 후 복귀" 질문을 정할 때, 현재 코드 기준 복귀 지점이 하나라는 것을 전제로 놓아야 합니다.4. core 는 선행 작업이 없고, Play Billing 의존성도 없습니다
core/network는 이미 준비돼 있습니다.ApiErrorCallAdapterFactory.kt:115-134가 HTTP 400..599 본문의code를 그대로 실어ApiException(status, code, serverMessage, fallbackMessage)로 올리므로,2800식별에 core 변경이 필요 없습니다.gradle/libs.versions.toml에 Play Billing 의존성이 없습니다(play매치는credentials-play-services-auth하나뿐). develop 전체에서 billing, subscription, entitlement 는 프로덕션·설정 코드 0건이고, 생성물인 baseline profile 의 Compose 클래스명만 걸립니다. "이미 부분적으로 돼 있는가" 는 아니오입니다.5. 이 이슈를 무는 열린 PR 은 없습니다
열린 PR 62건 본문을 전수로 훑어
881이 걸린 것은 #2008 하나인데, 그마저 커밋 SHAfc881bf...안의 우연한 문자열이라 Closes 가 아닙니다. 타임레터를 만지는 #1365(base develop)도TimeLetterWriteViewModel.kt를 수정하지만 diff 에 한도 게이트·구독 관련 변경은 0건입니다. 다만 그 PR 이 병합되면 위 줄 번호는 밀리므로, 인용은7d87aa3f기준으로 읽어 주세요.본문에서 고쳐야 할 전제
본문은 아직 고치지 않았습니다. 완료 조건을 좁히는 편집이 아니라 서술 정정이라, 아래 네 가지를 기록으로만 남깁니다.
feature/timeletter에 있고, 그 버튼이 갈 구독·결제 화면은 시안에도 없습니다. 본문에 없는 세 번째 게이트인데 #470 의 2026-08-31 코멘트에만 기록돼 있습니다. 정본 페이지 TEXT 6,482건 전수에서 990, 무제한, 결제, subscription, billing 이 각 0건이고, 선행 조건 3번의 1안4327:66610과 2안4327:66687은 둘 다 살아 있어 정본도 아직 안 갈렸습니다.다음 착수자에게
BE#223 이 병합·배포돼도 이 이슈는 바로 열리지 않습니다. 구독·결제 목적지 화면이 시안에 없고(위 3번), 한도 판정 주체를 FE 에서 걷어내는 작업이 별도로 필요합니다(위 2번). BE 대기와 병렬로 먼저 풀 수 있는 것은 시안 요청 쪽이고, 그건 #470 이 추적합니다.
1hyok commentedon Sep 18, 2026
PM 결정 대기 항목은 깃허브 이슈로 두지 않고 피그마 질문 한 자리에만 둔다(2026-09-18 결정). 이 이슈의 질문은 피그마 스레드에 걸려 있다: https://www.figma.com/design/UP9ZR186jHvRBicjA2SOea/?node-id=4823-17385#1932508488 답이 오면 그 답을 근거로 구현 이슈를 새로 만든다.