visionA/local-tool/.autoflow/03-design/design-cross-review.md
jim800121chen c54f16fca0 Initial commit: visionA monorepo with local-tool subproject
local-tool/: visionA-local desktop app
- M1: Wails shell + Go server + Next.js UI + Mock mode (macOS dmg ready)
- M2: i18n (zh-TW/en) + Settings 4-tab refactor
- M3: Embedded Python 3.12 runtime (python-build-standalone) + KneronPLUS wheels
- M4: Windows Inno Setup script (build on Windows runner)
- M5: Linux AppImage script + udev rule (build on Linux runner)
- M6: ffmpeg (GPL, pending legal review) + yt-dlp bundled
- Lifecycle: watchServer health check, fatal native dialog,
            Wails IPC raise endpoint, stale process cleanup

.autoflow/: full PRD / Design Spec / Architecture / Testing docs
            (4 rounds tri-party discussion + cross review)
.github/workflows/: macOS / Windows / Linux build CI

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:10:38 +08:00

153 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Design 交叉審閱報告
> 審閱者Design Agent日期2026-04-11第三輪文件完成後
> 審閱對象PM PRD`02-prd/`、Architect TDD + Design Doc`04-architecture/`
> 立場:從 UX 角度檢視產品需求與技術方案是否會衝擊使用者體驗
---
## ✅ 對齊的項目
1. **三方都確認砍掉 tray**PRD §3 非目標、TDD §8`tray-and-lifecycle.md`、Design §5 一致。
2. **macOS 資料目錄統一為 `~/Library/Application Support/visiona-local/`**Q-E1PRD `user-flows.md`、Architect `architecture-overview.md §4.2`、Design `04-first-run.md §4.1` 路徑一致。
3. **Workspace 升 sidebar 一級**Q-E2PRD feature-inventory、Design IA、Architect code-reuse-plan 三處都標註。
4. **Mock 模式預設關閉、需明確選擇**PRD AC-2.1、Design `04-first-run.md §4.4`、Architect `deviceMgr.mockMode` flag 一致。
5. **Settings 4 分頁結構**Q-E3PRD、Design 一致採「一般/硬體/模型/進階」。
6. **首次啟動體驗可跳過**PRD `user-flows.md §5.2`、Design `04-first-run.md §4.2` 都明確三步皆可略過。
---
## ⚠️ 發現的問題
### 對 PM 的問題
- **D→PM-01 [🟡]** **「首次推論 ≤ 15 秒」的 AC 與 First-Run 三步流程衝突。**
PRD `nonfunctional.md §6.1` 的驗收值寫「app 啟動 → Mock 第一幀 ≤ 15 秒」,但 Design `04-first-run.md` 的首次流程是**歡迎 → 模式選擇 → 硬體偵測(真實模式時要掃 10 秒)**,在真實模式下光硬體掃描 timeout 就 10 秒,不可能 15 秒到第一幀。建議:把 AC 拆成「首次(含 First-Run≤ 30 秒」與「回訪(跳過 First-Run≤ 15 秒」兩個指標,否則測試會一律 fail。
- **D→PM-02 [🟡]** **`user-flows.md §5.3.1` 步驟 3「啟動 Go server < 2 TDD `tray-and-lifecycle.md §4.1` `waitHealthy(10s)` 不一致。**
PM 「< 2 」,Architect 給自己留了 10 timeoutDesign 需要知道真實值才能決定 First-Run 是否要插 skeletonsplash建議 PM Architect 對齊Design 才能設計正確的 loading 體驗
- **DPM-03 [🟢]** **Error flow `5.4.1` Port 3721 被佔用的文案與 Architect 不符。**
PRD 請關閉占用該埠的程式或在 Settings 變更 port」, TDD `tray-and-lifecycle.md §3.2` `pickPort()` **自動挑 37223723...**根本不需要使用者介入兩邊敘述衝突Design `08-states.md` 我暫時沿用 PRD 但若採 Architect 自動挑 port應改成 info toast已改用 port 3722」。
- **DPM-04 [🟢]** **`nonfunctional.md §6.8.3` 不做額外無障礙驗證」, Design `09-accessibility.md` WCAG 2.2 AA 承諾衝突。**
Design 規格第三輪明確寫 WCAG 2.2 AA鍵盤 tab 順序ARIA label建議 PRD 在非功能需求同步把 a11y 拉到必達等級 Design 降級兩邊必須一致
- **DPM-05 [🟢]** **Non-goals 文字微矛盾。** PRD `feature-inventory.md` 原生 menu barFile New Device / Upload Model)」, `vision-and-non-goals.md` 暗示不做 quick action」。menu bar 其實就是 quick action 的一種建議 PM 不做 tray menu bar的界線在 non-goals 裡寫清楚避免未來有人誤解成 menu bar 都不能做」。
### 對 Architect 的問題
- **DArch-01 [🔴]** **完整冷啟時間沒有明確預算,影響 First-Run AC。**
Architect `TDD.md §5` 只寫冷啟 < 5 」,但三層程序Wails Go server 首次 scan spawn Python sidecar的疊加時間沒拆開Design 需要知道
- Wails WebView 載入 Next.js?
- Go server `waitHealthy`最多 10
- Python sidecar 首次 spawn + KneronPLUS import? 實測一下KneronPLUS 通常要 2-3
若總和超過 5 Design `04-first-run.md §4.5 Phase 1` 掃描 USB 進度條需要改成「**準備硬體子系統中...**」以免使用者誤以為 USB 掃描很慢。** Architect M1 後補上實測數字。**
- **DArch-02 [🔴]** **Port picking 導致使用者書籤/歷史的 URL 不穩。**
`tray-and-lifecycle.md §3.2` 決定3721 被佔 往上挑 37223723」, WebView `http://127.0.0.1:{port}/`使用者**不會**直接開瀏覽器書籤 localhostWails 殼包住 WebView這對一般使用者 OK但對進階使用者想用 Chrome DevTools 」「Settings 要顯示實際 port的情境要設計出口
**Design 建議** Settings > 進階新增唯讀欄位「目前 Server Port3722」+「複製」按鈕Dashboard Server Status 卡片也顯示實際 port。TDD 目前只寫「Server logs 印 warning」不夠。
- **D→Arch-03 [🟡]** **Single-instance 第二次雙擊的 UX 未定義。**
`tray-and-lifecycle.md §2.3` 說收到 `/ipc/raise``WindowShow(ctx)` 浮到前面。Design 需要確認:
1. 第二個程序啟動是**完全靜默**(只 raise沒有任何提示還是**顯示 toast**(「已有另一個 visionA-local 在執行中」)?
2. macOS 從 Dock click 的行為由 Cocoa 處理,但 Linux AppImage 每次都是新程序體驗不一致——Design 建議三平台統一走「靜默 raise + 可選 toast」。
3. 如果 `raiseExistingInstance()` 失敗(例如 IPC port 讀不到),目前邏輯是覆寫 lock、視為新程序——這會造成使用者看到「兩個視窗」**非常糟糕**。建議改為「失敗即顯示錯誤 modal + 退出」。
- **D→Arch-04 [🟡]** **Python sidecar crash 的 UI 呈現缺失。**
`tray-and-lifecycle.md §4.3` 寫「Python sidecar 空閒 N 分鐘自動 kill、崩潰時 Go server 自動重啟最多 3 次」。Design 需要知道:
1. 重啟那 1-2 秒使用者會看到什麼?目前的推論畫面會卡住/白屏?
2. 3 次失敗後呈現的錯誤頁需要內容Design `08-states.md` 只有通用 Critical error template沒有 sidecar-specific
3. 自動 kill閒置省記憶體後下一次使用者點推論Design 需要顯示「正在重新啟動推論引擎...」spinner否則 Start 按鈕按下後會有 2-3 秒無回應。
**建議 Architect 新增事件 `POST /ws/server-logs` 類型 `sidecar.state` 讓前端訂閱**Design 才能做對應 UI。
- **D→Arch-05 [🟡]** **Python 雙策略A 內嵌 / B 系統)切換沒有 UI 入口。**
`dependency-bundling.md §1.5` 寫可透過 `--python-mode=bundled|system` CLI flag 切換,但使用者不會跑 CLI。Design 規格 Settings > 進階 應該有「Python 執行模式:內嵌(目前)/ 系統/ 自動」的唯讀顯示 + 重設按鈕。**Design 這邊會補 wireframe但需要 Architect 確認前端能讀 `.installed` meta 的 API目前 `/api/system/deps` 是否涵蓋?)。**
- **D→Arch-06 [🟡]** **資料目錄遷移/升級情境未處理。**
Architect 第三輪把 macOS 資料目錄從 `~/.visiona-local/` 改到 `~/Library/Application Support/visiona-local/`Q-E1**`edge-ai-platform` 舊使用者**可能已有 `~/.visiona-local/` 的資料。雖然 visionA-local 是新專案沒有「升級」概念,但**如果使用者曾經裝過 edge-ai-platform 的 local 模式**有些人可能有啟動時要不要偵測舊路徑、詢問是否遷移Design 建議:**M1 範圍內不處理,但 First-Run 增加一段說明「若你之前用過舊版 visionA請手動搬移 `~/.visiona-local/` 到新路徑」**。Architect 是否同意不自動遷移?
- **D→Arch-07 [🟢]** **`watchServer()` 健康檢查頻率 10 秒對 UX 太慢。**
`tray-and-lifecycle.md §4.2` 寫每 10 秒 healthcheck、失敗 3 次才判定掛掉,代表使用者最糟要等 **30 秒**才看到錯誤。建議縮短為「每 3 秒、失敗 2 次」= 6 秒內可感知。
- **D→Arch-08 [🟢]** **macOS 第二個程序的 `⌘N`「新增視窗」語意未定義。**
砍掉 tray 後,`feature-inventory.md §4.5` 提到 menu bar 有「File → New Device」。但 macOS 慣例 File menu 常有「New Window (`⌘N`)」——我們是單例 app這個快捷鍵要完全拿掉還是改成「新增裝置」Design 建議改成「New Device (`⌘N`)」避免衝突。
---
## 📋 R9 Plan B 的 First-Run 下載流程草案
若 Kneron 不允許 re-distribution預置 `.nef` 無法內嵌,首次啟動必須線上下載 ~73MB 模型。Design 設計以下 fallback UX
**流程修改:** 在現有 First-Run Step 2模式選擇與 Step 3硬體偵測之間**插入一個新步驟 2.5「下載預置模型」**。
```
Step 1 歡迎 → Step 2 模式選擇 → [NEW] Step 2.5 下載模型 → Step 3 硬體偵測 → Dashboard
```
**Step 2.5 Wireframe**
```
┌─────────────────────────────────────────────────────┐
│ [略過 →] │
│ │
│ 下載預置 AI 模型 │
│ 首次使用需要下載約 73 MB 的範例模型 │
│ │
│ ┌──────────────────────────────────────┐ │
│ │ 📦 fd_mask.nef 14 MB ✓ │ │
│ │ 📦 yolov5s.nef 18 MB ⟳ │ │
│ │ 📦 resnet50.nef 22 MB … │ │
│ │ 📦 mobilenet.nef 8 MB … │ │
│ │ 📦 tiny_yolo.nef 11 MB … │ │
│ └──────────────────────────────────────┘ │
│ │
│ 整體進度:[■■■■□□□□□□] 40% (29 MB / 73 MB) │
│ 預估剩餘45 秒 │
│ │
│ 來源Innovedus 內部 CDN │
│ │
│ ⓘ 若要完全離線使用,請聯絡 IT 取得完整安裝包 │
│ │
│ [取消下載] [暫停] │
│ │
│ 2.5 / 3 │
└─────────────────────────────────────────────────────┘
```
**互動規則:**
1. **離線偵測**Wails app 啟動時先 ping Innovedus 內部 CDNHEAD 請求5 秒 timeout。無法連線 → 顯示「離線提示卡」:「目前無法連線到模型伺服器。你可以 (A) 稍後重試 (B) 改用 Mock 模式 (C) 手動放置 .nef 到 `<APPDATA>/data/nef/`」。
2. **斷線續傳**:每個模型用獨立 HTTP request失敗可單獨重試不重新下載已完成的。
3. **跳過**:「略過」→ 直接進 Step 3但 Models 頁會顯示空狀態「還沒有預置模型,請到 Settings > 進階 下載」。
4. **完成條件**:至少 1 個模型下載成功即可繼續0 個則強制退回 Step 2 選 Mock。
5. **Settings 入口**Settings > 進階 新增「重新下載預置模型」按鈕,使用者可隨時補。
**連帶影響(給 PM** PRD §6.4「離線可用」承諾必須加註解:「**例外**:若 R9 Plan B 觸發,首次啟動需一次性下載 ~73 MB 預置模型。後續使用仍完全離線。」
**Design 估計**Plan B 的 First-Run UI 工作量約 0.5 人週(只新增 1 個 step + 1 個 Settings 按鈕 + 文案)。
---
## ❓ 需要使用者或三方討論的問題
1. **D→PM-01 的 AC 拆分**使用者想要「15 秒」適用於所有情境,還是接受「首次 30 秒 / 回訪 15 秒」?
2. **D→Arch-02 的實際 port 顯示位置**Settings > 進階?還是 Dashboard Server 狀態卡?
3. **D→Arch-06 舊專案資料目錄遷移**:要不要自動偵測 `~/.visiona-local/` 並提示使用者?
4. **R9 Plan B 觸發時**,內部 CDN 是否可用PM 需要與 Innovedus IT 先確認,避免 Plan B 時再花時間找 host。
5. **macOS `⌘N` 快捷鍵**D→Arch-08要綁什麼動作
---
## 結論
**整體結論:三方文件一致性高,砍 tray、Workspace 升一級、Settings 4 分頁、macOS 資料路徑這幾個第三輪決策都有落實到各自的文件裡。**
主要風險在於**三層程序的啟動時間沒有被端到端量化**D→Arch-01這會直接影響到 First-Run 與 NFR §6.1 的 AC 能不能達成,建議 Architect 在 M1 結束時就實測並回填。
次要問題是一些**邊界情境的 UX 未被 Architect 顯式處理**port picking 的 UI 呈現、second-instance 的提示、sidecar crashauto-kill 的 loading 狀態、Python 雙策略的切換入口。這些不是 blocker 但會影響「順手、穩定」的使用體驗,建議 Architect 在 M3 前補齊 API 事件(`sidecar.state`、實際 port 查詢)讓 Design 能接著做 UI。
R9 Plan B 的 First-Run 下載流程已草擬Design 工作量可控(~0.5 人週),但**內部 CDN 可用性需要 PM 先確認**,避免真的觸發 Plan B 時措手不及。
**Design Agent 對 PRD 與 TDD 第三輪版的整體結論:原則上可進入實作階段,但上述 🔴 問題 2 條D→Arch-01、D→Arch-02建議在 M1 開始前先補,避免後續返工。其餘 🟡 🟢 可在 M2-M3 迭代解決。**