# Architect 交叉審閱報告 > 審閱者:Architect Agent > 日期:2026-04-11 > 審閱對象:PM PRD v1.1、Design Spec v2(第三輪修訂) > 結論:**整體對齊、無阻斷性衝突**;有 7 項需修正 / 澄清,2 項需使用者或三方裁決。 --- ## ✅ 對齊的項目 以下是 PM / Design 的產出與 Architect 架構完全一致、無需調整的部分: 1. **核心功能範圍**:PRD 4.1–4.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 上約 **90–180 秒**,加上 Wails 冷啟 + WebView 3–5 秒,首次安裝達標但非常緊。Windows 還要 UAC 裝 WinUSB driver 再 +20–40 秒。 **建議**: 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) 常駐 ~150–200 MB,Go server (Gin + embedded Next.js) ~40–60 MB,Next.js 前端在 WebView 執行 ~100–150 MB,**合計約 290–410 MB**。若 Mock 模式啟動 Python sidecar(即便只做 mock),還會再 +60–80 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-dlp(Q10)」,但沒提 About / Settings 會露出第三方授權聲明。Architect 在 `dependency-bundling §4.4` 註記 yt-dlp 是 Unlicense(public 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)**典型為 80–150 ms**,若加上推論 overlay 再 +20–50 ms。Architect 的 ≤ 200 ms 是保守值,PRD 的目標 ≤ 100 ms **風險高**。 **建議**: 1. PRD 改為「攝影機串流延遲 ≤ 150 ms(目標)/ ≤ 250 ms(上限)」 2. Design wireframe 的 42 ms 範例值應改為 100–120 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` — 有 100–300 ms 延遲 + 每次 spawn 程序 2. **第三方 Go 套件**:`github.com/gen2brain/beeep`(跨平台)或 `github.com/go-toast/toast`(Windows 專用)— 更原生但要多帶依賴 3. **純 App 內 toast**(退路):直接用前端 toast 取代 OS 通知 **建議**:第一版採用**方案 3(App 內 toast)+ 關鍵通知(Server 崩潰)用方案 1 shell out**。Design 規格需修改:裝置連接 / 斷線改成**僅 App 內 toast,不發 OS 通知**(因為使用者此時視窗已在前景),只有 Server 崩潰才發 OS 通知。這可以省掉引入 beeep 套件的風險。 - **D-3 🟡 [快捷鍵 Wails API 確認] ⌘1–4 切主區 + ⌘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 承諾 AA,PRD 明說 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()` 重建 menu(Wails 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 即時推論 overlay(MJPEG)** | 延遲 ≤ 100 ms(Design)/ ≤ 200 ms(Architect) | 中(MJPEG 極限 ~80-150 ms) | ⚠️ **需協調** | | **OS 原生通知(裝置連 / 斷 / 崩潰)** | 三情境都發 OS 通知 | 中(需 shell out 或引入 beeep) | ⚠️ **降級建議**:只 Server 崩潰發 OS 通知,其他改用 App 內 toast | | **深色模式自動跟隨系統** | Wails emit event | 低(CSS `prefers-color-scheme` 就夠) | ✅ 高(實作可簡化) | | **⌘1–4 切主區 + ⌘ ,、⌘ 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 bar(visionA-local / File / Edit / View / Devices / Help)** | 完整 menu bar | 中(Wails 支援但要逐項定義) | ✅ 中 | --- ## ❓ 需要使用者或三方討論的問題 1. **MJPEG 延遲目標(D-1 + P-2 相關)** PRD ≤ 100 ms 的目標與實作極限衝突。三方需決定: - **選項 A**:接受放寬到 ≤ 150 / 250 ms(Architect 建議) - **選項 B**:堅持 100 ms → 改用 WebCodecs / MediaSource + H.264,**工作量至少 +2 週** - **選項 C**:只對「感知延遲」保證(使用者主觀感覺不卡),拿掉量化指標 2. **無障礙 WCAG 2.2 AA 要不要做(D-6)** Design 承諾 AA、PRD 明說 scope 外。需 PM + Design 對齊到同一立場並更新文件。 --- ## 結論 PM PRD v1.1 與 Design Spec 第三輪修訂版整體對齊 Architect 的架構決策,**無阻斷性衝突**。主要問題集中在: 1. **數字級對齊問題**(P-2 安裝時間上限、P-3 Mock idle RAM、D-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-2、P-3、D-1、D-6),Design 依 D-2~D-5 做小修訂即可進入使用者最終確認階段。