# 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/tray` - `cfg.RelayURL` / `RelayToken` / `GiteaURL` flag - `tunnelClient.Start()`、`clusterMgr`、`relayWebURL()`、`trayMgr` 等呼叫 - `--gui` mode、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 授權檔案落點 所有授權檔案放在安裝後的 `/licenses/` 目錄: ``` /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)產出 - 若未來對外商業發佈需補上述合規流程