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>
4.2 KiB
4.2 KiB
Code Review 報告 — M1-7(前端清理 + pnpm build)
審查摘要
- 審查對象:
frontend/src/(清理 cluster/relay 相關程式碼)、frontend/out/(pnpm build 產物) - 產出 Agent:Frontend Agent
- 審查結果:✅ 通過(帶已知 walk-around,不阻斷 M1)
- 問題統計:Critical: 0 / Major: 0 / Minor: 4(皆已知、延到 M2)/ Suggestion: 1
驗收項目清單
| # | 驗收項目 | 結果 | 證據 |
|---|---|---|---|
| 1 | frontend/src/app/clusters/ 不存在 |
✅ | ls → No such file or directory |
| 2 | frontend/src/app/workspace/cluster/ 不存在 |
✅ | ls → No such file or directory |
| 3 | frontend/src/components/cluster/ 不存在 |
✅ | ls → No such file or directory |
| 4 | frontend/src/components/relay-token-sync.tsx 不存在 |
✅ | ls → No such file or directory |
| 5 | sidebar 不含 Clusters 導航項 | ✅ | sidebar.tsx navItems 僅 dashboard / models / devices / workspace / settings |
| 6 | Workspace 已提升為一級導航 | ✅ | { href: '/workspace', label: 'Workspace', icon: 'W' } |
| 7 | pnpm build 可重現且成功 |
✅ | Compiled successfully in 3.9s、Generating static pages (11/11) |
| 8 | 產出 frontend/out/ |
✅ | 已產出,含 index.html、devices/、models/、settings/、workspace/ |
| 9 | frontend/out/ 無 clusters 目錄 |
✅ | ls out/ | grep cluster → 無 |
| 10 | cluster 殘留皆為字串/註解,非 import/JSX | ✅ | grep 命中 4 檔:i18n/types.ts、i18n/en.ts、i18n/zh-TW.ts、use-resolved-params.ts(註解中的範例路徑) |
pnpm build 輸出路由表
○ / (Static)
○ /_not-found
○ /devices
● /devices/[id] (SSG, uses generateStaticParams → /devices/_)
○ /models
● /models/[id] (SSG → /models/_)
○ /settings
○ /workspace
● /workspace/[deviceId] (SSG → /workspace/_)
全部 11 個靜態頁面成功產出,無編譯錯誤、無 TypeScript 錯誤。
問題清單
Minor(已知 walk-around,延至 M2,不阻斷 M1)
| # | 檔案 | 問題描述 | 延後原因 |
|---|---|---|---|
| 1 | settings/page.tsx(推定) |
Settings 頁面仍保留 relay token / update-check UI | M2 才重構 Settings |
| 2 | lib/i18n/en.ts, zh-TW.ts, types.ts |
i18n 字串仍有 cluster key |
M2 才清 i18n |
| 3 | stores/activity-store.ts / components/activity-timeline.tsx(推定) |
flash_* 字串常量還在 |
M2 才清 |
| 4 | components/layout/sidebar.tsx L16 |
Workspace 用硬編字串 label: 'Workspace',沒走 t('nav.workspace') |
M2 補 i18n key |
Suggestion(非必要)
| # | 說明 |
|---|---|
| 1 | Next.js static export 把 workspace/[deviceId] 產成 workspace/_/ 佔位目錄(SSG with generateStaticParams 只產出 _ 這一個 stub)。執行期 Wails shell 會用 /workspace/{deviceId} 的 hash route 或 query string 導航,實際渲染靠 client-side 拿 deviceId,目前方式 OK;建議在 use-resolved-params.ts 或 workspace 的 client component 加一行註解說明這個 pattern,以免未來有人看到 out/workspace/_/ 覺得怪 |
動態路由 static export 的行為確認
workspace/[deviceId]、devices/[id]、models/[id] 在 Next.js 16 static export 下,若 generateStaticParams 回傳空陣列或包含 _ placeholder,會產出 /<route>/_ 作為 stub。這是 Next.js 官方支援的做法,runtime 在 Wails 環境用 client-side routing 拿到實際的 deviceId 即可。不影響 M1 驗收(macOS 雙擊 dmg 能跑)。
優點
- 刪除工作乾淨俐落,四個必刪路徑零殘留
- sidebar 精簡到只剩 5 個一級導航,符合 local-only 定位
pnpm build首次執行即成功,無需人工介入- 產物體積合理、所有必要頁面都有產出
- 殘留的
cluster字串都在 i18n 與註解中,不影響編譯,也不影響 runtime 行為
總結意見
M1-7 通過,可進入 M1 驗收。 四個已知 walk-around 都明確屬於 M2 範疇(settings 重構、i18n 清理、activity 字串、sidebar i18n key),與 M1 目標「macOS 雙擊 dmg 能跑」無衝突。build 產物完整可用,已準備好給 M1-8 embed 到 Go server。
可進入 M1-9(Wails installer shell)。