visionA/visionA-frontend
jim800121chen 99dea42239 feat(visionA-frontend): Phase 0 → 0.7 雲端前端(Next.js + OIDC redirect 流程)
visionA 雲端版前端 — 沿用 local-tool 既有 UI(原則 4:先抄 local-tool)+
新增雲端特有的登入 / 配對 / 設定流程,含以下整合階段:

- Phase 0:13 頁 + 30+ 元件 + 雛形 banner
  - dashboard / devices / models / workspace / clusters / settings 等頁
  - AppShell + Sidebar + Header + tokens + i18n(中英雙語 96 keys)
  - API client + 5 stores + 3 hooks
- Phase 0.6:OIDC redirect 改造
  - login 頁改為 OIDC redirect(`window.location.href = /api/auth/login`)
  - register 改說明頁、account 改唯讀(user 資料來源是 MC)
  - api client 改 cookie session(credentials: include)+ 完全清掉 localStorage
- Phase 0.7:stage 部署 + nil guard
  - getApiBaseUrl() 修:browser 環境視為 same-origin(與 login 頁一致)
  - login 頁加「已登入 → router.replace('/')」effect
  - User type email/name 改 optional(MC id_token 不一定回 email/name claim)
  - header.tsx UserMenu displayName 4 層 fallback:name → email → id → i18n
  - 雛形 banner 文案更新(已接 Innovedus 帳號中心)+ 版號 Phase 0.7

驗證:pnpm lint / test (125/125) / build 全綠

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 11:21:36 +08:00
..

visionA Cloud Frontend

visionA Cloud 前端 Web 應用Next.js 16 + React 19 + Tailwind 4

目的:將 local-tool/ 的使用體驗延伸到雲端,讓使用者透過瀏覽器操作由 local agent 連入的邊緣裝置Kneron KL520/KL720 等)。

🚧 Phase 0 雛形 — 任何功能皆以 UI 走通為目標不做真實身分驗證、OAuth、WebSocket 即時推送、MJPEG 串流。完整功能清單見下方「雛形範圍與限制」。

規劃中的正式版請見 .autoflow/02-prd/PRD.md,架構決策見 .autoflow/04-architecture/design-doc.md


技術堆疊

層級 技術 版本
框架 Next.jsApp Router 16.1.6
UI 函式庫 React / React DOM 19.2.3
語言 TypeScript ^5
樣式 Tailwind CSS@tailwindcss/postcss ^4
元件 primitive Radix UI ^1.4.3
元件規範 shadcn new-york stylecomponents.json
圖示 lucide-react ^0.575.0
狀態管理 Zustand ^5.0.11
主題 next-themes ^0.4.6
Toast sonner ^2.0.7
Class 工具 clsx + tailwind-merge + class-variance-authority
測試 Vitest + @testing-library/react + jsdom ^4 / ^16 / ^28
Lint ESLint + eslint-config-next ^9 / 16.1.6

版本與 local-tool/frontend/ 對齊,確保「雲端版 / 離線版同一套前端」的架構決策可執行。


前置需求

  • Node.js ≥ 20
  • pnpm ≥ 10
  • 依賴: 需同時運行 visionA-backendGo。前端所有 API 呼叫會指向 NEXT_PUBLIC_API_BASE,後端未啟動時功能會顯示錯誤但 UI 仍可瀏覽(多數頁面對 501 / 連線錯誤已做 graceful fallback

快速啟動

# 1. 安裝依賴
cd visionA-frontend
pnpm install

# 2. 設定環境變數
cp .env.local.example .env.local
# 檢查 NEXT_PUBLIC_API_BASE 是否指到正確後端位址

# 3. 啟動後端(另一個 terminal
cd ../visionA-backend
make run        # 或參考 visionA-backend/README.md

# 4. 啟動前端
cd ../visionA-frontend
pnpm dev        # http://localhost:3000

進入後任何 email + 任何密碼都可登入Phase 0 的 StaticAuthProvider

可用腳本

指令 說明
pnpm dev 開發模式Turbopack / HMR
pnpm build 產線打包(output: "standalone",便於 Docker 部署)
pnpm start 啟動 production build
pnpm lint 執行 ESLint
pnpm test 執行 Vitest一次性
pnpm test:watch 執行 Vitestwatch mode

專案結構

visionA-frontend/
├── src/
│   ├── app/                     # Next.js App Router 路由
│   │   ├── layout.tsx           # Root layoutTheme / Locale / AppShell
│   │   ├── page.tsx             # /  Dashboard
│   │   ├── login/               # /login
│   │   ├── register/            # /registerPhase 0 Coming Soon
│   │   ├── account/             # /account  帳號設定 stub
│   │   ├── devices/             # /devices, /devices/[id], /devices/pair
│   │   ├── models/              # /models, /models/[id]
│   │   ├── workspace/           # /workspace, /workspace/[deviceId]
│   │   ├── clusters/            # /clustersPhase 0 預告頁)
│   │   └── settings/            # /settings
│   ├── components/
│   │   ├── ui/                  # Shadcn primitiveButton / Card / Input ...
│   │   ├── layout/              # Sidebar / Header / PrototypeBanner / AppShell
│   │   ├── dashboard/           # StatCard / ActivityTimeline / ConnectedDevicesList
│   │   ├── devices/             # DeviceCard 相關
│   │   ├── models/              # ModelCard / ModelUploadDialog
│   │   ├── cloud/               # RemoteDeviceBadge
│   │   └── pairing/             # PairingTokenCard / PairingCountdown
│   ├── hooks/                   # useFetch / useWebsocket / useTunnelStatus
│   ├── lib/
│   │   ├── api.ts               # 統一 API clientenvelope / 401 / 501 / timeout
│   │   ├── utils.ts             # cn() 等
│   │   └── i18n/                # zh-Hant / en 字典 + Context
│   ├── stores/                  # Zustand storesauth / session / device / model / activity / pairing
│   ├── tests/                   # Vitest setup
│   └── types/                   # 共用型別api / user / pairing ...
├── public/                      # 靜態資源
├── components.json              # Shadcn CLI 設定
├── next.config.ts               # output: standalone
├── tsconfig.json                # @/* → ./src/*
└── package.json

主要頁面清單

路徑 Phase 0 狀態 說明
/login 可用 任意帳密皆通過StaticAuth
/register ⚠️ Coming Soon 引導回 /loginPhase 1 才實作
/ Dashboard 可用 StatCard × 4、近期活動、快速操作無裝置時顯示空狀態引導 /devices/pair
/devices 可用 裝置列表RemoteDeviceBadge 顯示遠端連線狀態
/devices/[id] 可用 裝置詳細、離線 banner
/devices/pair 可用(核心) 三步配對流程:產生 Pairing Token → 15 分鐘倒數 → 輪詢 3 分鐘
/models 可用 模型列表 + 上傳 DialogXHR 進度)
/models/[id] 可用 模型詳細、部署到裝置
/workspace 可用 選擇線上裝置
/workspace/[deviceId] ⚠️ Camera placeholder 推論 Start/Stop 可按MJPEG stream Phase 1 接上
/clusters ⚠️ Phase 1 預告 POC 有完整實作,雛形後端是 stub
/account 可用 stub 顯示使用者 + 登出;其他操作是 toast 提醒
/settings 可用 語言 / 主題 / API 端點切換

