d3ro-voice/docs/map/06-mobile-app.md
Yun Chan 6b06442412
Some checks failed
ci / 정본·보안·린트·타입·테스트 (push) Successful in 50s
ci / 모바일 린트·타입·Jest (push) Successful in 38s
ci / Supabase Edge Functions + Cloudflare Worker (push) Successful in 21s
ci / .NET API 서버 테스트 (push) Successful in 11s
deploy-site / deploy (push) Successful in 33s
ci / 워크스페이스 빌드 검증 (push) Has been cancelled
docs(map): cross-device sync rewrite, fixed defects and what is still local
2026-09-27 14:04:49 +09:00

114 lines
7.3 KiB
Markdown

# 06 — Mobile App (React Native) Map
> Surface: `apps/mobile-rn` (ACTIVE product mobile app)
> Stack: React Native 0.85 + React 19 (CLI) + Supabase + Google Play Billing + AdMob
> The Expo legacy skeleton (`apps/mobile`) was **removed 2026-09-13**; `apps/mobile-rn` is the only mobile runtime.
> Authoritative checklist: `docs/v3/MOBILE_APP_COMPLETION_SSOT.md`
---
## 1. Navigation structure
Root stack (`App.tsx` `RootNavigator`) branches on auth/onboarding:
- `recovery` → `UpdatePassword`
- `onboarding` → Onboarding + InviteAccept + Login
- unauthenticated → Login, SignUp, ForgotPassword, InviteAccept
- authenticated → `Main` (`TabNavigator`) + ~22 stack screens
Bottom tabs (`TabNavigator.tsx`): **Dash / Works / Record (center raised FAB) / Talk / Settings**.
Deep links: `d3ro-voice://` and `https://d3ro.chanpaca.net` (`accept-invite`).
Provider stack: `GestureHandlerRootView → SafeAreaProvider → AuthProvider → EntitlementProvider → BillingProvider → MobileAdsProvider → MobilePreferencesProvider → DeviceProvider → LocalizedApplication (I18n + StatusBar)`.
---
## 2. Screens (`src/screens/`, 30)
| Screen | Feature |
|---|---|
| `RecordScreen` | Recording + local-whisper/cloud transcription, import audio, share |
| `DashScreen` | Dashboard: usage stats, tier, streaks, trends |
| `WorksHubScreen` | WORKS hub: pinned feature drill-down (desktop-parity) |
| `TalkScreen` | Voice/text AI chat: STT, LLM streaming, TTS |
| `HistoryScreen` / `HistoryDetailScreen` | History list/detail: sync, search, filters, audio playback, edit/share/favorite/delete |
| `MeetingsScreen` / `MeetingDetailScreen` | Meeting workspaces: create/rename/delete, transcript, memos, documents, export, content report |
| `MemosScreen` | Memos: list, tags, search, share |
| `TemplatesScreen` | Dictation/meeting document templates CRUD |
| `KnowledgeScreen` | Knowledge docs: create/import/index/merge/delete/search |
| `CommandsScreen` | Custom instruction CRUD/reorder/activate/execute |
| `ActionsScreen` | Voice-action parse/confirm/execute + history |
| `DictionaryScreen` | Dictionary CRUD/search/filters |
| `TeamsScreen` / `TeamDetailScreen` | Teams: create, members, invites, rename, leave, meetings, activity feed/comments |
| `DevicesScreen` | Registered devices (phones, web, **desktop apps**), platform label, revoke/remove — revoking a desktop signs it out |
| `NotificationsScreen` | Notification list, permission, deep-link nav |
| `AccountScreen` | Profile, identities, data export/delete, logout |
| `DataPortabilityScreen` | Export/import archive, dictionary, history, meeting docs |
| `AdminScreen` / `AdminUserDetailScreen` | Role-gated admin: users, subscriptions, audit, role/tier edits |
| `ProPaywallScreen` | Pro/Pro+ paywall: Play IAP, restore, rewarded ads |
| `OnboardingScreen` | First-run audience/theme/locale |
| `SettingsScreen` | Preferences, locale/theme, privacy links, logout |
| `LoginScreen` / `SignUpScreen` / `ForgotPasswordScreen` / `UpdatePasswordScreen` / `InviteAcceptScreen` | Auth flows |
---
## 3. Features (`src/features/`, 20 modules)
| Module | Purpose |
|---|---|
| `recording/` | Durable offline recording queue, retry processing, language handling |
| `import/` | Audio pick/decode/validate, local Whisper fallback, resumable multipart upload, Android share-intent intake |
| `history/` | History service + local cache + sync hook |
| `meetings/` | Meeting workspace CRUD, realtime channels, processing jobs, transcripts/memos/docs |
| `memos/` | Memo CRUD, tags, search, realtime, share |
| `talk/` | Streaming LLM, transcription, TTS playback |
| `teams/` | Team CRUD/members/invites/realtime, pending invite, `listTeamActivities`/`createTeamActivity` (activity feed) |
| `knowledge/` | Knowledge docs CRUD/index/merge/search + file picker |
| `commands/` | Custom command client |
| `actions/` | Voice-action parse/execute + side effects |
| `dictionary/` | Dictionary CRUD/pagination/search |
| `devices/` | Device registration/list/revoke |
| `dashboard/` | Dashboard stats + recent entries |
| `templates/` | Templates + generation idempotency |
| `auth/` | OAuth sign-in (in-app browser, PKCE) + identity linking |
| `admin/` | Admin user/subscription/audit APIs + session/role |
| `data-portability/` | Canonical JSON export/import, schema validation, legacy import, meeting export, file sharing |
| `chat/` | Chat LLM normalization/streaming, reportable generation IDs |
| `notifications/` | Notification contract/native registration/service/runtime hook |
| `reporting/` | AI content reporting (reason codes, Edge calls, idempotency) |
Core libs (`src/lib/`): `auth-context`, `auth-redirect`, `auth-capabilities`, `secure-auth-storage` (Keychain + legacy migration), `logout`, `account-exit`, `account-local-data` (central purge), `supabase`, `billing-context` (Play/App Store IAP), `entitlement-context`, `device-context`, `preferences-context`, `mobile-ads-context` (UMP consent + rewarded), `native-config`, `pkce-s256`, `random-id`, `audio-recorder`, `e2e-runtime-bootstrap`.
---
## 4. Mobile status summary
Source of truth for status is `docs/v3/MOBILE_APP_COMPLETION_SSOT.md` sections 0.1, 2.1, 4. Current condensed state:
| Area | Status |
|---|---|
| Auth / account | `[~]` Implemented + Jest GREEN; external OAuth consent→callback and logout/delete/provider device E2E pending |
| Onboarding / theme / accessibility | `[x]` device journey GREEN (some checklist rows still `[ ]` for a11y specifics) |
| Recording / transcription / Talk | `[x]` core path GREEN on API 34 (FGS, recovery, local Whisper, cloud fail-closed, TTS) |
| Data portability | `[x]` export/restore + share E2E GREEN |
| History / meetings | `[x]` real data + meeting creation contract GREEN; audio timestamp/speaker + cross-app E2E pending |
| Teams / push | `[~]` teams GREEN; real FCM delivery needs Firebase/FCM credentials |
| Billing / ads | `[~]` test ads + Google Play verification code GREEN; live store purchase/restore/settlement and production AdMob serving **RED (external)** |
| Admin | `[x]` mobile admin role E2E GREEN (ordinary/manager/admin/super_admin, stale JWT) |
| Quality / distribution | `[~]` lint/typecheck/Jest GREEN; production signed AAB + Play submission **RED (external gates)** |
**External blockers (do not treat as code gaps):** production Firebase project, AdMob live serving, Play Billing license tester, CI secret injection, signed production AAB, Play closed test (0/12, 14 days), production access approval. See SSOT §0, §6.
---
## 5. Legacy removal
The Expo skeleton (`apps/mobile`) was deleted on 2026-09-13: it duplicated auth/data logic, shipped a dev-bypass login, and was outside the workspace and CI. `scripts/ci/sync-version.mjs` and `package-lock.json` no longer reference it. `apps/mobile-rn` is the sole mobile runtime; git history retains the old app.
---
## 6. Tests & evidence
- Jest: `apps/mobile-rn/__tests__/` — per SSOT 57 suites / 353 tests (auth, privacy purge, admin, billing, recording language, generation idempotency, templates/memos, STT quota integration).
- Maestro E2E: `apps/mobile-rn/.maestro/` + evidence in `.maestro-output/`.
- Android instrumentation: `apps/mobile-rn/android/app/src/androidTest` (CSPRNG + incoming share).
- Build verifiers: `scripts/ci/verify-android-artifact.mjs`, `verify-android-app-links.mjs`, `verify-mobile-build-config.mjs`, `verify-mobile-release-boundary.mjs`.