- shared/realtime.ts: add SOCKET_NAMESPACES constants (/trading, /admin, root) - shared/feature-flags.ts: add tabs.marketplace and tabs.membership to TradingFeatureFlagsResponse; add FEATURE_FLAG_KEYS constants - .env.example: remove /api suffix from VITE/NEXT_PUBLIC trading URL vars (web appends /api itself); add tab visibility flag vars with comments - web: add useTabFeatureFlags hook + DOM test; wire tab visibility into App.tsx - web/vite.config.ts: finalize build config - mobile/providers/TradingDataProvider.tsx: deriveSocketParams for proxy-safe socket origin/path resolution (already landed upstream, conflict resolved) - docs: add CUTOVER_WEB.md, CUTOVER_MOBILE.md checklists; update OPERATIONS.md with Docker commands and resolved gap log; update ROADMAP.md to Done; add BACKEND_AUDIT_SCHEMA.md, BACKEND_API_DEPRECATION.md, CONVENTIONS.md; add audit-events container entry to AZURE_INFRASTRUCTURE.md - README.md: full rewrite with workspace table, arch summary, env var reference Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
252 lines
9.5 KiB
Markdown
252 lines
9.5 KiB
Markdown
# Mobile Internal Beta Checklist (Stage 3 Cutover)
|
||
|
||
## Purpose
|
||
|
||
This document is the step-by-step runbook for releasing the monorepo mobile app
|
||
(`mobile/`) to internal testers before broader rollout.
|
||
|
||
**Prerequisite:** Stage 2 (web internal adoption) must be complete and stable through
|
||
at least one full backend deploy cycle before beginning Stage 3.
|
||
See `docs/CUTOVER_WEB.md`.
|
||
|
||
---
|
||
|
||
## Pre-Flight Gate
|
||
|
||
Do not begin mobile beta until all of the following are true.
|
||
|
||
### Go / No-Go Checks
|
||
|
||
```bash
|
||
# From monorepo root
|
||
pnpm verify # must be green
|
||
pnpm lint # must be green
|
||
pnpm smoke:release # must pass — validates mobile platform contract compilation
|
||
```
|
||
|
||
### Backend + Web Stability
|
||
|
||
- [ ] Stage 2 (web internal adoption) signed off with no rollback triggers
|
||
- [ ] Backend has been stable through at least one full deploy cycle since web cutover
|
||
- [ ] `GET /health/live` returns 200 from the deployment that mobile will target
|
||
- [ ] WebSocket `/trading` namespace is reachable from an external network (not just localhost)
|
||
- [ ] Feature flags endpoint `GET /api/feature-flags` returns valid response
|
||
|
||
### Mobile Build Readiness
|
||
|
||
- [ ] `EXPO_PUBLIC_PRODUCT_ID`, `EXPO_PUBLIC_PLATFORM_URL`, `EXPO_PUBLIC_TRADING_API_URL` set correctly for the target environment
|
||
- [ ] App compiles cleanly: `pnpm --filter @bytelyst/trading-mobile typecheck`
|
||
- [ ] Internal distribution channel ready (TestFlight for iOS, Internal Testing for Android, or Expo Go for dev)
|
||
- [ ] Internal testers identified (typically the same operators who validated web)
|
||
|
||
### Rollback Readiness
|
||
|
||
- [ ] Web dashboard remains fully operational as the primary operator interface
|
||
- [ ] Mobile beta can be pulled from distribution without affecting backend or web
|
||
- [ ] You know who owns the rollback decision
|
||
|
||
---
|
||
|
||
## Step 1 — Build and Distribute the Beta
|
||
|
||
### Option A — Expo Go (fastest for internal testing)
|
||
|
||
```bash
|
||
cd mobile
|
||
pnpm dev # starts Expo dev server; testers scan QR code with Expo Go app
|
||
```
|
||
|
||
### Option B — Native build via EAS (recommended for realistic testing)
|
||
|
||
```bash
|
||
# Requires EAS CLI and Expo account
|
||
npx eas build --platform all --profile preview
|
||
npx eas submit --platform all # submit to TestFlight / Google Play Internal Testing
|
||
```
|
||
|
||
Verify distribution:
|
||
|
||
- [ ] Each internal tester can install the app on their device
|
||
- [ ] App launches without crash on both iOS and Android (or whichever platforms are in scope)
|
||
|
||
---
|
||
|
||
## Step 2 — Fresh Install Sign-In
|
||
|
||
Each tester performs a fresh install (no prior session):
|
||
|
||
- [ ] App launches to the sign-in screen (no blank screen, no crash)
|
||
- [ ] Sign in with platform credentials — same credentials as web
|
||
- [ ] Session established — app navigates to the Overview tab
|
||
- [ ] Confirm auth token is a platform JWT (check tester's device Expo logs)
|
||
- [ ] `GET /api/me/profile` returns the correct user profile
|
||
|
||
---
|
||
|
||
## Step 3 — Session Restore
|
||
|
||
- [ ] Close the app completely (background + remove from recents)
|
||
- [ ] Reopen the app
|
||
- [ ] App restores session without re-prompting for sign-in
|
||
- [ ] Overview tab loads with live state (not a loading spinner indefinitely)
|
||
- [ ] Confirm secure storage is working: token survives app restart
|
||
|
||
---
|
||
|
||
## Step 4 — Kill-Switch and Degraded-State Handling
|
||
|
||
### Kill-switch
|
||
|
||
- [ ] Toggle maintenance mode on via platform-service
|
||
- [ ] Reopen (or refresh) the mobile app — it must block access with a maintenance/unavailable screen
|
||
- [ ] Toggle maintenance mode off
|
||
- [ ] App recovers without requiring a reinstall or manual sign-in
|
||
|
||
### Degraded backend
|
||
|
||
- [ ] Stop the backend service temporarily
|
||
- [ ] App shows a degraded/offline state clearly (not a crash or blank screen)
|
||
- [ ] Restart the backend — app reconnects automatically and restores live state
|
||
|
||
---
|
||
|
||
## Step 5 — Core Feature Validation
|
||
|
||
Each tester validates their own user scope across all five tabs:
|
||
|
||
### Overview (index.tsx)
|
||
- [ ] Portfolio summary loads with current positions and account snapshot
|
||
- [ ] Live ticker or price updates are visible within 60 seconds
|
||
- [ ] Trading control badge shows correct mode (RUNNING / PAUSED)
|
||
- [ ] WebSocket connects to `/trading` namespace (check backend logs: `[API][/trading] Client connected`)
|
||
|
||
### Positions (positions.tsx)
|
||
- [ ] Open positions list matches what the web dashboard shows
|
||
- [ ] Each position shows symbol, side, size, entry price, unrealised PnL
|
||
- [ ] Positions update live when the backend broadcasts `positions_update`
|
||
|
||
### History (history.tsx)
|
||
- [ ] Closed trade history loads and matches web dashboard
|
||
- [ ] Scroll loads older history correctly (if pagination is implemented)
|
||
|
||
### Strategies (strategies.tsx)
|
||
- [ ] Trading profiles list loads for the authenticated user
|
||
- [ ] Profile names, symbols, and active state are correct
|
||
|
||
### Settings (settings.tsx)
|
||
- [ ] User email and account info display correctly
|
||
- [ ] Sign-out works — returns to the sign-in screen and clears the session
|
||
- [ ] Notification preference toggles are visible (even if push delivery is deferred)
|
||
|
||
---
|
||
|
||
## Step 6 — Real-Time Update Verification
|
||
|
||
Leave the app running on the Overview tab for at least 5 minutes:
|
||
|
||
- [ ] Symbol prices update at least once during the observation window
|
||
- [ ] Health status reflects current backend loop health
|
||
- [ ] If a trade closes during the observation window, it appears in History without a manual refresh
|
||
- [ ] No unhandled exceptions appear in Expo logs during this period
|
||
|
||
### Polling fallback
|
||
|
||
- [ ] Disable WebSocket connectivity (e.g., block the Socket.IO port via network settings)
|
||
- [ ] App falls back to polling — data still refreshes (may be slower)
|
||
- [ ] Restore connectivity — app reconnects to WebSocket automatically
|
||
|
||
---
|
||
|
||
## Step 7 — Offline / Poor-Connectivity Behaviour
|
||
|
||
- [ ] Enable airplane mode while the app is running
|
||
- [ ] App shows a clear offline or disconnected indicator (not a crash)
|
||
- [ ] Restore network — app reconnects and reloads state without manual intervention
|
||
- [ ] No stale or misleading data is shown during the offline period
|
||
|
||
---
|
||
|
||
## Step 8 — Safe Operator Controls
|
||
|
||
Mobile v1 is intentionally monitor-first. Validate that the scope is correctly limited:
|
||
|
||
- [ ] No destructive trading actions are available in the mobile UI (no "close position", no "pause trading" button)
|
||
- [ ] No strategy editing available in mobile (strategies tab is read-only)
|
||
- [ ] No admin panel or diagnostics UI visible to non-admin testers
|
||
- [ ] Confirm no API calls are made to `POST /api/trade`, `POST /api/close`, or `/internal/trading/*` from mobile
|
||
|
||
---
|
||
|
||
## Step 9 — Parallel Run Period (Recommended: 3–7 days)
|
||
|
||
Run the mobile beta in parallel with the web dashboard:
|
||
|
||
- [ ] Testers use mobile for monitoring; web remains primary for operator actions
|
||
- [ ] Testers report any data discrepancy between mobile and web
|
||
- [ ] Collect feedback on performance, UX clarity, and any missing information
|
||
- [ ] Monitor backend logs for unusual error spikes correlated with mobile connections
|
||
|
||
---
|
||
|
||
## Rollback Triggers
|
||
|
||
Pull the beta build from distribution immediately if any of the following occur:
|
||
|
||
| Condition | Action |
|
||
|---|---|
|
||
| Sign-in or session restore fails | Remove from distribution |
|
||
| Tenant data leak — tester sees another user's data | Remove immediately + page oncall |
|
||
| App crashes on launch for any tester | Remove and diagnose |
|
||
| App shows incorrect or stale positions/history vs. web | Investigate before proceeding |
|
||
| Backend error rate increases after mobile connections are established | Rollback and diagnose |
|
||
|
||
### Rollback Steps
|
||
|
||
1. Remove the beta build from TestFlight / Play Internal Testing
|
||
2. Notify testers to uninstall or stop using the app
|
||
3. File an incident report — include device, OS version, Expo logs, and `x-request-id` from any correlated backend errors
|
||
4. Do not modify Cosmos state as first-response rollback
|
||
5. Resolve the root cause before re-attempting the beta
|
||
|
||
---
|
||
|
||
## Post-Beta Monitoring (Ongoing during beta period)
|
||
|
||
### Watch during the beta
|
||
|
||
- [ ] Platform auth failure rate is baseline — no spike correlated with mobile sessions
|
||
- [ ] Token refresh failures from mobile clients are zero
|
||
- [ ] WebSocket `/trading` namespace connection count is stable (no reconnect storm)
|
||
- [ ] Backend `401` / `403` errors are baseline — no increase from mobile auth
|
||
- [ ] Cosmos read latency is normal — mobile polling does not add unexpected load
|
||
- [ ] Mobile degraded/offline state frequency is low (expected: near zero on good networks)
|
||
|
||
---
|
||
|
||
## Beta Sign-Off
|
||
|
||
Complete after the parallel run period with no rollback triggers:
|
||
|
||
- [ ] All internal testers confirm the app is working correctly on their devices
|
||
- [ ] No open P0/P1 bugs from the beta period
|
||
- [ ] Monitoring checks above are green for the duration of the beta
|
||
- [ ] Feedback collected and triaged (decide what goes into a follow-up release vs. pre-GA fix)
|
||
- [ ] ROADMAP.md: mark "Mobile internal beta" as `[x]` Done
|
||
- [ ] OPERATIONS.md: update Staged Cutover section to reflect Stage 3 complete
|
||
|
||
---
|
||
|
||
## Next Stage
|
||
|
||
After mobile internal beta is signed off:
|
||
|
||
**Stage 4 — Controlled Operator Rollout**
|
||
- Expand to a small group of external operators (e.g., power users, design partners)
|
||
- Gate: mobile beta signed off + web adoption stable for ≥ 1 week
|
||
- Monitor: same checks as post-beta, extended for 24–48 hours after each rollout increment
|
||
|
||
**Stage 5 — Production Cutover**
|
||
- Switch full operational ownership from legacy repos to this monorepo
|
||
- Archive legacy `bytelyst-trading-dashboard-web`, `bytelyst-trading-bot-service`, and `bytelyst-trading-dashboard-mob`
|
||
- Gate: Stage 4 stable + rollback owners confirmed + monitoring dashboards in place
|