# 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)。