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>
13 KiB
13 KiB
4. 功能清單與 API 對照(對照原 edge-ai-platform)
本章節列出 visionA-local 相對於原 edge-ai-platform 的功能取捨。所有 ✅ / ❌ / ⚠️ 決定都已依使用者 Q1-Q15 與三方第一輪分析定案。
4.1 後端 API 對照表
| API 群組 | Endpoint | 去留 | 說明 |
|---|---|---|---|
| 系統 / 健康 | GET /api/system/health |
✅ 保留 | 基本健康檢查 |
GET /api/system/info |
✅ 保留 | 顯示版本、平台、執行目錄 | |
GET /api/system/metrics |
✅ 保留(簡化) | local 版可省略 prometheus 整合,回傳簡單 JSON | |
GET /api/system/deps |
✅ 保留 | 顯示依賴狀態(Python / ffmpeg / KneronPLUS) | |
GET /api/system/update-check |
❌ 砍 | Q6 決定不做 auto-update | |
POST /api/system/restart |
✅ 保留 | Settings 頁「重啟服務」按鈕會用到(原 Tray 用途已取消) | |
| 模型管理 | GET /api/models |
✅ 保留 | 列出所有模型 |
GET /api/models/:id |
✅ 保留 | ||
POST /api/models/upload |
✅ 保留 | 支援拖放上傳 | |
DELETE /api/models/:id |
✅ 保留 | ||
GET /api/models/:id/download |
✅ 保留 | ||
| 裝置管理 | GET /api/devices |
✅ 保留 | |
POST /api/devices/scan |
✅ 保留 | USB 掃描 | |
POST /api/devices/:id/connect |
✅ 保留 | ||
POST /api/devices/:id/disconnect |
✅ 保留 | ||
POST /api/devices/:id/flash |
❌ 砍 | Q9 決定砍掉韌體燒錄 | |
POST /api/devices/:id/inference/start |
✅ 保留 | ||
POST /api/devices/:id/inference/stop |
✅ 保留 | ||
| 攝影機 | GET /api/camera |
✅ 保留 | 列出 webcam |
POST /api/camera/:id/start |
✅ 保留 | ||
POST /api/camera/:id/stop |
✅ 保留 | ||
GET /api/camera/:id/stream |
✅ 保留 | MJPEG 串流 | |
| 媒體上傳 | POST /api/media/upload/image |
✅ 保留 | |
POST /api/media/upload/video |
✅ 保留 | ||
POST /api/media/upload/batch |
✅ 保留 | ||
POST /api/media/url |
✅ 保留 | Q10 決定保留(打包 yt-dlp) | |
| Cluster | /api/clusters/*(全部 endpoint) |
❌ 全砍 | |
| WebSocket | /ws/clusters/* |
❌ 砍 | |
/ws/devices/* |
✅ 保留 | 裝置狀態即時推送 | |
/ws/server-logs |
✅ 保留 | Server log 顯示(供進階 / 設定頁使用,非 tray) | |
| 認證 / Relay | POST /auth/token |
❌ 砍 | relay token,localhost 不需要 |
| relay / tunnel 中介層 | ❌ 砍 |
4.2 前端頁面對照表
對照 frontend/src/app/:
| 路由 | 去留 | 說明 |
|---|---|---|
/(Dashboard) |
✅ 保留(重新設計) | 拿掉 cluster 統計,首頁改為「快速開始 + 裝置狀態 + 最近活動」 |
/devices |
✅ 保留 | 裝置列表 + connect / disconnect |
/models |
✅ 保留 | 模型庫 |
/workspace 或 /workspace/[deviceId] |
✅ 保留(升為 sidebar 一級) | 核心頁面:單裝置推論工作區。第三輪 Q-E2 決策:Workspace 從「進入 Device 後的子頁」升級為 sidebar 一級入口,讓使用者不需要先挑裝置就能進工作區(內部可顯示「請先連線裝置」狀態) |
/workspace/cluster |
❌ 砍 | |
/clusters |
❌ 砍 | |
/settings |
✅ 保留(重新設計) | 清掉 relay / cluster 設定。第三輪 Q-E3 決策:取消「外觀」分頁(深色模式跟隨系統不需獨立分頁)、將「語言」併入「一般」分頁。最終分頁結構:一般(含語言)/ 硬體 / 模型 / 進階,共 4 個分頁 |
4.3 元件對照表
對照 frontend/src/components/:
| 分類 | 元件 | 去留 |
|---|---|---|
camera/ |
camera-feed, camera-controls, camera-overlay, source-selector, camera-inference-view, batch-image-thumbnails | ✅ 全保留 |
devices/ |
device-card, device-list, device-health-card, device-connection-log, device-status | ✅ 保留 |
| flash-dialog, flash-progress | ❌ 砍(Q9) | |
models/ |
model-card, model-grid, model-filters, model-upload-dialog, model-detail, model-comparison-dialog | ✅ 全保留 |
inference/ |
inference-panel, classification-result, confidence-slider, performance-metrics, video-progress | ✅ 全保留 |
cluster/ |
cluster-card, cluster-list, cluster-create-dialog, cluster-performance | ❌ 全砍 |
dashboard/ |
stat-card, activity-timeline, connected-devices-list | ✅ 保留(拿掉 cluster 欄位) |
layout/ |
sidebar, header, connection-status, help-button | ✅ 保留但改寫(sidebar 為 4 個主導航 + Settings(底部獨立區,用 divider 分隔):Dashboard / Devices / Models / Workspace + ── divider ── + Settings。對應 Design spec/01-IA §1.2) |
| — | onboarding-dialog, guided-tour | ✅ 保留並強化(First-Run) |
| — | relay-token-sync | ❌ 砍 |
| — | server-log-viewer, server-status-dashboard | ✅ 保留(桌面 app 需要) |
| — | theme-sync, lang-sync, store-hydration | ✅ 保留 |
4.4 Server 內部模組對照表
對照 server/internal/:
| 模組 | 去留 |
|---|---|
api/ |
✅ 改寫(刪除 cluster / tunnel / relay handler 與 route) |
camera/ |
✅ 直接複製 |
device/ |
✅ 直接複製 |
model/ |
✅ 直接複製 |
inference/ |
✅ 直接複製 |
config/ |
✅ 改寫(砍掉 RelayURL / RelayToken / GiteaURL / GUIMode) |
deps/ |
✅ 直接複製 |
cluster/ |
❌ 整包刪除 |
tunnel/ |
❌ 整包刪除 |
flash/ |
❌ 整包刪除(Q9) |
update/ |
❌ 整包刪除(Q6) |
relay/ |
❌ 整包刪除 |
tray/ |
❌ 整包刪除(第三輪 Q-A 決策砍掉 tray) |
server/main.go 需移除的 import 與初始化:
internal/cluster、internal/tunnel、pkg/hwid、internal/flash、internal/update、internal/traycfg.RelayURL/RelayToken/GiteaURLflagtunnelClient.Start()、clusterMgr、relayWebURL()、trayMgr等呼叫--guimode、relay-server cmd、tray init
4.5 新增的功能(相對於原專案)
| 新功能 | 說明 |
|---|---|
| First-Run 歡迎流程 | 歡迎畫面 → 模式選擇(真實 / Mock)→ 硬體偵測(真實模式)→ 完成 |
| 內嵌依賴解壓流程 | 首次啟動時把 Python wheels / ffmpeg / nef 從 Wails payload 解壓到 OS 慣例資料目錄(macOS:~/Library/Application Support/visiona-local/;Windows / Linux 依各自慣例,由 Architect TDD 定義) |
| Python fallback 策略 | 優先使用內嵌 Python(Q1 決定 A + B),找不到時 fallback 到系統 Python |
| 原生 menu bar(macOS / Win / Linux) | 釋放 ⌘N / ⌘W / ⌘Q 等桌面快捷鍵;快速動作(新增裝置 / 上傳模型 / 開啟工作區)改走 menu bar,不再透過 tray |
| 拖放 .nef / 圖片 / 影片到視窗任意處 | 桌面 app 慣例 |
| Mac Gatekeeper 警告引導頁 | 因為不做 notarization |
| Windows SmartScreen 警告引導頁 | 因為不做 EV cert |
| Mock 模式視覺標記 | 主視窗標題列 + 首頁徽章 + sidebar 底部狀態列(不再含 tray badge) |
4.6 原專案要刪除的檔案清單(具體路徑)
server/internal/cluster/ ← 整包刪
server/internal/tunnel/ ← 整包刪
server/internal/flash/ ← 整包刪(Q9)
server/internal/update/ ← 整包刪(Q6)
server/internal/tray/ ← 整包刪(第三輪 Q-A)
server/cmd/relay-server/ ← 整包刪
server/pkg/hwid/ ← relay token 用的,可刪
docker/ ← 整包刪
scripts/deploy-aws.sh ← 刪
scripts/deploy-ec2.sh ← 刪
frontend/src/app/clusters/ ← 整包刪
frontend/src/app/workspace/cluster/← 整包刪
frontend/src/components/cluster/ ← 整包刪
frontend/src/components/relay-token-sync.tsx ← 刪
frontend/src/components/devices/flash-*.tsx ← 刪
第三輪 Q-C 決策:M1(即 MVP)階段必須一次把前端 cluster / relay / tray 相關 UI 全部清乾淨,不允許「先留著不動」。若開發過程中發現 legacy 相依讓清理成本很高,也必須在 M1 內解決。
4.7 RICE 優先級(簡化版)
因為 MVP 範圍已定案(一次到位),此處 RICE 僅用於開發順序而非功能取捨。
| 功能 | Reach(內部人數) | Impact(0.25-3) | Confidence | Effort(人週) | RICE | 建議開發順序 |
|---|---|---|---|---|---|---|
| Wails 殼 + payload 解壓流程 | 10 | 3 | 100% | 2 | 15 | 1(阻斷性) |
| Go server 瘦身(刪 cluster / relay / tray) | 10 | 3 | 100% | 1 | 30 | 2 |
| 前端 sidebar / 路由 / 首頁改寫(含 Workspace 升一級 + 清 cluster/relay/tray UI) | 10 | 2.5 | 100% | 1.5 | 16.7 | 3 |
| Python runtime + wheels 內嵌 | 10 | 3 | 80% | 2 | 12 | 4(R1/R3 風險) |
| 裝置偵測 + connect(核心推論路徑) | 10 | 3 | 100% | 1 | 30 | 5 |
| First-Run 歡迎流程 + Mock 模式入口 | 10 | 2 | 100% | 1 | 20 | 6 |
| 攝影機串流 + 推論 overlay | 10 | 2.5 | 100% | 1 | 25 | 7 |
| 媒體上傳(image / video / URL) | 7 | 1.5 | 100% | 1 | 10.5 | 8 |
| 中英雙語 + 深色模式跟隨系統(Settings 語言併入一般) | 10 | 1 | 100% | 0.5 | 20 | 9 |
| 打包輸出(dmg / exe / AppImage) | 10 | 3 | 70% | 2 | 10.5 | 10(阻斷性發佈) |
第三輪 Q-A 決策:原排序第 6 的「Tray(三平台)」已移除,後續項目依序向前遞補。
注意:Reach 取「預計內部使用人數 × 次數」近似值,因為是內部工具沒有市場規模概念。
4.8 第三方依賴的授權宣告(第四輪新增)
visionA-local 內嵌以下第三方工具,對應授權與宣告責任如下:
| 依賴 | 用途 | 授權 | 宣告要求 |
|---|---|---|---|
| ffmpeg(LGPL build) | 攝影機 / 影片處理 | LGPL v2.1+ | ⚠️ 必須宣告:(1) 在安裝檔內附 LICENSE-ffmpeg.txt(含完整 LGPL 條文與 copyright notice);(2) About 對話框顯示 Powered by FFmpeg (LGPL) 與連結;(3) 若未來改用 GPL build 的 ffmpeg,整個 visionA-local 必須改為 GPL 授權,本 MVP 只能用 LGPL build;(4) 動態連結 ffmpeg binary(不靜態連結成 Go binary),符合 LGPL 的 "user can replace the library" 條款 |
| yt-dlp | /api/media/url YouTube 影片下載 |
Unlicense(public domain-equivalent)+ MIT fork 歷史 | ✅ 建議宣告:About 對話框列出 yt-dlp (Unlicense);內附 LICENSE-yt-dlp.txt。無強制要求但好習慣 |
| KneronPLUS SDK(wheel) | 裝置 / 推論 | Kneron 專有授權(re-distribution 待確認,見 R5 / R9) | ⚠️ 發佈前 gate(R5):授權允許後才能正式對外發佈;內嵌時必須保留 Kneron 的 copyright notice 與 LICENSE-KneronPLUS.txt |
| Python runtime(python-build-standalone) | 執行 KneronPLUS | PSF License 2.0(Python 本體)+ 各組件授權 | ✅ 必須宣告:內附 LICENSE-python.txt;About 對話框列出 Python 版本與授權 |
| Python wheels(numpy / opencv / pyusb 等) | 推論依賴 | 各 wheel 不同(多為 BSD / MIT / Apache 2.0) | ✅ 必須宣告:內附 third_party_licenses.txt,列出每個 wheel 的授權條文 |
| Wails v2 | GUI 殼 | MIT | ✅ About 對話框列出 |
| Next.js / React / shadcn / Radix / Tailwind / Zustand | 前端 | MIT 為主(個別 check) | ✅ About 對話框列出主要依賴;前端 build 時由 webpack-license-plugin 自動產出 frontend-licenses.txt |
4.8.1 授權檔案落點
所有授權檔案放在安裝後的 <APPDATA>/licenses/ 目錄:
<APPDATA>/licenses/
├── LICENSE-visionA-local.txt (本產品 — 內部工具,待定)
├── LICENSE-ffmpeg.txt (LGPL v2.1+)
├── LICENSE-yt-dlp.txt (Unlicense)
├── LICENSE-KneronPLUS.txt (Kneron 專有)
├── LICENSE-python.txt (PSF)
├── third_party_licenses.txt (Python wheels 合併)
├── frontend-licenses.txt (前端 npm 依賴合併)
└── README.md (宣告總覽與對應表)
About 對話框提供「檢視第三方授權」按鈕 → 開啟上述目錄或彈出瀏覽器檢視。
4.8.2 架構責任分工
- Architect:在
04-architecture/dependency-bundling.md/packaging.md補實作細節(檔案來源、打包流程、ffmpeg 必須動態連結而非靜態) - Frontend:在 Settings > 進階 或 Help > About 對話框加「第三方授權」入口
- DevOps:CI build 流程加入授權檔案收集腳本,確保每次 release 都帶齊
4.8.3 MVP 邊界聲明
本 MVP 是內部工具,不對外商業發佈,因此:
- ✅ 授權宣告做到位(LGPL 強制項目必做)
- ❌ 不做 OSS license compliance tool 的正式掃描(如 FOSSA、Black Duck)
- ❌ 不做 SBOM(Software Bill of Materials)產出
- 若未來對外商業發佈需補上述合規流程