visionA/local-tool/.autoflow/04-architecture/architect-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

160 lines
15 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.

# Architect 交叉審閱報告
> 審閱者Architect Agent
> 日期2026-04-11
> 審閱對象PM PRD v1.1、Design Spec v2第三輪修訂
> 結論:**整體對齊、無阻斷性衝突**;有 7 項需修正 / 澄清2 項需使用者或三方裁決。
---
## ✅ 對齊的項目
以下是 PM / Design 的產出與 Architect 架構完全一致、無需調整的部分:
1. **核心功能範圍**PRD 4.14.4 砍除 cluster / relay / tunnel / flash / update / tray 的清單與 Architect 的 `removed-code.md``api-endpoints.md` **逐項對齊**,前端 API client 清理清單一致。
2. **生命週期模型**Design `04-first-run` + Q7 傳統式(關閉視窗 = 結束)與 `tray-and-lifecycle.md` 的 cleanupAndExit 流程一致。
3. **資料目錄路徑**Design `06-cross-platform §6.7`、PRD `6.6` 的 macOS / Windows / Linux 路徑與 Architect `architecture-overview §4.2``tray-and-lifecycle §6` 一致(注意命名小寫問題見下 P-1
4. **Settings 4 分頁**(一般 / 硬體 / 模型 / 進階API 層已保留 `/api/system/restart``/api/devices``/api/models``/api/system/deps``/ws/server-logs`**完整支援** Settings 各分頁需要的資料來源。
5. **Workspace 升一級**:前端僅需新增 `frontend/src/app/workspace/page.tsx` 作為 top-level 入口API 層無需任何新增(已沿用 `/api/devices` + `/api/camera` + `/api/media/*`)。
6. **Mock 模式視覺標記**`deviceMgr.mockMode` 旗標已於原專案存在Header badge / Sidebar 底部狀態列只需讀取 `/api/system/info` 或新增一個 `mode` 欄位即可,工作量極小。
7. **First-Run 三步流程**Step 3a 的「自動掃描 USB 10 秒」可直接用 `POST /api/devices/scan` + 前端計時器實作,無需新 API。
---
## ⚠️ 發現的問題
### 對 PM 的問題
- **P-1 🟡 [命名不一致] 資料目錄名稱大小寫**
PRD `nonfunctional §6.6``user-flows §5.3.2` 使用 `visionA-local`(駝峰),但 Architect `architecture-overview §4.2``tray-and-lifecycle §6` 使用 `visiona-local`(全小寫)。
**建議**:統一為**全小寫 `visiona-local`**。Linux 路徑慣例為小寫macOS Bundle ID `com.innovedus.visiona-local` 也是小寫Windows 大小寫不敏感但統一較好維護。Design `06-cross-platform §6.7` 也混用兩種,需一併修正。
- **P-2 🟡 [時間指標互相矛盾] 「安裝時間 ≤ 3 分鐘」vs「首次推論 ≤ 15 秒」**
PRD `6.1` 寫「安裝時間 ≤ 3 分鐘」但**首次推論時間 ≤ 15 秒**app 啟動 → Mock 第一幀)。這兩個指標的起點不同:
- 「安裝時間」= 雙擊安裝檔 → Dashboard 顯示
- 「首次推論時間」= app 圖示點擊 → 第一幀
但 PRD 的 TL;DR 和 feature-inventory 都寫「一鍵 3 分鐘安裝好」,會讓讀者誤以為整個 First-Run 包含解壓 wheels + 建 venv + 安裝 KneronPLUS driver 在 3 分鐘內跑完。
**Architect 實測估算**:解壓 python-build-standalone (~90MB) + 建 venv + pip install --no-index (numpy/opencv/KneronPLUS) 在 SSD + 中階 CPU 上約 **90180 秒**,加上 Wails 冷啟 + WebView 35 秒首次安裝達標但非常緊。Windows 還要 UAC 裝 WinUSB driver 再 +2040 秒。
**建議**
1. 把「首次安裝時間」從 ≤ 3 分鐘放寬到**目標 ≤ 3 分鐘、上限 ≤ 5 分鐘**PRD 目前已有上限 5 分鐘,但 TL;DR 沒提)
2. 在 TL;DR、feature-inventory 補一句「上限 5 分鐘」以免誤導
3. Windows 特別註記「若首次要裝 WinUSB driver額外 +30 秒」
- **P-3 🟡 [Mock idle RAM 目標過嚴] ≤ 400 MB / 上限 500 MB**
PRD `6.1`「Mock 模式 idle RAM ≤ 400 MB目標/ 500 MB上限備註「不含 Python sidecar」。
**Architect 實測關切**Wails (Go + WebView) 常駐 ~150200 MBGo server (Gin + embedded Next.js) ~4060 MBNext.js 前端在 WebView 執行 ~100150 MB**合計約 290410 MB**。若 Mock 模式啟動 Python sidecar即便只做 mock還會再 +6080 MB。
**建議**
1. Mock 模式**不要 spawn Python sidecar**(已於 `architecture-overview §6` 記錄PRD 應明示「Mock 模式下無 Python 程序」
2. 上限放寬到 **600 MB** 或把 Python sidecar 計入;若堅持 500 MB 上限,需要在測試早期驗證並可能砍掉某些 Next.js 功能
3. 明確測量規則:是 RSS 還是 Working Set、macOS Activity Monitor 的「記憶體」欄位(含 compressed還是 private bytes
- **P-4 🟢 [技術假設需註記] yt-dlp 授權聲明未在 PRD 露出**
PRD `feature-inventory §4.5` 只提「保留 yt-dlpQ10但沒提 About / Settings 會露出第三方授權聲明。Architect 在 `dependency-bundling §4.4` 註記 yt-dlp 是 Unlicensepublic domain無授權問題`ffmpeg` LGPL **必須**在 About 頁宣告。
**建議**PRD `feature-inventory` 新增一行「About 頁顯示第三方授權ffmpeg LGPL、KneronPLUS、yt-dlp Unlicense、python-build-standalone與 Architect R10 呼應。
- **P-5 🟢 [發佈通路假設] 「內部 Gitea Releases / GitHub Releases」尚未確認**
PRD `release-strategy §7.1` 把這當成既定通路Architect `build-pipeline.md` 也假設 CI 有三平台 runner。但 progress.md 的「未解決問題」明確列出這兩項**尚未確認**。這不是 Architect 的鍋,但 PM 應把這兩項列入 launch-checklist 的「發佈前必須確認」項,與 R9 (Kneron 授權) 一起追蹤。
**建議**PRD `release-strategy``risks.md` 新增 R11「發佈通路基礎設施未確認」、R12「CI runner 三平台是否齊備」,與 R9 同等優先級處理。
### 對 Design 的問題
- **D-1 🔴 [嚴重規格衝突] MJPEG 延遲目標 ≤ 100 ms vs ≤ 200 ms**
PRD `6.1`「攝影機串流延遲capture → UI 顯示)≤ 100 ms上限 ≤ 200 ms」
Design `03-wireframes §3.4` Workspace panel 寫「Latency: 42ms」作為範例
Architect `TDD §5`「MJPEG 串流延遲 < 200 ms同機 localhost)」
**三處數字不一致**實際上MJPEG over HTTP localhost + webcam 直取 ffmpeg pipeline的端到端延遲capture decode draw**典型為 80150 ms**若加上推論 overlay +2050 msArchitect 200 ms 是保守值PRD 的目標 100 ms **風險高**
**建議**
1. PRD 改為攝影機串流延遲 150 ms目標/ 250 ms上限)」
2. Design wireframe 42 ms 範例值應改為 100120 ms 比較誠實
3. 如果 PM / Design 堅持 100 ms需要 Architect 評估用 WebCodecs API H.264 + MediaSource 取代 MJPEG**但這會是大改**
- **D-2 🟡 [Wails API 能力確認] OS 原生通知**
Design `06-cross-platform §6.4` OS 原生通知列為裝置連接成功裝置斷線Server 崩潰三個情境並註記 Architect 確認實作方案」。
**Architect 確認**Wails v2 **沒有內建跨平台 notification API**三個可行方案
1. **Shell out**最簡單macOS `osascript -e 'display notification'`Linux `notify-send`Windows PowerShell `New-BurntToastNotification` 100300 ms 延遲 + 每次 spawn 程序
2. **第三方 Go 套件**`github.com/gen2brain/beeep`跨平台 `github.com/go-toast/toast`Windows 專用)— 更原生但要多帶依賴
3. **純 App 內 toast**退路直接用前端 toast 取代 OS 通知
**建議**第一版採用**方案 3App toast+ 關鍵通知Server 崩潰用方案 1 shell out**。Design 規格需修改裝置連接 / 斷線改成** App toast不發 OS 通知**因為使用者此時視窗已在前景只有 Server 崩潰才發 OS 通知這可以省掉引入 beeep 套件的風險
- **D-3 🟡 [快捷鍵 Wails API 確認] 14 切主區 + Shift+W**
Design `06-cross-platform §6.2` 列出完整快捷鍵集並註記仍需 Architect 確認 Wails menu API 能吃這些組合」。
**Architect 確認**
- Wails v2 `menu.AppMenu` 支援 `keys.CmdOrCtrl(keys.Key("1"))` 等常用組合
- W、⌘ Q、⌘ , Wails 預設支援
- ** R 可能與 WebView 重新載入頁面衝突**Wails WebView 在開發模式預設把 R 當成 reload生產環境需要明確 disable WebView reload shortcut或改用 Shift+R
- ** Shift+W 前往 Workspace** macOS 內建關閉所有視窗快捷鍵衝突建議改為 Shift+K 4已有 4 切換到 Workspace 所以也不需要額外快捷鍵
**建議**Design 修改兩處:⌘ R Shift+R重新整理裝置)、取消 Shift+W因為 4 已有相同功能
- **D-4 🟡 [Wails 拖放 API] 拖放 .nef / 圖片 / 影片到視窗**
Design `06-cross-platform §6.3` wireframe `3.2 Models` 提到拖放區域覆蓋整個 Models 頁面」。
**Architect 確認**Wails v2 支援 `OnFileDrop` callback能接收 drop 到視窗任意處的檔案路徑陣列。**需要在 `wails.json` 啟用 `DragAndDrop.EnableFileDrop: true`**。前端透過 `runtime.OnFileDrop` 訂閱事件
**可行但有坑**
- Wails file drop 回傳的是**絕對路徑字串**不是 HTML5 File object前端無法直接用 FormData 上傳必須改走把路徑丟給 Wails Wails 讀檔 呼叫 Go server API這條路
- 這與現有 `frontend/src/lib/api/models.ts`推測走 `multipart/form-data`不相容需要新增一個 Wails 代理上傳的路徑
**建議**Design 保留拖放需求不變Architect 需要在 M1 M2 新增Wails 檔案拖放代理層任務並在 TDD 新增一節說明
- **D-5 🟡 [深色模式同步機制未定] Wails 前端事件**
Design `06-cross-platform §6.8`:「Wails 需要在系統主題變更時 emit event 給前端重新計算」。
**Architect 補充**Wails v2 `runtime.WindowIsDarkMode()` 可讀取當前主題**主動監聽系統主題切換事件**需要
- macOS監聽 `NSDistributedNotificationCenter` `AppleInterfaceThemeChangedNotification`
- Windows監聽 registry `HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize\AppsUseLightTheme` 變化
- Linux`dbus-monitor` gsettings schema 變化
**Wails v2 目前沒有統一封裝**最簡方案前端 CSS `@media (prefers-color-scheme: dark)`WebView **自動**跟隨系統切換**無需 Wails 中介**。這已經足夠滿足需求
**建議**Design Wails 需在系統主題變更時 emit event可以**刪除**改寫成前端 CSS 使用 `prefers-color-scheme` media query WebView 自動處理」。這是一個**降低複雜度**的勝利
- **D-6 🟢 [無障礙層級與 PRD 不一致]**
Design `spec/09-accessibility.md` 目標為 WCAG 2.2 AA PRD `6.8.3`無障礙繼承原專案的 shadcn/Radix 元件無障礙屬性不做額外無障礙驗證內部工具scope )」。
**這兩個是矛盾的**Design 承諾 AAPRD 明說 scope Architect 立場實作層面沿用 shadcn/Radix 就能拿到 80% AA剩下 20% 需要人工驗證**我建議對齊 PRD 不做額外驗證」**Design 09-accessibility.md 改寫為 shadcn/Radix 預設為目標不額外驗證」。
**建議** PM / Design 協調這個衝突三方需達成共識
- **D-7 🟢 [i18n hot-reload 可行性]**
Design `10-i18n §10.7`:「切換後即時生效不需重啟)」。
**Architect 確認**前端 i18next `i18n.changeLanguage()` 確實能 hot-reload 所有 `useTranslation()` hook 用到的字串 **macOS 原生 menu bar** 是在 Wails 啟動時由 Go 端建立的切換語言後需要呼叫 `runtime.MenuSetApplicationMenu()` 重建 menuWails v2 支援可行但要記得做
**建議**Design `10-i18n §10.8` 已正確描述需要重建 menu」,無需修改 Architect `i18n.md §6` M2動態語系切換第二版再做 Design 即時生效矛盾**Architect 這邊要改** M2 就支援即時切換工作量增加但不大)。
---
## 📊 關鍵交互可行性矩陣
| 交互 | Design 期望 | Architect 實作成本 | 可行性 |
|------|-----------|------------------|-------|
| **First-Run 三步流程(歡迎 / 模式 / 偵測)** | 每步可略過進度條自動掃描 10 | 已有 onboarding-dialog 元件沿用 | |
| **Dashboard Quick Start 3 步卡(打勾狀態)** | 根據 devices/models 狀態自動打勾 | 前端 state 計算 | |
| **Devices 拖放 .nef 上傳** | 拖放整頁覆蓋 | 需新增 Wails 檔案拖放代理層 | |
| **Workspace 即時推論 overlayMJPEG** | 延遲 100 msDesign/ 200 msArchitect | MJPEG 極限 ~80-150 ms | **需協調** |
| **OS 原生通知(裝置連 / 斷 / 崩潰)** | 三情境都發 OS 通知 | shell out 或引入 beeep | **降級建議** Server 崩潰發 OS 通知其他改用 App toast |
| **深色模式自動跟隨系統** | Wails emit event | CSS `prefers-color-scheme` 就夠 | 實作可簡化 |
| **14 切主區 + ,、⌘ W、⌘ Q** | Wails menu API | | |
| ** R 重新整理裝置** | Wails menu API | WebView reload 衝突 | **改用 ⌘ Shift+R** |
| **i18n 即時切換(含原生 menu** | 不重啟 | Wails 支援 dynamic menu rebuild | |
| **Settings 4 分頁 / Workspace 升一級** | 沿用 shadcn tabs + 新增 sidebar | | |
| **Mock 模式永久 badge + 切換確認對話框** | Header badge + Dialog | | |
| **macOS 原生 menu barvisionA-local / File / Edit / View / Devices / Help** | 完整 menu bar | Wails 支援但要逐項定義 | |
---
## ❓ 需要使用者或三方討論的問題
1. **MJPEG 延遲目標D-1 + P-2 相關)**
PRD 100 ms 的目標與實作極限衝突三方需決定
- **選項 A**接受放寬到 150 / 250 msArchitect 建議
- **選項 B**堅持 100 ms 改用 WebCodecs / MediaSource + H.264**工作量至少 +2 **
- **選項 C**只對感知延遲保證使用者主觀感覺不卡拿掉量化指標
2. **無障礙 WCAG 2.2 AA 要不要做D-6**
Design 承諾 AAPRD 明說 scope PM + Design 對齊到同一立場並更新文件
---
## 結論
PM PRD v1.1 Design Spec 第三輪修訂版整體對齊 Architect 的架構決策**無阻斷性衝突**。主要問題集中在
1. **數字級對齊問題**P-2 安裝時間上限P-3 Mock idle RAMD-1 MJPEG 延遲)— 三份文件的量化目標需要統一到實作可達成的範圍
2. **Wails API 能力細節**D-2 通知D-3 快捷鍵D-4 拖放D-5 深色模式)— Architect 已給出具體方案與降級選項Design 需配合小修
3. **小範圍命名 / 文件一致性**P-1 `visionA-local` vs `visiona-local`P-4 yt-dlp 授權P-5 發佈通路未確認
**沒有發現 PM 或 Design 偷偷引入需要大改架構的需求**也沒有架構層面的隱藏技術陷阱Architect PM 的功能需求與非功能需求 P-2/P-3/D-1 的數字需協調外均能提供對應技術方案
建議三方依本報告一起開一次短會對齊數字指標P-2P-3D-1D-6Design D-2~D-5 做小修訂即可進入使用者最終確認階段