Some checks failed
ci / 정본·보안·린트·타입·테스트 (push) Failing after 50s
ci / 워크스페이스 빌드 검증 (push) Has been skipped
ci / Supabase Edge Functions + Cloudflare Worker (push) Successful in 20s
ci / .NET API 서버 테스트 (push) Successful in 12s
deploy-site / deploy (push) Successful in 39s
ci / 모바일 린트·타입·Jest (push) Failing after 3h10m31s
126 lines
10 KiB
Markdown
126 lines
10 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`) + 23 stack screens
|
|
|
|
Bottom tabs (`TabNavigator.tsx`): **Home / Records / Meetings / More**. `Record` remains a hidden tab route so an active recording stays mounted; it never occupies a visible tab slot. A floating `RecordFab` appears on Home/Records/Meetings (not More/Record) and routes **dictation → Record**, **meeting recording → Meetings + `createRequest`**, **audio import → Record + `importRequest`**. Android back, scrim press, and action selection close its menu; tab back behavior is history-based.
|
|
Home opens `UnifiedSearch` on the root stack. New and converted v4 flows use the app-level `ScreenHeader` with a 48dp back action; tab roots such as Records and Meetings show a title without a back action. Historical stack screens that were not part of this conversion may still use their own header.
|
|
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/`: 31 active source files)
|
|
|
|
| Screen | Feature |
|
|
|---|---|
|
|
| `HomeScreen` | Today summary, recent 5 records / 3 meetings, unified-search entry, Free plan entry |
|
|
| `MoreScreen` | Tools and account routes; Admin entry is role-gated |
|
|
| `UnifiedSearchScreen` | Authenticated record+meeting search, newest-first merged results, source-aware detail navigation |
|
|
| `RecordScreen` | Recording + local-whisper/cloud transcription, import audio, share; entered from the hidden Record route/FAB |
|
|
| `TalkScreen` | Voice/text AI chat: STT, LLM streaming, TTS; opened from More on the root stack |
|
|
| `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; opened from More on the root stack |
|
|
| `LoginScreen` / `SignUpScreen` / `ForgotPasswordScreen` / `UpdatePasswordScreen` / `InviteAcceptScreen` | Auth flows |
|
|
|
|
---
|
|
|
|
## 3. Features (`src/features/`, 23 modules)
|
|
|
|
| Module | Purpose |
|
|
|---|---|
|
|
| `recording/` | Durable offline recording queue, retry processing, language handling |
|
|
| `audio/` | Linked recording/audio cleanup |
|
|
| `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 |
|
|
| `account/` | Account deletion service and server-confirmed exit boundary |
|
|
| `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) |
|
|
| `search/` | User-scoped record title/original/polished/summary + meeting title/raw/edited transcript search; sanitization, parallel queries, newest-first merge |
|
|
|
|
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 | `[x]` previous first-run device journey GREEN; this does not verify the new v4 shell on every viewport/theme |
|
|
| v4 shell / theme / accessibility | `[x]` shell journey at 320dp dark and 411dp light; `[~]` broader design-system/a11y proof because TalkBack/font-scale/rotation remain |
|
|
| 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 |
|
|
| Record+meeting unified search | `[~]` service/row tests and both canonical runtime journeys (both source results → details) GREEN; mobile raw-text overfetch/no cancellation and FTS/index/large-data performance remain unproved |
|
|
| 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.
|
|
|
|
The v4 shell also removed `DashScreen` and `WorksHubScreen`. Home replaces the dashboard entry; first-class tabs and More preserve the former WorksHub destinations. The WorksHub-only local tool filter and pinning were intentionally retired to avoid a second navigation taxonomy and local ordering state. This removed navigation UI, not record/meeting/tool content; an unused `works-hub-pins.v1` AsyncStorage key may remain on upgraded installs.
|
|
|
|
---
|
|
|
|
## 6. Tests & evidence
|
|
|
|
- Jest: `npm --prefix apps/mobile-rn test` — current full tree **86 suites / 589 tests PASS** (2026-09-28). v4-focused coverage includes `navigation-shell.test.tsx`, `screen-header.test.tsx`, `theme-parity.test.ts`, `ui-native-theme.test.tsx`, `unified-search-service.test.ts`, and `unified-search-result-row.test.tsx`.
|
|
- Maestro E2E: `apps/mobile-rn/.maestro/` + evidence in `.maestro-output/`.
|
|
- v4 local runtime: `apps/mobile-rn/.maestro/navigation-shell-search-local.yaml`; 320dp dark **1/1 PASS, 88 s** at `scratch/design-audit/wave45/navigation-shell-search-320-dark-verified.xml`, and 411dp light **1/1 PASS, 100 s** at `scratch/design-audit/wave45/navigation-shell-search-411-light-verified.xml`.
|
|
- Runtime APK: `com.d3ro.voice`, versionName `1.9.0-e2e.20260928.2`, versionCode `202609282`, 147063583 bytes, SHA-256 `96EBA2A47E54033EB0DEFCE4E4D282F1D06F162A5F7DF9457E99609D98745D58`. This is a local E2E artifact, not a production-signed APK/AAB or Play release.
|
|
- Committed evidence summary: [`docs/evidence/wave45-mobile-shell-search-2026-09-28.md`](../evidence/wave45-mobile-shell-search-2026-09-28.md).
|
|
- 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`.
|