環境變數

變數 說明 預設值 必要
NEXT_PUBLIC_API_BASE 雲端 API Server 位址(無尾斜線) http://localhost:3721
NEXT_PUBLIC_WS_BASE WebSocket 位址;留空則從 API 推導 從 API base 推導

所有 runtime 變數都以 NEXT_PUBLIC_ 開頭Next.js 要求前端可讀),不要放真正機密的值——這類值應走後端。


Phase 0 雛形範圍與限制

可做到的

  • 完整 UI 骨架Sidebar / Header / 全域雛形 Banner / Sonner toast
  • i18nzh-Hant / en可即時切換key 集合兩語系強制同步
  • Light / Dark / System 主題切換
  • 裝置 / 模型 / 活動 三個 store 的 CRUD UI對齊 api-spec
  • Pairing 流程:產 token → 視覺切兩行顯示(複製永遠是完整 36 字元)→ 15 分鐘倒數3 色階段)→ 輪詢連線狀態 → 成功 toast + 跳轉
  • 離線降級:RemoteDeviceBadge + 頁面離線 Banner + Workspace 遮罩
  • 模型上傳XHR progress + presigned URL 直送 storage

Phase 0 刻意不做Phase 1 接手)

  • 任何帳密可登入 — 後端 StaticAuthProviderdemo-user;重啟後端後前端 localStorage 的 token 雖然還在,但伺服器上沒有任何 session 資料
  • OAuth / 2FA / 密碼重設 — 全部 Phase 1
  • 註冊功能 — 顯示 Coming Soon 頁面
  • 重啟後端 → 裝置 / 模型資料消失 — 後端目前是 InMemoryRepository
  • WebSocket 即時推送 — 事件 / 推論結果 / 配對狀態的 WS endpoint 目前回 501前端改用 3 秒輪詢pairing 頁)
  • Camera / MJPEG 串流/workspace/[deviceId] 的 Camera tab 顯示 placeholderImage / Video / Batch tabs disabled
  • Cluster CRUD/clusters 顯示 Phase 1 預告頁
  • Account CRUD — 變更個人資料 / 刪除帳號都是 toast stub
  • 真實 SHA-256 checksum — 模型上傳用 placeholder:{size}:{nameLen}(詳見 model-upload-dialog.tsx §placeholderChecksum

前端安全債詳見 .autoflow/04-architecture/security.md §14localStorage token / WS querystring / CSP / CSRF 等 6 項,每項有 Phase 1 計畫)。


效能預算Phase 1 開始嚴格執行)

資源 預算
JavaScript首次載入壓縮後 < 200 KB
CSS壓縮後 < 50 KB
首次載入總大小 < 500 KB
Core Web Vitals LCP < 2.5s、INP < 200ms、CLS < 0.1

雛形Phase 0階段僅確保 pnpm build 成功CI 中加入 bundle 檢查由 DevOps 任務處理。


無障礙規範

目標 WCAG 2.2 AA(詳見 .autoflow/03-design/design-spec.md §8

  • 色彩對比:一般文字 ≥ 4.5:1、大文字 ≥ 3:1
  • 鍵盤可操作所有核心流程Tab / Enter / Escape
  • Focus ring 可見shadcn 預設 ring-2 ring-ring
  • 語意化 HTML<nav><main><aside><header>
  • 動態內容 aria-live
  • Pairing token 顯示:role="text" + 完整 token 於 aria-label(避免 SR 一字一念)
  • Status card成功 / 失敗用 role="status" / role="alert" + aria-live

測試

  • 策略Unit ~60% / Integration ~25% / Visual ~10% / E2E ~5%E2E 交給 Testing Agent
  • 工具Vitest + React Testing Library + jsdom
  • 當前15 個測試檔、94 個 test 全綠
  • 強制一致i18n.test.ts 驗 zh-Hant / en 兩份字典 key 集合完全一致且無空字串
pnpm test          # 一次跑完
pnpm test:watch    # watch mode

部署

  • next.config.ts 已設 output: "standalone",方便未來 Docker 化
  • Dockerfile / docker-compose / Helm chart 由 DevOps Agent 規劃Phase 1

相關文件