Phase 0.8 把 kneron_model_converter 的轉檔功能整合進 visionA Cloud。
visionA backend 當 streaming proxy(upload)+ delegated download token broker(download)+
ownership trust boundary,converter / FAA / MC 三方零修改。
新增 internal/conversion/ 套件(8 個檔,~10,000 行 prod+test,117+ test cases,race -count=3 全綠):
- conversion.go:Service interface 5 method、Job/PromoteResult/InitJobInput types
- errors.go:13+ sentinel errors + ErrorCode/HTTPStatus mapping,對齊 conversion.md §6
- mc_token_client.go:service-to-service token (client_credentials grant) + DCL cache
(exp - 15s 重取,per-scope cache),IssueDelegatedDownload(MC delegated download token)
錯誤分 idp_misconfigured (4xx) / idp_unavailable (5xx) / download_token_failed / mc_token_unavailable
- converter_client.go:對 converter scheduler 4 method(InitJob multipart streaming /
GetJob / Promote / ListInProgressJobs),InitJob 不 retry 5xx(streaming body 無法 replay)
- faa_client.go:對 FAA GET /files/{key} server-to-server pull,Phase A retry(GET 無 body
可 replay)對齊 §9.1 retry 矩陣,streaming io.ReadCloser 透傳避 OOM
- ownership.go:in-memory job_id → user_id map + per-user mutex 防 thundering herd lazy rebuild
(不同 user 平行 fetch,同 user 100 caller 收斂成 1 次),visionA 重啟靠 converter
ListInProgressJobs(user) 重建
- flow.go:Service interface 整合層(5 method 串接 converter/FAA/MC/ownership)
- InitJob 用 io.Pipe + multipart.Reader/Writer 重組 streaming proxy(黑名單 client user_id
+ 灌入 OIDC sub)
- DownloadRedirectURL 自動觸發 promote(spec §1 Stage 3b),用 ensurePromoted helper
- PromoteToModels 冪等(modelStore.FindBySourceJobID 為 source-of-truth)
- OwnershipMismatch → ErrJobNotFound 不 forbidden(§7.2 防枚舉)
- storage / modelStore 失敗包 ErrStorageUnavailable / ErrModelStoreUnavailable
(視為 visionA 自身 500 而非 502 gateway,SRE alarm 才打對 team)
新增 internal/api/conversion.go(5 endpoint handler + main.go wire):
- POST /api/conversion/init(multipart streaming proxy,不呼叫 c.MultipartForm())
- GET /api/conversion/active(lazy rebuild ownership)
- GET /api/conversion/{job_id}(poll status)
- POST /api/conversion/{job_id}/promote-to-models(FAA pull → models 三段式)
- GET /api/conversion/{job_id}/download(server-side HTTP 302 → FAA,token 不過 frontend
JS,仿 FAA TestSite DownloadFileDirect pattern;Cache-Control: no-store)
5 個 endpoint 全部走 OIDC AuthMiddleware;user_id 從 cookie session 灌(trust boundary),
從不接受 client multipart form / JSON / query 的 user_id。
TestAllAPIEndpointsRequire401WithoutCookie 自動覆蓋新 5 endpoint regression 防呆。
新增 cmd/api-server/conversion_e2e_test.go(4 個 e2e 場景):
- TestConversionE2E_StreamingProxy(10MB body + trust boundary regression)
- TestConversionE2E_LazyRebuildAfterRestart(visionA 重啟仍能 /active)
- TestConversionE2E_Download302Redirect(驗 302 + Location header + token 不在 body)
- TestConversionE2E_ActiveJobConflict(409 + active_job 詳情)
修改 internal/config/{config,load}.go:新增 ConversionConfig 5 欄位
(ConverterBaseURL / FAABaseURL / TenantID / ServiceClientID / ServiceClientSecret)+
Enabled() helper(雙非空判定)。
修改 cmd/api-server/main.go:條件 wire(cfg.Conversion.Enabled() 為 true 才建 client + Service;
否則 Deps.Conversion=nil,handler 自動回 501)。
修改 .env.example:新增 Phase 0.8 區塊註解。
新增 cmd/api-server/conversion_adapters.go:narrow interface adapter(接既有
internal/model.Repository / internal/storage.Store → conversion.ModelStore / Storage,避免 import cycle)。
驗證:go test -race -count=3 ./... 17 packages 全綠 / go vet 0 warning / go build 成功。
對齊文件:
- .autoflow/04-architecture/adr/adr-014-conversion-integration.md
- .autoflow/04-architecture/conversion.md (TDD)
- .autoflow/04-architecture/api/api-conversion.md
- .autoflow/02-prd/features/feature-converter-integration.md
- .autoflow/03-design/wireframes/wireframe-conversion.md
- .autoflow/03-design/flows/flow-conversion.md
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
visionA
Innovedus visionA monorepo — Edge AI 開發平台(離線版 + 雲端版)。
開發環境快速啟動
make dev-up # 起 backend + Member Center(OIDC)+ Postgres
make frontend-dev # 另開 terminal:起 frontend dev server(pnpm dev)
# 開瀏覽器 http://localhost:3000
完整流程(含 OAuth client 手動註冊、port 對照、疑難排解)見 docs/DEV-SETUP.md。
其他 target:make help。
子專案
| 專案 | 角色 | 狀態 |
|---|---|---|
local-tool/ |
離線版 桌面工具(Wails + Go + Next.js) | 穩定維護 |
visionA-frontend/ |
雲端版 web 前端(Next.js) | ✅ Phase 0 雛形 |
visionA-backend/ |
雲端版後端(Go,雙 binary:api-server + remote-proxy) | ✅ Phase 0 雛形 |
local-agent/ |
visionA Agent — 雲端版 local 端代理(Wails + Go + Next.js) | ✅ Phase 0.5 雛形 |
架構關係
離線模式(local-tool 單獨)
使用者瀏覽器 → localhost:3721 (local-tool server) → Kneron 裝置
雲端模式(visionA 雲端版 + visionA Agent)
使用者瀏覽器 → visionA-frontend (CDN) → visionA-backend (api-server)
↓ internal HTTP
visionA-backend (remote-proxy)
↓ WebSocket + yamux tunnel
使用者電腦上的 visionA Agent
↓ 本機 HTTP
Agent 的內部 server → Kneron 裝置
兩種模式可在同一台電腦共存(local-tool 和 visionA Agent 獨立安裝、不衝突)。
產品線原則
- local-tool 不動,需要時 fork
- 雲端 vs 本機差異只在前端部署位置
- 雲端 agent 的 server ≈ local-tool 的 server(差別在沒本機操作 UI)
- 雲端 web UI 先抄 local-tool,之後再加新功能
文件
完整產品文件見 .autoflow/:
- 產品需求:
.autoflow/02-prd/PRD.md - 設計規格:
.autoflow/03-design/design-spec.md - 架構總覽:
.autoflow/04-architecture/design-doc.md - 交付總結:
.autoflow/07-delivery/project-summary.md
License
TBD(內部使用)
Description
Languages
Go
54.6%
TypeScript
33.4%
Python
3.8%
Makefile
1.8%
JavaScript
1.8%
Other
4.6%