From 8aff92d6b25e6734a7e01802ffc4ec3b3a050c78 Mon Sep 17 00:00:00 2001 From: Saravana Achu Mac Date: Mon, 30 Mar 2026 23:48:33 -0700 Subject: [PATCH] docs(mobile): add MOBILE_DELEGATION_ROADMAP for NoteLett MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Sequential blocks A–I (auth, kill switch, broadcast/survey, feedback, offline queue, blob, health, RNTL, optional sync) with file paths under mobile/ - Cross-link from AGENT_TASK_ROADMAP Current State section Made-with: Cursor --- docs/AGENT_TASK_ROADMAP.md | 4 + docs/MOBILE_DELEGATION_ROADMAP.md | 251 ++++++++++++++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 docs/MOBILE_DELEGATION_ROADMAP.md diff --git a/docs/AGENT_TASK_ROADMAP.md b/docs/AGENT_TASK_ROADMAP.md index 28a9ab7..91033f3 100644 --- a/docs/AGENT_TASK_ROADMAP.md +++ b/docs/AGENT_TASK_ROADMAP.md @@ -18,6 +18,10 @@ **Package resolution note:** 5 backend `@bytelyst/*` packages (`backend-config`, `backend-flags`, `backend-telemetry`, `fastify-auth`, `field-encrypt`) do not have source directories in `learning_ai_common_plat/packages/`. They resolve via `^0.1.0` from the private Gitea npm registry but their source must be created in common_plat. This is a shared blocker with NomGap — see Phase 0 below. +### Mobile — sequential handoff + +For **ordered mobile implementation** (Expo app under `mobile/`), use **[`MOBILE_DELEGATION_ROADMAP.md`](./MOBILE_DELEGATION_ROADMAP.md)** — blocks, file pointers, and acceptance criteria in one place. Update the **Current State** table above when mobile capabilities change materially. + --- ## Phase 0 — Missing Platform Package Source (SHARED BLOCKER) diff --git a/docs/MOBILE_DELEGATION_ROADMAP.md b/docs/MOBILE_DELEGATION_ROADMAP.md new file mode 100644 index 0000000..432d2e4 --- /dev/null +++ b/docs/MOBILE_DELEGATION_ROADMAP.md @@ -0,0 +1,251 @@ +# NoteLett Mobile — Delegation Roadmap (single-agent, sequential) + +**Purpose:** One document to hand to an AI or human implementer. Execute **blocks in order** (later blocks assume earlier ones are merged). When a block is done, update **`docs/AGENT_TASK_ROADMAP.md`** (e.g. **Current State** table and any new mobile checklist rows), then commit and push. + +**Canonical product checklist:** [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md). + +**Repo:** `learning_ai_notes` +**Mobile app root:** `mobile/` (Expo Router under `mobile/src/app/`). +**Stack:** Expo ~55, React Native ~0.83, Zustand + MMKV, `@bytelyst/*` (auth-client, api-client, telemetry-client, feature-flag-client, kill-switch-client, blob-client, offline-queue, diagnostics-client). + +**Related pattern:** NomGap uses the same idea under `learning_ai_fastgap/docs/MOBILE_DELEGATION_ROADMAP.md` — **do not** copy fasting-specific paths or M-numbers; this file is authoritative for NoteLett. + +--- + +## 0 — Prerequisites (before writing code) + +- [ ] **Install:** From `learning_ai_notes` root: `pnpm install` (workspace: `backend`, `web`, `mobile`). +- [ ] **Private registry:** If `.npmrc` references `${GITEA_NPM_HOST}`, set env so installs resolve `@bytelyst/*`. +- [ ] **Baseline:** `cd mobile && pnpm run typecheck` (and `pnpm test`) pass on your machine. +- [ ] **Branch:** `git checkout -b feat/mobile-` (one branch per major block is fine). + +**Note:** This repo’s `pnpm-workspace.yaml` lists only `backend`, `web`, `mobile` — not `learning_ai_common_plat`. Platform packages typically resolve from the registry; link local plat only if your team uses that workflow. + +--- + +## 1 — Already shipped (verify before redoing) + +| Area | What to verify | +|------|----------------| +| **Router + shell** | `mobile/src/app/_layout.tsx` — bootstraps auth, `initPlatform()`, hydrates stores | +| **Entry** | `mobile/src/app/index.tsx` → `Redirect` to `/auth` | +| **Auth UI** | `mobile/src/app/auth.tsx` — email/password → `useAuthStore` → `/(tabs)` | +| **Auth + API** | `mobile/src/api/auth.ts` (`createAuthClient`, MMKV `storagePrefix: PRODUCT_ID`), `mobile/src/api/client.ts` (`createApiClient` + `getToken`) | +| **Platform clients** | `mobile/src/lib/platform.ts` — telemetry init + `trackEvent`, feature flags, kill switch, `blobClient`, diagnostics singleton | +| **Stores + API modules** | `auth-store`, `notes-store`, `workspace-store`, `inbox-store`; `mobile/src/api/notes.ts`, `workspaces.ts`, `note-agent-actions.ts` | +| **Offline queue (module)** | `mobile/src/lib/offline-queue.ts` exports `noteOfflineQueue` — **UI/store wiring is still partial** (see capture screen copy) | +| **Tabs + detail** | `(tabs)/` index, search, capture, inbox; `mobile/src/app/note/[id].tsx` | +| **Tests** | Vitest on stores (`*.test.ts`); no `@testing-library/react-native` in `mobile/package.json` today | + +--- + +## 2 — Execution order (mandatory) + +``` +Block A → Auth flow + session UX (register, refresh, guarded entry) +Block B → Kill switch gate + safe degraded UI +Block C → Broadcast + survey (web parity) +Block D → Profile / settings + feedback-client +Block E → Offline queue: enqueue + flush on boot / resume +Block F → Blob / attachments (capture or note detail) via shared blobClient +Block G → Code health (telemetry versions, a11y, dead code) +Block H → RNTL + smoke screen tests +Block I → Optional — @bytelyst/sync or deeper sync (last; needs API contract review) +``` + +--- + +## Block A — Auth flow and session UX + +### A.1 Goals + +- **Signed-in users** should not be forced through `/auth` on every cold start — `index` should redirect to `/(tabs)` when `useAuthStore` / `getAuthClient()` is authenticated (after `bootstrap` resolves). +- Add **register** (and optional forgot-password) paths aligned with backend + web, or document why mobile is sign-in only. +- Ensure **token refresh** behavior matches `@bytelyst/auth-client` expectations (no silent 401 loops on `getApiClient()`). + +### A.2 Files to read first + +- `mobile/src/app/index.tsx`, `mobile/src/app/auth.tsx`, `mobile/src/app/_layout.tsx` +- `mobile/src/store/auth-store.ts`, `mobile/src/api/auth.ts`, `mobile/src/api/config.ts` +- Web reference: `web/src/lib/auth.ts`, auth pages under `web/src/app/(auth)/` + +### A.3 Optional (platform SDK parity) + +If the team standardizes on **`@bytelyst/react-native-platform-sdk`**: either integrate **`AuthProvider`** with the **same MMKV keys** as `createAuthClient({ storagePrefix: PRODUCT_ID })`, or document a minimal bridge (same approach as NomGap Block A in `learning_ai_fastgap`). + +### A.4 Done criteria + +- [ ] Cold start: authed → tabs; unauthed → auth +- [ ] `cd mobile && pnpm run typecheck && pnpm test` +- [ ] Update **Current State** / any new checklist rows in [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md) +- [ ] Commit: `feat(mobile): auth entry flow and session handling` (split if large) + +--- + +## Block B — Kill switch gate + +### B.1 Goal + +Mirror web `middleware` / layout behavior: when **`checkKillSwitch()`** reports disabled, block main app UI and show message (reuse pattern from `web` or NomGap `KillSwitchGate`). + +### B.2 Files + +- `mobile/src/lib/platform.ts` (`checkKillSwitch`) +- `mobile/src/app/_layout.tsx` or a small `KillSwitchGate` wrapper component + +### B.3 Done criteria + +- [ ] Manual test with kill switch on/off (or mocked) +- [ ] Update [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md) +- [ ] Commit: `feat(mobile): kill switch gate` + +--- + +## Block C — Broadcast + survey (web parity) + +### C.1 Goal + +Integrate **`@bytelyst/broadcast-client`** and **`@bytelyst/survey-client`** in the root layout (banner + modal), matching API usage from web (see `web` app layout and `@bytelyst/broadcast-client` / `@bytelyst/survey-client` exports). + +### C.2 Files + +- Add deps to `mobile/package.json` if missing +- `mobile/src/app/_layout.tsx` + new thin components under `mobile/src/components/` as needed +- Reference: `web/src/app/(app)/layout.tsx` (or wherever BroadcastBanner / SurveyBanner live) + +### C.3 Done criteria + +- [ ] No duplicate/wrong client API (align with current package exports) +- [ ] Update [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md) +- [ ] Commit: `feat(mobile): broadcast and survey clients` + +--- + +## Block D — Settings / profile + feedback + +### D.1 Goal + +Add **`@bytelyst/feedback-client`** from mobile — same payload shape as web (`submit({ type, title, body })` or current API). + +### D.2 Files + +- New screen or tab entry: e.g. `mobile/src/app/settings.tsx` or profile section on a tab +- `mobile/package.json` if adding `feedback-client` + +### D.3 Done criteria + +- [ ] Graceful offline / error handling +- [ ] Update [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md) +- [ ] Commit: `feat(mobile): feedback client in settings` + +--- + +## Block E — Offline queue wiring + +### E.1 Goal + +`noteOfflineQueue` exists but capture screen still says wiring is deferred. **Enqueue** failed note mutations; **flush** on app start and on connectivity / `AppState` active (match web offline-queue behavior). + +### E.2 Files + +- `mobile/src/lib/offline-queue.ts` +- `mobile/src/store/notes-store.ts` (and any create/update paths) +- `mobile/src/app/(tabs)/capture.tsx` + +### E.3 Done criteria + +- [ ] Airplane-mode manual test: queue → reconnect → drain +- [ ] Update [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md) +- [ ] Commit: `feat(mobile): offline queue enqueue and flush` + +--- + +## Block F — Blob / attachments + +### F.1 Goal + +Any mobile upload path (future file capture, artifacts) should use **`blobClient`** from `mobile/src/lib/platform.ts` — no second SAS or raw `fetch` duplicate. + +### F.2 Files + +- `mobile/src/lib/platform.ts` (`blobClient`) +- Future: note detail or capture file picker + +### F.3 Done criteria + +- [ ] Single upload abstraction; E2E or manual upload test +- [ ] Update [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md) +- [ ] Commit: `feat(mobile): blob uploads via shared blobClient` (or `refactor` if replacing duplicate code) + +--- + +## Block G — Code health + +Execute in **flexible order**; prefer **small commits**. + +| Task | Hints | +|------|--------| +| **Telemetry metadata** | Use `expo-constants` for `appVersion` / `buildNumber` instead of hardcoded strings in `platform.ts` | +| **Feature flags in UI** | Gate experimental mobile surfaces with `isFeatureEnabled` where web uses flags | +| **Accessibility** | `accessibilityLabel` on tab icons and primary actions | +| **Theme** | Prefer shared tokens from `@bytelyst/design-tokens` / `theme/` consistently | + +**Done criteria:** typecheck + tests; reflect changes in [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md). + +--- + +## Block H — RNTL + smoke tests + +### H.1 Infrastructure + +- [ ] Add **`@testing-library/react-native`** to `mobile` `devDependencies` +- [ ] Extend `mobile/vitest.config.ts` for component tests + any RN mocks + +### H.2 Minimum tests + +- [ ] **Auth screen** — submit / error path (mock store or API) +- [ ] **One tab screen** — render with mocked stores + +### H.3 Done criteria + +- [ ] `cd mobile && pnpm test` +- [ ] Update [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md) +- [ ] Commit: `test(mobile): RNTL setup and smoke tests` + +--- + +## Block I — Optional sync engine (`@bytelyst/sync`) + +**Last.** Mobile currently hydrates via **REST + Zustand**. Replacing with **`@bytelyst/sync`** requires mapping entities (notes, workspaces, inbox) to backend contracts and conflict rules — verify with backend before swapping. + +### I.1 Done criteria (only if attempted) + +- [ ] Parity with current hydration + offline behavior +- [ ] Update [`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md) +- [ ] Commit: `feat(mobile): adopt @bytelyst/sync` (large; may split) + +--- + +## 3 — After every block + +1. `cd mobile && pnpm run typecheck` +2. `cd mobile && pnpm test` +3. Sync **[`AGENT_TASK_ROADMAP.md`](./AGENT_TASK_ROADMAP.md)** +4. Commit with a clear message; push to remote +5. If block descriptions drift, update **this file** in the same PR + +--- + +## 4 — Reference paths + +| Area | Path | +|------|------| +| Root layout | `mobile/src/app/_layout.tsx` | +| Auth | `mobile/src/app/auth.tsx`, `mobile/src/store/auth-store.ts` | +| Platform init | `mobile/src/lib/platform.ts` | +| API | `mobile/src/api/client.ts`, `mobile/src/api/config.ts` | +| Workspace definition | `pnpm-workspace.yaml` | + +--- + +**End of delegation roadmap.** Point your agent at: **`docs/MOBILE_DELEGATION_ROADMAP.md`**.