Skip to content

Commit e79064c

Browse files
committed
docs: PWA 移动端实施计划(T0-M4 + Phase 1.5 任务拆解)
1 parent 4979757 commit e79064c

1 file changed

Lines changed: 192 additions & 0 deletions

File tree

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# 熵减移动端 PWA 版 Implementation Plan
2+
3+
> **For agentic workers:** 按任务顺序逐 Task 实施,Step 使用 checkbox(`- [ ]`)跟踪。
4+
> **Spec:** `docs/superpowers/specs/2026-08-16-pwa-mobile-design.md`(v2 已定稿)
5+
6+
**Goal:** 在现有代码库上增加第二条运行时——PWA(iOS Safari / Android Chrome),首批交付:番茄钟、空白笔记、课堂助手(麦克风录音转写 + 视频转笔记)、桌面↔移动账号同步。移动端本轮只保证**布局可用 + 功能完整**,不含 UI 视觉美化(Spec §1.3)。
7+
8+
**Architecture:** 复用现有双模式基座(`storageFactory` PWA/Dexie 分支、ASR 云端降级链、墙钟校准计时);新增 `WebCaptureAdapter`(getUserMedia + MediaRecorder + 云端分段 ASR)与视频导入链路(复用网关 `/api/v1/multimodal/analyze-video`);同步复用 sync-service + OfflineQueue + Automerge。
9+
10+
**Tech Stack:** React 18 + Vite(VitePWA 已配置)、TypeScript、Dexie/IndexedDB、TipTap、Zustand、Web Notification API、supabase-js、Go sync-service(浏览器 WebSocket 直连)。Phase 1.5 可选项:sherpa-onnx-web(WASM + onnxruntime-web)。
11+
12+
**关键约束:**
13+
- 桌面路径**零回归**:所有新增 PWA 分支必须经 `window.electronAPI` 存在性判定,Electron 原有行为不变(Spec §3.2 适配器模式)。
14+
- PWA 下禁止调用未守卫的 IPC;`refreshLocalAsrStatus()` 在无 electronAPI 时已返回 false(自动走云端),不得绕过。
15+
- 存储:PWA 走 Dexie;IndexedDB→SQLite 迁移**仅存在于 Electron 首次启动**,PWA 侧禁止反向迁移(Spec F1)。
16+
- **CORS 前置项**:浏览器直连 AI 网关需确认/新增网关 CORS 允许源(桌面 Electron 无此问题,T0.2 验证)。
17+
- 部署必须 HTTPS(PWA SW 与 getUserMedia 的 secure context 要求)。
18+
- 单文件 ≤300 行、`@ai-context` 中英双语注释(项目规范);`npm run check` 门禁(lint --deny-warnings / typecheck×2 / test)。
19+
- 移动端验证:Chrome DevTools 设备模拟器 + 真机(iOS Safari / Android Chrome)双轨。
20+
21+
---
22+
23+
## T0: 前置验证(0.5–1 天,阻塞性)
24+
25+
**Files:** `client/vite.config.ts`、`server/ai-gateway`(CORS 中间件)、`client/src/lib/http/apiClient.ts`
26+
27+
- [ ] **Step 1: web 构建冒烟** — `cd client && vite build`(非 ELECTRON_BUILD)产出含 SW/manifest 的 PWA 产物;静态服务打开,确认 `navigator.serviceWorker` 注册成功、manifest 生效
28+
- [ ] **Step 2: 浏览器登录 + AI 调用验证** — 浏览器模式下 supabase 登录成功;远程 AI 调用(如 `/api/v1/...`)无 CORS 报错;若报错,在 ai-gateway 中间件新增允许源配置(生产源 + localhost)
29+
- [ ] **Step 3: 存储双模式冒烟** — 无 electronAPI 环境下 `createAllStores()` 落 Dexie,笔记 CRUD 通过
30+
- [ ] **验收**:web 产物可访问、登录成功、AI 调用无 CORS 错误、Dexie 存储可用;阻塞项全部清零
31+
32+
## M1: 横切基建 + 番茄钟(第 1 周,~1 周)
33+
34+
### Task 1: PWA 部署目标与 manifest 完善(0.5 天)
35+
36+
**Files:** `client/vite.config.ts`、`client/public/`(icon/manifest 字段)
37+
38+
- [ ] **Step 1:** manifest 补齐:`display: standalone`、`orientation`、启动图/图标尺寸(iOS 需 apple-touch-icon)、主题色
39+
- [ ] **Step 2:** 部署目标落地:静态托管(nginx/对象存储)+ HTTPS;确定生产 URL 并在 T0.2 CORS 源中登记
40+
- [ ] **验收**:iOS Safari"添加到主屏幕"后以 standalone 模式启动、图标正常
41+
42+
### Task 2: 移动端导航与响应式布局结构(1 天)
43+
44+
**Files:** `client/src/App.tsx`、`client/src/components/layout/`、`client/src/styles/`
45+
46+
- [ ] **Step 1:** 移动端导航:按设计系统既有方案(BottomNav / 汉堡菜单,见 docs/archive/superdesign-init/layouts.md)接入路由;桌面布局不变,窄屏切换移动导航
47+
- [ ] **Step 2:** 全局容器响应式:viewport meta、safe-area-inset、`100dvh` 处理(iOS 地址栏)、滚动容器
48+
- [ ] **Step 3:** 三个目标模块路由可达(番茄钟/笔记/课堂),其余路由保持桌面入口或占位
49+
- [ ] **验收**:360–430px 下导航可用、无横向溢出;桌面端布局零变化
50+
51+
### Task 3: iOS Safari 平台细节(1 天)
52+
53+
**Files:** `client/src/lib/`(audio 工具)、`client/src/hooks/useReducedMotion.ts`
54+
55+
- [ ] **Step 1:** AudioContext 用户手势解锁:所有音频播放(番茄钟音效/录音提示音)在首次触摸后 resume
56+
- [ ] **Step 2:** 字体/缩放:`font-size` 与 `text-size-adjust` 防 iOS 自动缩放;输入框聚焦不缩放
57+
- [ ] **验收**:iOS Safari 上音效首触可播、无自动缩放异常
58+
59+
### Task 4: 番茄钟移动端(1–1.5 天)
60+
61+
**Files:** `client/src/features/pomodoro/pages/`、`components/`(TimerFace/ImmersiveTimer/设置/统计)
62+
63+
- [ ] **Step 1:** 响应式布局:计时主界面/沉浸页/设置页/统计页窄屏可用(按钮可达、无遮挡、可滚动)
64+
- [ ] **Step 2:** 通知流程验证:Web Notification 权限申请 + 到点通知(`sendNotification` 已现成,F3)
65+
- [ ] **Step 3:** 后台节流验证:切后台/锁屏 ≥5 分钟恢复,墙钟校准不漂移(tickSlice 已实现,验证即可)
66+
- [ ] **验收**:手机端完整番茄流程(启动→专注→休息→统计)可用;后台 5 分钟不漂移;通知可达
67+
68+
## M2: 空白笔记 + 同步(第 2–5 周,~3–4 周)
69+
70+
### Task 5: 笔记存储与数据链路验证(1 天)
71+
72+
**Files:** `client/src/features/notes/`(store/lib)、`client/src/lib/storage/`
73+
74+
- [ ] **Step 1:** PWA 模式下笔记 CRUD/文件夹/搜索(Dexie 全表)/链接/标签全链路验证,修复 PWA 分支缺陷
75+
- [ ] **Step 2:** 笔记加密/导出导入在浏览器环境的行为确认(`backupCrypto` 为纯 TS,验证即可)
76+
- [ ] **验收**:移动端笔记全数据链路可用;无 electronAPI 时无报错(F4 守卫确认)
77+
78+
### Task 6: 编辑器布局适配(功能向,1.5–2 周,最大单项)
79+
80+
**Files:** `client/src/features/notes/components/editor/`、`NoteEditPage.tsx`、`EditorToolbar.tsx`
81+
82+
- [ ] **Step 1:** 工具栏窄屏折叠(溢出项收纳,不遮挡内容)
83+
- [ ] **Step 2:** 触摸可用:选区/光标操作、滑动滚动、触摸目标 ≥44px(关键操作)
84+
- [ ] **Step 3:** 虚拟键盘:输入时内容不遮挡(`visualViewport` 监听或 fixed 布局修正)
85+
- [ ] **Step 4:** 图片插入:`<input type="file" accept="image/*">` 替代粘贴(桌面粘贴路径保留)
86+
- [ ] **Step 5:** 移动端只读/阅读模式可用(若已有 useNoteReadingMode 则验证)
87+
- [ ] **验收**:手机上可新建/编辑/插图/保存笔记,无输入遮挡、无工具栏溢出
88+
89+
### Task 7: 剪藏/PDF 浏览器替代(1 天)
90+
91+
**Files:** `client/src/features/notes/hooks/useClipImport.ts`、`package.json`
92+
93+
- [ ] **Step 1:** URL 剪藏:浏览器 fetch(CORS 允许的站点可用;受限站点提示降级);不可用时隐藏入口
94+
- [ ] **Step 2:** PDF 解析:引入 pdf.js 或裁剪(仅移动端路径),解析后走既有内容入库
95+
- [ ] **验收**:移动端剪藏/PDF 导入可用或明确降级提示,无死链 UI
96+
97+
### Task 8: 桌面↔移动同步(1–1.5 周)
98+
99+
**Files:** `client/src/lib/sync/`(OfflineQueue/同步客户端)、`client/src/lib/auth/supabaseClient.ts`、`server/sync-service/`
100+
101+
- [ ] **Step 1:** 账号绑定流程:PWA 登录(supabase-js 已验证)→ 设备注册 → 同步凭证获取
102+
- [ ] **Step 2:** 浏览器 WebSocket 直连 sync-service 验证(CORS/协议层确认)
103+
- [ ] **Step 3:** OfflineQueue 浏览器环境测试(现有测试为 jsdom,补真浏览器行为验证)
104+
- [ ] **Step 4:** 冲突策略确认:桌面↔移动双写场景(Automerge CRDT + syncConflicts 表现层)
105+
- [ ] **验收**:同一账号桌面↔移动双向增量同步;离线操作入队、恢复后补齐;冲突可见可解
106+
107+
## M3: 课堂助手(第 2–6 周,~3–4 周;与 M2 并行)
108+
109+
### Task 9: WebCaptureAdapter(1.5–2 周,核心件)
110+
111+
**Files:** 新增 `client/src/features/classroom/capture/WebCaptureAdapter.ts`、`client/src/lib/audio/`(浏览器侧)
112+
113+
- [ ] **Step 1:** getUserMedia 麦克风采集(16kHz 单声道:AudioWorklet/ScriptProcessor 降采样,复用 asrFilters 处理链)
114+
- [ ] **Step 2:** MediaRecorder 分段(5–15s)+ 每段转码为云端 ASR 所需格式
115+
- [ ] **Step 3:** `CaptureAdapter` 接口定义(含现有 Electron 路径能力枚举:captureType/windowless 模式),`useSessionControl`/`useClassroomEvents` 加环境分支
116+
- [ ] **Step 4:** 移动端隐藏窗口选择/屏幕采集/系统音频 UI(`WindowSelectCard`/Vision 入口等按环境条件渲染)
117+
- [ ] **Step 5:** 会话中断恢复:标签切后台录音停止→前台恢复续录(复用/对齐 useAudioRecovery 语义)
118+
- [ ] **验收**:手机麦克风录音→分段→云端转写(transcribeWithRetry 现成链路)文本回流;后台切换不崩溃、可恢复
119+
120+
### Task 10: 视频转笔记(1–1.5 天)
121+
122+
**Files:** `client/src/features/classroom/`(新增导入入口)、`client/src/lib/ai/`(上传调用)
123+
124+
- [ ] **Step 1:** 文件选择 UI(`<input type="file" accept="video/*">`)+ 上传进度 + 取消
125+
- [ ] **Step 2:** 复用网关 `POST /api/v1/multimodal/analyze-video`(≤500MB、300s 超时,对齐 videoAnalyzeHandler 契约)
126+
- [ ] **Step 3:** 结果入库:结构化笔记写入 notes 存储(复用 noteGenerator/既有生成链路)
127+
- [ ] **验收**:导入手机录屏/网课视频 → 生成结构化笔记入库;失败有明确提示
128+
129+
### Task 11: 课堂会话页响应式布局(0.5–1 天)
130+
131+
**Files:** `client/src/features/classroom/pages/ClassroomPage.tsx`、`components/`(SessionContentView/UnifiedTimeline/QA 面板)
132+
133+
- [ ] **Step 1:** 会话控制(开始/暂停/停止)、转写流、分段列表、QA 面板窄屏布局可用
134+
- [ ] **验收**:手机上完整课堂会话流程可操作,无遮挡溢出
135+
136+
## M4: 联调与发布(第 8–11 周,~1–1.5 周)
137+
138+
### Task 12: 双端回归与移动端专项测试(3–4 天)
139+
140+
**Files:** 全量(回归)+ `client/src/**/*.test.ts`(新增 PWA 分支测试)
141+
142+
- [ ] **Step 1:** Electron 桌面回归:`npm run check` + 手工冒烟(笔记/番茄钟/课堂桌面路径不变)
143+
- [ ] **Step 2:** 真机专项:iOS Safari(音频/通知/键盘/后台)+ Android Chrome(同上)验收清单执行
144+
- [ ] **Step 3:** 长会话性能:课堂 60 分钟录音转写内存/队列表现;番茄钟长开漂移测试
145+
- [ ] **Step 4:** 新增 PWA 分支单测(适配器环境判定、降级路径、存储双模式)纳入 `npm run check`
146+
- [ ] **验收**:Spec §6 验收标准 1–8 全部通过
147+
148+
### Task 13: 发布(1–2 天)
149+
150+
**Files:** 部署配置、`docs/`(使用说明)
151+
152+
- [ ] **Step 1:** 部署生产 PWA(HTTPS)+ 网关 CORS 最终确认
153+
- [ ] **Step 2:** 内测指引文档(添加主屏幕、通知权限、桌面↔移动同步说明)
154+
- [ ] **验收**:外网 URL 可安装、内测用户全流程可用
155+
156+
## Phase 1.5(可选,+1.5–2.5 周):端侧 WASM 流式转写
157+
158+
### Task 14: StreamingAsrProvider 抽象 + WASM 实现
159+
160+
**Files:** 新增 `client/src/lib/asr/`(接口 + 两实现)、改造 `client/electron/ai/local-asr/streamingAsr.ts`(提炼共享编排层)
161+
162+
- [ ] **Step 1:** 从 streamingAsr.ts 提炼平台无关编排层(partial 节流/端点断句/热词/静音跳过/SenseVoice 重打分)
163+
- [ ] **Step 2:** `SherpaNodeProvider`(桌面,保留原生,行为不变)+ `SherpaWasmProvider`(web worker + sherpa-onnx-web,WASM+SIMD)
164+
- [ ] **Step 3:** 桌面降级路径:原生加载失败 → WASM(缓解 node-gyp CI 痛点)
165+
- [ ] **Step 4:** 模型分发:移动端模型下载/缓存(IndexedDB/Cache Storage)
166+
- [ ] **验收**:桌面原生性能不变;移动端流式 partial 延迟 <2s、可离线;桌面原生失败可降级 WASM
167+
168+
---
169+
170+
## 依赖关系与关键路径
171+
172+
```
173+
T0(阻塞前置)
174+
└─ M1(Task 1→2→3→4,串行 1 周)
175+
├─ M2:Task 5 → 6(最长)→ 7;Task 8 依赖 Task 5,可与 6/7 并行
176+
└─ M3:Task 9 → 10 → 11(M2 与 M3 并行,共享 M1 基座)
177+
└─ M4:Task 12(依赖 M2+M3 完成)→ Task 13
178+
Phase 1.5:Task 14 依赖 Task 9(采集链路)与 M1
179+
```
180+
181+
关键路径:T0 → M1 → M2(Task 6 编辑器为最大单项)→ M4 ≈ **9–13 周(单人)**;M3 与 M2 并行后总窗口不变;2 人并行时 M2/M3 各归一人,**5–7 周**。
182+
183+
## 工作量汇总(与 Spec §4 对齐)
184+
185+
| 阶段 | 任务 | 工期(单人) |
186+
|---|---|---|
187+
| T0 | 前置验证 | 0.5–1 天 |
188+
| M1 | Task 1–4(基建+番茄钟) | 1 周 |
189+
| M2 | Task 5–8(笔记+同步) | 3–4 周 |
190+
| M3 | Task 9–11(课堂助手) | 3–4 周(与 M2 并行) |
191+
| M4 | Task 12–13(联调发布) | 1–1.5 周 |
192+
| Phase 1.5 | Task 14(WASM 流式,可选) | +1.5–2.5 周 |

0 commit comments

Comments
 (0)