依 autoflow-agent workspace v2 設計把 PRD / 設計 / 架構 / 交付類 共享文件從個人層 .autoflow/(ignored)搬到 docs/autoflow/(進 git), 讓團隊可共享產品與架構文件,個人層只留 progress / review / testing 等 per-branch 筆記。 - 02-prd/ 21 個檔(PRD、features、market-analysis 等) - 03-design/ 18 個檔(design-spec、wireframes、flows 等) - 04-architecture/ 31 個檔(TDD、design-doc、ADR×14、API 規格等) - 07-delivery/ 3 個檔(project-summary、phase-0.6-handover、stage-deployment-setup) 合計 73 檔。原檔已從 .autoflow/ 移除(migration 工具執行 git mv, 但因 .autoflow/ 在 .gitignore 中、git 將此操作視為新增、無 rename history)。
8.7 KiB
8.7 KiB
API Spec — 對前端的 REST + WebSocket 端點
base URL:
https://api.visiona.cloud(Phase 1)/http://localhost:3001(雛形) 認證:Authorization: Bearer <JWT>(雛形可省略,走StaticAuthService) 通用回應格式:{ "success": true, "data": {...} } { "success": false, "error": { "code": "ERR_CODE", "message": "..." } }
1. Auth(雛形 stub)
POST /api/auth/login
- 雛形:回
501 { code: "NOT_IMPLEMENTED" } - Phase 1:
{ email, password }→{ user, access_token, refresh_token }
POST /api/auth/register
- 同上
POST /api/auth/logout
- Phase 1:清 refresh token
GET /api/auth/me
- 雛形:回
demo-userhard-coded - Phase 1:從 JWT 取
2. Pairing
POST /api/pairing/token
- Auth required(雛形:靜默通過)
- 雛形 Response:
{ "success": false, "error": { "code": "NOT_IMPLEMENTED", "message": "Dev uses env VISIONA_PAIRING_TOKEN" } } - Phase 1 Response:
{ "success": true, "data": { "token": "pk_AbCd1234...", "expires_at": "2026-04-21T13:00:00Z" } }
GET /api/pairing/status
- 查詢當前 user 的 tunnel 連線狀態
- Response:
{ "success": true, "data": { "connected": true, "connected_at": "2026-04-21T12:00:00Z", "last_seen_at": "2026-04-21T12:34:56Z", "device_id": "dev-xxx", "agent_version": "local-tool 1.2.3" } }
GET /api/pairing/tokens
- List 當前 user 的所有 tokens
- Phase 1:回 array of
{ id, device_id, kind, created_at, last_seen_at }
DELETE /api/pairing/tokens/:id
- 撤銷指定 token
- Phase 1 實作;雛形 501
3. Devices
以下大部分端點會被轉發到 local agent。api-server 行為:
- 檢查 user 有 tunnel 連線
- 若 device_id 有傳,檢查 ownership
- 透過 tunnel forward 請求到 local agent(沿用 POC
handleProxy) - 回傳 local agent 的 response
路徑與回應格式與 local-tool 相同,前端改 base URL 即可。
GET /api/devices — 列出當前本地掃到的裝置
POST /api/devices/scan — 觸發重掃
GET /api/devices/:id — 單一裝置
POST /api/devices/:id/connect
POST /api/devices/:id/disconnect
POST /api/devices/:id/flash — 燒韌體(透過 tunnel)
POST /api/devices/:id/inference/start
POST /api/devices/:id/inference/stop
雲端特有(非 tunnel forward):
GET /api/cloud/devices — 列出「我在雲端綁過的 Device records」
- 與
GET /api/devices不同:這個是查雲端 DB,不問 local agent - 雛形:從
InMemoryDeviceRepository回 - Response:
[{ id, name, device_type, serial_number, status, last_seen_at }]
POST /api/cloud/devices/:id/rename
- 改雲端上的 device name
4. Models
GET /api/models — 列出 user 的 model
- 雲端模型(存 storage)+ preset models(硬編碼)
- Response:
{ "success": true, "data": [ { "id": "abc-123", "name": "YOLOv5 Face", "target_chip": "kl520", "file_size": 12345678, "source": "uploaded", "created_at": "..." } ] }
GET /api/models/:id
- Model 詳情
POST /api/models/init — 初始化上傳
- Request:
{ name, file_size, checksum, target_chip, description? } - Response:
{ "success": true, "data": { "model_id": "new-id", "upload_url": "https://...presigned-put-url...", "upload_expires_at": "..." } }
POST /api/models/:id/finalize
- 在 presigned PUT 成功後呼叫
- api-server 驗證檔案已存在、size / checksum 對 → status 改 "ready"
DELETE /api/models/:id
POST /api/models/:id/load-to-device
- Body:
{ device_id } - api-server 產 presigned GET URL → 透過 tunnel 送 local agent 「下載並載入」
- 回傳 job status
5. Clusters(從 POC 搬)
GET /api/clusters
POST /api/clusters
- Body:
{ name, device_ids: [...] }
GET /api/clusters/:id
DELETE /api/clusters/:id
POST /api/clusters/:id/devices
DELETE /api/clusters/:id/devices/:deviceId
PUT /api/clusters/:id/devices/:deviceId/weight
POST /api/clusters/:id/flash
POST /api/clusters/:id/inference/start
POST /api/clusters/:id/inference/stop
6. Camera / Media
與 local-tool 相同,全部透過 tunnel forward:
GET /api/camera/list
POST /api/camera/start
POST /api/camera/stop
GET /api/camera/stream — MJPEG(透過 tunnel streaming)
POST /api/media/upload/image
POST /api/media/upload/video
POST /api/media/upload/batch-images
GET /api/media/batch-images/:index
POST /api/media/seek
7. System
GET /api/system/health
- 雲端側:回 api-server 自己的健康 + tunnel 連線狀態
{ "success": true, "data": { "api_server": "ok", "tunnel_connected": true, "agent_last_seen_at": "..." } }
GET /api/system/info
- 版本資訊
8. Converter
8.1 Phase 1 stub(既有,保留)
雛形 stub 路由;Phase 0.8 的真實整合改走 §8.2
/api/conversion/*,下列路由保留為 placeholder 待 Phase 1 視需要 supersede。
POST /api/converter/jobs
- Body:
{ source_model_key, target_chip, params? } - Response:
{ job_id, status: "queued" }
GET /api/converter/jobs
- List user 的 jobs
GET /api/converter/jobs/:id
- Job 狀態
GET /api/converter/jobs/:id/download
- 下載產物(presigned URL redirect)
詳細契約 → api-converter-contract.md
8.2 Phase 0.8 — /api/conversion/*(轉檔功能整合)
正式對接 kneron_model_converter scheduler + FAA delegated download:
POST /api/conversion/init— multipart streaming proxy 到 converter,建 jobGET /api/conversion/{job_id}— 查狀態(HTTP polling,frontend 間隔 2s)POST /api/conversion/{job_id}/promote-to-models— 「加到模型庫」POST /api/conversion/{job_id}/download-token— 換 browser 直連 FAA 的 delegated URLGET /api/conversion/active— 查當前 user 是否有 active job
詳細契約 → api-conversion.md
內部設計 → ../conversion.md
ADR → ../adr/adr-014-conversion-integration.md
9. WebSocket
WS /ws/devices/events
- 訂閱「裝置上下線」事件
- Server push:
{ "type": "device.connected", "device_id": "xxx", "at": "..." } { "type": "device.disconnected", "device_id": "xxx", "at": "..." }
WS /ws/devices/:id/flash-progress
- 燒錄進度(透過 tunnel 從 local agent 取)
WS /ws/devices/:id/inference
- 推論結果串流
WS /ws/server-logs
- log broadcast(沿用 local-tool 的 broadcaster)
WS /ws/system
- 系統事件(server:shutdown-imminent 等)
WS /ws/clusters/:id/inference
WS /ws/clusters/:id/flash-progress
WS /ws/pairing/status(新)
- 訂閱 tunnel 連線狀態變化
- Server push:
{ "type": "tunnel.connected", "connected_at": "..." } { "type": "tunnel.disconnected", "reason": "network_error", "at": "..." }
10. Storage(雛形 LocalFS 代理)
GET /storage/*filepath?expires=...&signature=...
- LocalFS 的假 presigned GET
- 驗簽後讀檔回傳
PUT /storage/*filepath?expires=...&signature=...
- LocalFS 的假 presigned PUT
- 驗簽後收 body 寫檔
Phase 1:直接由 S3 提供,不走 api-server。
11. 錯誤碼清單
| Code | HTTP | 說明 |
|---|---|---|
UNAUTHORIZED |
401 | 未認證或 token 無效 |
FORBIDDEN |
403 | 權限不足 |
NOT_FOUND |
404 | 資源不存在 |
VALIDATION_FAILED |
400 | 輸入驗證失敗 |
TUNNEL_DISCONNECTED |
502 | Local agent 未連線 |
TUNNEL_ERROR |
502 | Tunnel 傳輸錯誤 |
NOT_IMPLEMENTED |
501 | 雛形尚未實作 |
RATE_LIMITED |
429 | 請求過快(Phase 1) |
INTERNAL_ERROR |
500 | 未預期錯誤 |
12. Pagination
對會變大的 list(models、devices、jobs)用 cursor-based:
GET /api/models?limit=50&cursor=...
Response:
{ "data": [...], "next_cursor": "..." | null }
雛形可先簡單回全部(in-memory);Phase 1 接 DB 時實作 cursor。
雛形 MVP 清單(必須有):
GET /api/system/healthGET /api/pairing/statusGET /api/devices+ 透過 tunnel forwardGET /api/models+POST /api/models/init+/finalize(LocalFS)/storage/*代理- WS
/ws/devices/events - WS
/ws/pairing/status
其他可以先 501 或 stub。