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>
58 lines
3.9 KiB
Markdown
58 lines
3.9 KiB
Markdown
# Code Review 報告 — M1-5(Go binary + smoke test)
|
||
|
||
## 審查摘要
|
||
- 審查對象:`dist/visiona-local-server` 及 `Makefile` 的 `server` / `build-server` target
|
||
- 產出 Agent:Backend Agent
|
||
- 審查結果:✅ 通過
|
||
- 問題統計:Critical: 0 / Major: 0 / Minor: 1 / Suggestion: 1
|
||
|
||
## 驗收項目清單
|
||
|
||
| # | 驗收項目 | 結果 | 證據 |
|
||
|---|---------|------|------|
|
||
| 1 | Binary 存在且可執行 | ✅ | `file dist/visiona-local-server` → `Mach-O 64-bit executable x86_64`,31 MB |
|
||
| 2 | `--help` 輸出包含 `--mock --dev --port --data-dir --python-mode` | ✅ | `-mock`, `-dev`, `-port`, `-data-dir`, `-python-mode` 皆存在 |
|
||
| 3 | `--help` 無 `--relay-url --tray --gui` | ✅ | 已完全移除,flag 清單乾淨 |
|
||
| 4 | `--host` 強制 127.0.0.1 | ✅ | flag 預設值為 `127.0.0.1`,help 字串 `(forced to 127.0.0.1 for local-only use)` |
|
||
| 5 | Smoke:`./visiona-local-server --mock --port 13721` 可啟動 | ✅ | log 顯示 `Server listening on 127.0.0.1:13721` |
|
||
| 6 | `GET /api/system/health` 回 200 | ✅ | `{"status":"ok"}` |
|
||
| 7 | `GET /api/system/info` 回 200 | ✅ | `{"data":{"goVersion":"go1.26.0","platform":"darwin/amd64","uptime":1.51,"version":"dev"},"success":true}` |
|
||
| 8 | Bind 在 127.0.0.1 而非 0.0.0.0 | ✅ | `lsof -nP -iTCP:13721` → `TCP 127.0.0.1:13721 (LISTEN)` |
|
||
| 9 | SIGTERM 可優雅關閉 | ✅ | `Received signal terminated, shutting down gracefully...` |
|
||
| 10 | Makefile `server` / `build-server` target 可執行 | ✅ | 兩個 target 已定義,`server` 為 `build-server` 的 alias,內容為 `cd server && go build -o ../dist/visiona-local-server .` |
|
||
| 11 | Embedded frontend 已掛載 | ✅ | log:`Serving embedded frontend static files`,註冊 `/_next/*filepath`、`/favicon.ico` |
|
||
| 12 | 外部依賴自檢 | ✅ | ffmpeg 8.0.1、yt-dlp 2026.02.04、python3 3.14.3 全部 OK |
|
||
|
||
## 問題清單
|
||
|
||
### Minor(建議修復)
|
||
| # | 檔案 | 問題描述 | 建議 |
|
||
|---|------|---------|------|
|
||
| 1 | `dist/data/models.json` | 啟動時 warning:`could not load models from .../dist/data/models.json: no such file or directory` | M1-8 打包時應把 seed 的 `models.json` 放進 `dist/data/`,或讓 backend 在檔案不存在時靜默跳過(目前就是走這條,只是 log 成 warning 略吵) |
|
||
|
||
### Suggestion(非必要)
|
||
| # | 建議 |
|
||
|---|------|
|
||
| 1 | 預設 `GIN_MODE=debug` 在正式 binary 跑會印很多 route 註冊 log;M1-9 installer build 時透過 ldflags 或環境變數設為 `release` 更乾淨 |
|
||
|
||
## 備註:Port 衝突與歷史 daemon
|
||
|
||
執行 smoke test 時發現系統上有一隻 legacy `edge-ai-server` (PID 44243) 已經佔用 `127.0.0.1:3721`(帶 `--relay-url / --relay-token / --tray` 參數,顯然是 M0 時代的背景 daemon)。**這不影響 M1-5 交付**,但:
|
||
|
||
1. 第一次 smoke test 若跑在 3721,curl 回應其實來自 legacy daemon,不是新 binary。**我改用 port 13721 重測,確認新 binary 行為正確。**
|
||
2. 建議 M1-9(Wails installer)或交付文件裡加一段「升級注意事項」:提醒使用者先 `pkill edge-ai-server` 或手動移除舊 launchd plist,否則新舊 binary 搶 port。
|
||
|
||
## 優點
|
||
|
||
- `--host` flag 明確標示 `forced to 127.0.0.1 for local-only use`,意圖清楚,local-only 原則落實到 CLI 層
|
||
- 啟動時主動做外部依賴自檢(ffmpeg / yt-dlp / python3),對使用者除錯很友善
|
||
- Graceful shutdown 正確實作(SIGTERM → 關閉 → 進程退出,無殘留)
|
||
- 路由註冊完整:system、models、devices、camera、media、ws 全部對齊 TDD 規格
|
||
- Makefile target 命名直覺,`server` 作為 `build-server` alias 符合慣用做法
|
||
|
||
## 總結意見
|
||
|
||
**M1-5 完整通過。** Binary 可執行、CLI flags 符合規格、強制 bind 127.0.0.1、health/info endpoint 正常、graceful shutdown 正確、Makefile target 可用。僅一個 Minor(models.json warning)與一個 Suggestion(GIN debug mode),皆不阻斷 M1 驗收。
|
||
|
||
可進入 M1-9(Wails installer shell)。
|