feat(release): prepare 1.1.0 candidate
This commit is contained in:
parent
5a34f66981
commit
5205dcdfa9
736 changed files with 115667 additions and 12203 deletions
255
docs/v3/play/03-app-content-draft.md
Normal file
255
docs/v3/play/03-app-content-draft.md
Normal file
|
|
@ -0,0 +1,255 @@
|
|||
# App content 답변 초안
|
||||
|
||||
## 1. 광고
|
||||
|
||||
| 질문 | 입력안 | 근거 |
|
||||
| ----------------------- | ------ | ------------------------------------------------------------------------------------ |
|
||||
| 앱에 광고가 포함되는가? | **예** | Free 사용자를 위한 AdMob adaptive banner와 사용자가 직접 실행하는 rewarded ad가 있음 |
|
||||
|
||||
콘솔 메모:
|
||||
|
||||
```text
|
||||
D3RO Voice uses Google AdMob banner ads for eligible Free-plan users and offers an optional rewarded ad that grants non-transferable in-app AI usage credits only after server-side verification. Paid entitlements do not request ads.
|
||||
```
|
||||
|
||||
코드 근거:
|
||||
|
||||
- 광고 eligibility는 로그인 사용자이며 최신 entitlement가 `free`이고 ad-free가 아닐 때만 성립: `apps/mobile-rn/src/lib/mobile-ads-context.tsx:65-80`
|
||||
- UMP 동의 결과가 광고 요청을 허용한 뒤 SDK 초기화: `apps/mobile-rn/src/lib/mobile-ads-context.tsx:89-137`
|
||||
- banner는 비개인화 요청: `apps/mobile-rn/src/components/FreeTierBanner.tsx:44-73`
|
||||
- rewarded ad는 사용자가 실행하고 SSV user ID/custom data를 설정: `apps/mobile-rn/src/lib/mobile-ads-context.tsx:216-240`
|
||||
|
||||
## 2. Advertising ID
|
||||
|
||||
| 질문 | 입력안 | 상태 |
|
||||
| ------------------------------------------------- | -------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 앱 또는 포함된 SDK가 Advertising ID를 사용하는가? | **예** | **후보/사실상 필수**. Google Mobile Ads SDK가 release manifest에 `com.google.android.gms.permission.AD_ID`를 병합할 수 있음 |
|
||||
| 사용 목적 | 광고 또는 마케팅, 분석, 사기 방지·보안 | Google Mobile Ads 공식 disclosure와 맞춤 |
|
||||
|
||||
제출 직전 release merged manifest에서 아래를 다시 캡처한다.
|
||||
|
||||
```text
|
||||
com.google.android.gms.permission.AD_ID
|
||||
android.permission.ACCESS_ADSERVICES_AD_ID
|
||||
android.permission.ACCESS_ADSERVICES_ATTRIBUTION
|
||||
android.permission.ACCESS_ADSERVICES_TOPICS
|
||||
```
|
||||
|
||||
소스 manifest에 직접 보이지 않더라도 SDK library manifest에서 병합될 수 있다. E2E merged manifest에는 위 항목이 확인됐지만, Console 선언은 **최종 production AAB** 기준으로 확정한다.
|
||||
|
||||
## 3. 앱 액세스
|
||||
|
||||
### Console 선택
|
||||
|
||||
`앱 기능의 전체 또는 일부가 로그인, 멤버십, 위치 또는 다른 형태의 인증으로 제한됨`을 선택한다. D3RO Voice의 핵심 기능은 Supabase 계정 로그인이 필요하다.
|
||||
|
||||
실제 reviewer credential은 저장소나 release note에 넣지 않고 Play Console의 App access 필드에만 저장한다. 아래 placeholder를 실계정으로 교체한다.
|
||||
|
||||
### Credential set A — Free/ads path
|
||||
|
||||
```text
|
||||
Name: D3RO Voice reviewer — Free plan
|
||||
Username/email: <PLACEHOLDER_PLAY_REVIEWER_FREE_EMAIL>
|
||||
Password: <PLACEHOLDER_PLAY_REVIEWER_FREE_PASSWORD>
|
||||
|
||||
Instructions (English):
|
||||
1. Launch D3RO Voice. On a fresh install, complete the onboarding screens and choose the existing-account sign-in path.
|
||||
2. Choose email/password sign-in. Do not use Google OAuth.
|
||||
3. Enter the reusable credentials above. No OTP, 2-step verification, location restriction, or expiring password is required.
|
||||
4. This account is on the Free plan with sufficient quota. It can access recording, import, transcription, Talk, meetings, templates, knowledge, teams, banner ads, rewarded ads, privacy options, data export, and account settings.
|
||||
5. To review rewarded ads, open the plan/paywall screen and use the rewarded-ad control. Credits appear only after server verification.
|
||||
6. To review AI reporting, open Talk, generate an AI response, and tap Report next to that assistant response. The sheet previews the selected response, lets the reviewer choose a reason and optional comment, and returns a report receipt after submission.
|
||||
```
|
||||
|
||||
### Credential set B — Pro+/ad-free and team path
|
||||
|
||||
```text
|
||||
Name: D3RO Voice reviewer — Pro+ and team
|
||||
Username/email: <PLACEHOLDER_PLAY_REVIEWER_PRO_PLUS_EMAIL>
|
||||
Password: <PLACEHOLDER_PLAY_REVIEWER_PRO_PLUS_PASSWORD>
|
||||
|
||||
Instructions (English):
|
||||
1. Follow the same onboarding and email/password sign-in steps as credential set A.
|
||||
2. This reusable account has an active reviewer-only Pro+ entitlement and belongs to a seeded private review team. It does not require the reviewer to make a purchase.
|
||||
3. Open Works > Teams > <PLACEHOLDER_REVIEW_TEAM_NAME> to review invited-team collaboration, roles, meetings, memos, and shared records.
|
||||
4. The Pro+ entitlement is ad-free; no ad request should be made for this account.
|
||||
5. Use Settings > Account for account management and the in-app deletion path. Do not delete the shared reviewer account; the separate deletion procedure is documented below.
|
||||
```
|
||||
|
||||
### 계정 운영 게이트
|
||||
|
||||
- 두 계정 모두 이메일 확인 완료, 비밀번호 만료 없음, OTP/2FA/CAPTCHA 없음, 전 세계 reviewer 네트워크에서 24시간 재사용 가능해야 한다.
|
||||
- seed 데이터에는 실사용자·실회의·민감정보를 넣지 않는다.
|
||||
- Free 계정에는 광고와 AI 신고를 검토할 충분한 quota를 둔다.
|
||||
- Pro+ entitlement는 reviewer 계정에만 운영적으로 부여하고 만료 모니터를 둔다.
|
||||
- 매 release 제출 직전 깨끗한 Play 설치본으로 두 계정을 실제 로그인한다.
|
||||
|
||||
[Google의 로그인 정보 요구사항](https://support.google.com/googleplay/android-developer/answer/15748846?hl=en)을 따른다.
|
||||
|
||||
## 4. 콘텐츠 등급(IARC)과 타깃 연령
|
||||
|
||||
### 타깃 연령 후보
|
||||
|
||||
- 선택: **18세 이상만**
|
||||
- 아동 대상 여부: **아니요**
|
||||
- 아동에게 의도적으로 호소하는 그래픽·문구·캐릭터: **아니요**
|
||||
|
||||
이 선택은 앱이 성인물이라는 뜻이 아니라, 녹음·업로드·생성형 AI·초대형 팀 협업과 광고/구독을 포함하는 업무 생산성 도구를 아동 대상으로 운영하지 않겠다는 제품 경계다. 실제 target-audience 질문과 국가별 의무를 Console에서 다시 확인한다.
|
||||
|
||||
### IARC 답변 지침
|
||||
|
||||
IARC 결과 등급을 미리 단정하지 않는다. 질문에 아래 사실을 정확히 반영하고 Console이 산출한 지역별 등급을 수용한다.
|
||||
|
||||
| 항목 | 사실 기반 답변안 |
|
||||
| --------------------------------------------------- | --------------------------------------------------------------------------- |
|
||||
| 앱 유형 | 생산성/유틸리티, 게임 아님 |
|
||||
| 광고 | 예 |
|
||||
| 디지털 구매 | 예, 자동 갱신 Google Play 구독 가능 |
|
||||
| 생성형 AI | 예, 음성/텍스트 입력에 대한 대화 및 문서 결과 생성 |
|
||||
| 사용자 제작 콘텐츠 | 예, 사용자가 녹음·입력·업로드한 전사, 메모, 문서, 팀 기록 |
|
||||
| 사용자 간 콘텐츠 교환/온라인 상호작용 | 예(보수적), 초대된 비공개 팀 안에서 회의와 관련 기록 공유 |
|
||||
| 공개 피드·불특정 사용자 채팅 | 아니요 |
|
||||
| 사용자 차단/신고 | release에서 구현·운영 검증 후 실제 질문에 답변. 미구현 상태에서는 제출 차단 |
|
||||
| 개발자가 제공하는 폭력·성적·도박·약물 콘텐츠 | 아니요 |
|
||||
| 실제 현금 도박·상금·베팅 | 아니요 |
|
||||
| 사용자가 입력하거나 녹음할 수 있는 민감/불쾌 콘텐츠 | 가능. 신고·moderation 정책으로 처리하며 이를 숨기지 않음 |
|
||||
|
||||
광고는 앱의 최종 IARC 등급보다 현저히 성숙한 콘텐츠를 보여주면 안 된다. 현재 광고 SDK request configuration은 최대 광고 등급 `T`를 사용한다(`mobile-ads-context.tsx:95-98`). 최종 IARC 결과가 더 낮으면 광고 등급을 그 이하로 내리고 재검증한다.
|
||||
|
||||
## 5. 금융 기능 선언
|
||||
|
||||
후보 선택:
|
||||
|
||||
```text
|
||||
My app doesn't provide any financial features.
|
||||
```
|
||||
|
||||
근거:
|
||||
|
||||
- Google Play 구독은 앱의 디지털 기능 이용 권한을 구매하는 일반 in-app purchase다.
|
||||
- rewarded ad의 `cloud_ai_tokens`는 D3RO Voice 안에서만 소비되는 AI 사용량 quota다.
|
||||
- 이 quota는 현금 가치, 인출, 송금, 교환, 사용자 간 이전, 투자, 암호자산 또는 외부 상품 교환 기능이 없다.
|
||||
|
||||
따라서 현재 제품은 금융 서비스나 `Rewards, points, frequent flier miles, and other incentives`형 금융 프로그램으로 운영하지 않는다는 후보 판단이다. **크레딧을 양도·판매·환전·외부 보상에 사용하게 바꾸면 즉시 이 선언을 재검토한다.** 최종 저장 전 [Google의 금융 기능 선언 분류](https://support.google.com/googleplay/android-developer/answer/13849271?hl=en)와 Console의 최신 항목을 그대로 대조한다.
|
||||
|
||||
## 6. 계정 삭제
|
||||
|
||||
| 질문 | 입력안 | 근거 |
|
||||
| --------------------------------------- | ------------------------------------------------------------------------------- | ------------------------------------------ |
|
||||
| 앱에서 계정을 만들 수 있는가? | 예 | 이메일/OAuth 가입 |
|
||||
| 앱 안에서 계정 삭제를 요청할 수 있는가? | 예 | Settings > Account > Delete account |
|
||||
| 앱 밖에서 삭제를 요청할 수 있는가? | 예 | 아래 공개 URL |
|
||||
| 삭제 URL | `https://d3ro.chanpaca.net/delete-account/` | 앱 내·외 절차, 삭제/제한 보관 범주 기재 |
|
||||
| 일부 데이터만 삭제하는 별도 경로 | 계정 전체 삭제와 데이터 내보내기 제공. 별도 부분 삭제 질문은 실제 기능별로 확인 | 데이터 이동성 및 각 기록 삭제 UI 대조 필요 |
|
||||
|
||||
삭제 설명 후보:
|
||||
|
||||
```text
|
||||
Users can delete their account in D3RO Voice from Settings > Account > Delete account. The authenticated server deletes the account and associated service data, after which the app purges account-scoped local caches, queued audio, recordings, action history, preferences, entitlement caches, and push registration. Users who cannot access the app can request deletion at https://d3ro.chanpaca.net/delete-account/. Minimum payment, dispute, security, and abuse-prevention records may be retained only where required for those purposes.
|
||||
```
|
||||
|
||||
`20260824000029_content_reporting.sql`은 계정 삭제 시 report의 `reporter_id`와 review actor identity를 NULL로 분리하고 안전 신고 증거는 유지한다. pending/reviewing 증거는 최종 처리 전에는 time purge하지 않으며, dismissed/actioned 증거에는 처리 시점부터 180일의 `evidence_expires_at`을 설정한다. service-only purge RPC도 구현됐다. 다만 자동 scheduler·운영 담당 연결과 이 기준의 privacy/deletion 페이지 반영 전에는 위 삭제 답변을 최종 제출하지 않는다.
|
||||
|
||||
근거: `apps/mobile-rn/src/screens/AccountScreen.tsx:69-94,410-455`, `apps/mobile-rn/src/lib/account-local-data.ts:21-49`, `site/public/delete-account/index.html:18-39`.
|
||||
|
||||
## 7. AI 생성 콘텐츠와 UGC
|
||||
|
||||
### 현재 분류
|
||||
|
||||
- Talk의 text-to-text AI 응답과 전사 기반 문서 생성이 있으므로 Google Play의 AI-Generated Content 정책 적용 대상이다.
|
||||
- 초대된 팀 안에서 회의·전사·메모·문서를 공유하므로 제한적 UGC/online interaction도 있다.
|
||||
- 공개 피드나 익명 대화방은 없다. 그렇더라도 AI 결과 신고 요구사항은 면제되지 않는다.
|
||||
|
||||
### release 차단 조건
|
||||
|
||||
현재 source에는 Talk assistant response의 `Report` 버튼, 신고 sheet, authenticated Edge Function, generation receipt, service-only moderation 원장·purge RPC와 manager/admin review RPC가 구현돼 있다. 클라이언트는 `X-D3RO-Generation-Purpose`에 `talk_response`, `command_response`, `action_response` 중 하나를 보내고, 성공 응답의 서버 발급 `X-D3RO-Generation-Id`를 신고 source로 사용한다. 신고 POST는 UUID `Idempotency-Key`, `ai_output`, 동일 source type/generation ID, reason, 선택 snapshot/comment를 사용한다. generation receipt는 user·purpose·model·timestamps만 저장하고 raw prompt나 전체 생성 결과를 저장하지 않으며, Edge/general audit log도 snapshot 원문을 기록하지 않는다. 근거는 `apps/mobile-rn/src/screens/TalkScreen.tsx`, `apps/mobile-rn/src/components/ContentReportSheet.tsx`, `apps/mobile-rn/src/features/reporting/content-report-service.ts`, `server/supabase/functions/_shared/generation-receipt.ts`, `server/supabase/functions/content-report/`, `server/supabase/migrations/20260824000029_content_reporting.sql`이다. **source 구현과 local GREEN은 production 배포·운영 moderation·Play 설치본 E2E 완료를 의미하지 않는다.**
|
||||
|
||||
아래가 모두 GREEN이 되기 전에는 AI 기능을 포함한 release를 어떤 심사 트랙에도 제출하지 않는다.
|
||||
|
||||
- [x] generation receipt 30일 유효, source 3종, request/response header와 idempotent 신고 contract가 source에 구현됐다.
|
||||
- [x] local SQL integration, HTTP Edge 15 assertions와 shared Deno 64 tests가 GREEN이다.
|
||||
- [ ] 모든 AI 생성 결과 화면에서 앱을 벗어나지 않고 offensive content를 신고할 수 있다.
|
||||
- [ ] Play release 설치본에서 신고자가 인증돼 있고, 신고 sheet가 선택된 AI 응답을 미리 보여주는지 확인한다. 사용자가 제출하면 generation ID·reason·선택 comment와 해당 AI 응답 snapshot만 전송하며, 음성·전체 대화·원래 prompt는 자동 첨부하지 않는다.
|
||||
- [ ] production 원장에서 RLS, 허용 target/reason, 길이 제한, rate limit, 중복/남용 방어가 실제로 적용되는지 재검증한다.
|
||||
- [ ] 운영자용 검토 상태, 감사 기록, 처리 절차와 책임자가 있다.
|
||||
- [ ] 이용약관/사용자 정책이 금지 콘텐츠·행동, 신고·조치 가능성을 구체적으로 설명한다.
|
||||
- [ ] 개인정보처리방침이 reporter/target/reason/comment/AI 응답 snapshot, 목적, 공유, 30일 receipt, 해결 전 보관, 해결 후 180일 evidence, identity unlink와 purge를 설명한다.
|
||||
- [ ] service-only purge RPC에 자동 scheduler를 연결하고 운영 담당·실패 알림·runbook을 지정했다.
|
||||
- [ ] production migration/API/UI 배포 후 reviewer 계정으로 신고→운영 검토 원장 도달 E2E 증거를 남긴다.
|
||||
- [ ] `<PLACEHOLDER_REPORT_TEST_EVIDENCE>`를 실제 증거 링크/경로로 교체한다.
|
||||
|
||||
정책 근거: [AI-Generated Content](https://support.google.com/googleplay/android-developer/answer/13985936?hl=en), [Developer Program Policy](https://support.google.com/googleplay/android-developer/answer/17190352?hl=en&rd=2).
|
||||
|
||||
## 8. Foreground service 선언
|
||||
|
||||
### 유형과 사용 사례
|
||||
|
||||
| 필드 | 입력안 |
|
||||
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| FGS type | `microphone` |
|
||||
| Console use case | `Background audio access` / `Voice recording` |
|
||||
| permission | `android.permission.FOREGROUND_SERVICE`, `android.permission.FOREGROUND_SERVICE_MICROPHONE`, `android.permission.RECORD_AUDIO` |
|
||||
| service | `.D3RORecordingService`, exported `false` |
|
||||
|
||||
manifest 근거: `apps/mobile-rn/android/app/src/main/AndroidManifest.xml:4-9,49-53`.
|
||||
|
||||
### 기능 설명 — Console 입력안
|
||||
|
||||
```text
|
||||
D3RO Voice starts a microphone foreground service only after the signed-in user taps Record. The service captures the user-requested recording while the user may navigate to another app screen or place the app in the background. An ongoing notification clearly states that the D3RO Voice microphone is active, shows recording progress, and provides Pause/Resume, Stop, and Discard controls. The user can terminate the task at any time, and the foreground service and notification stop when the recording is stopped or discarded.
|
||||
```
|
||||
|
||||
### 지연·중단 영향 — Console 입력안
|
||||
|
||||
```text
|
||||
If start is deferred, the beginning of the user-requested conversation can be missed. If the task is interrupted, the recording can contain an unrecoverable gap and the resulting transcript can be incomplete. The app journals and repairs a partial WAV when possible, but it cannot reconstruct audio that the system did not capture. Immediate, user-visible foreground execution is therefore required for the core recording feature.
|
||||
```
|
||||
|
||||
코드 근거:
|
||||
|
||||
- 사용자 녹음 시작과 permission 요청: `apps/mobile-rn/src/screens/RecordScreen.tsx:320-347`
|
||||
- Android foreground service 시작: `apps/mobile-rn/android/app/src/main/java/com/d3ro/voice/D3RORecordingModule.kt:98-111`
|
||||
- ongoing notification과 Pause/Resume, Stop, Discard: `apps/mobile-rn/android/app/src/main/java/com/d3ro/voice/D3RORecordingService.kt:528-590`
|
||||
- 최대 wake lock과 종료 처리: `D3RORecordingService.kt:449-465,588-628`
|
||||
|
||||
### 영상 URL
|
||||
|
||||
```text
|
||||
<PLACEHOLDER_FGS_DEMO_URL>
|
||||
```
|
||||
|
||||
영상은 실제 release 후보를 설치한 Android 14+ 실기기에서 다음 순서를 한 번에 보여준다.
|
||||
|
||||
1. 앱 정보 화면 또는 화면 오버레이로 package, versionName/versionCode와 Play 설치본임을 식별한다.
|
||||
2. D3RO Voice 로그인 후 Record 화면을 연다.
|
||||
3. 녹음 시작을 탭하고, 처음 실행이면 앱 내 설명 뒤 microphone/notification runtime prompt를 보여준다.
|
||||
4. 녹음이 시작되자마자 ongoing notification에 microphone active와 timer가 표시되는 것을 보여준다.
|
||||
5. 홈으로 나가거나 화면을 잠갔다가 notification shade를 열어 녹음이 계속되고 있음을 보여준다.
|
||||
6. notification의 Pause와 Resume을 각각 사용한다.
|
||||
7. Stop으로 종료하고 notification이 사라진 뒤 앱에서 녹음/전사 처리 상태를 보여준다.
|
||||
8. 별도 짧은 녹음을 시작해 Discard로 즉시 종료할 수 있음을 보여준다.
|
||||
|
||||
영상에는 실제 대화나 개인정보를 녹음하지 않는다. 비공개/로그인 제한 없이 reviewer가 열 수 있는 unlisted YouTube 또는 공개 읽기 전용 Drive URL을 사용하고 제출 직전 링크를 익명 창에서 확인한다.
|
||||
|
||||
[Google FGS 선언 안내](https://support.google.com/googleplay/android-developer/answer/13392821?hl=en)를 따른다.
|
||||
|
||||
## 9. 기타 App content 후보
|
||||
|
||||
| 항목 | 입력안 |
|
||||
| -------------------------------- | ----------------------------------------------------------------------------- |
|
||||
| 개인정보처리방침 | `https://d3ro.chanpaca.net/privacy/` |
|
||||
| 뉴스/매거진 앱 | 아니요 |
|
||||
| 정부 앱 | 아니요 |
|
||||
| 건강 앱/의료 기능 | 아니요 |
|
||||
| COVID-19 기능 | 아니요 |
|
||||
| 데이터 브로커/대출/도박/암호화폐 | 아니요 |
|
||||
| Families/교사 승인 | 신청하지 않음 |
|
||||
| 민감 권한 | microphone, notification, microphone FGS. 위치·연락처·통화 기록·SMS 권한 없음 |
|
||||
|
||||
## 최종 저장 전 확인
|
||||
|
||||
- [ ] 실제 Console 질문 문구와 이 문서의 후보 답을 한 항목씩 대조했다.
|
||||
- [ ] release AAB가 선언한 permission/SDK와 답이 일치한다.
|
||||
- [ ] Data safety, 개인정보처리방침, 광고·AI·UGC·FGS 답변 사이에 모순이 없다.
|
||||
- [ ] 모든 `<PLACEHOLDER_...>`를 실제 값으로 교체했다.
|
||||
- [ ] 사용자 본인이 정책·수출법·Play App Signing 약관과 각 App content 선언을 검토하고 제출을 승인했다.
|
||||
Loading…
Add table
Add a link
Reference in a new issue