kneron_model_converter/docs/autoflow/03-design/user-flow-cross-system.md
jim800121chen cff9236699 docs: migrate Autoflow shared documents to docs/autoflow/
Move PRD, design specs, architecture docs, and TDD from .autoflow/
(personal/per-branch layer) to docs/autoflow/ (shared layer that
goes into git) per the new Autoflow workspace layout.

Files moved:
- 02-prd/PRD.md
- 03-design/design-review.md
- 03-design/user-flow-cross-system.md
- 04-architecture/TDD.md
- 04-architecture/design-doc.md
- 04-architecture/security.md

The originals were never tracked, so git mv reduced to a filesystem
rename with no history to preserve. .autoflow/ remains for personal
notes (progress.md, review reports, testing logs).

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

18 KiB
Raw Blame History

跨系統使用者流程圖 — VisionA 終端使用者視角

視角VisionA 終端使用者Edge AI 應用開發者)在 VisionA 平台內完成模型轉檔的完整體驗。

重點從使用者能「感知到什麼」切入而非技術細節。Token 種類、錯誤情境等只標示關鍵分支,詳細 API 規格見 04-architecture/TDD.md

涵蓋情境

  • 情境 A首次上傳模型並轉檔主要 Happy Path
  • 情境 B離開頁面後回來看未完成的 jobRecovery
  • 情境 CPhase 2 使用者下載模型(阻塞中 — 僅供未來參考)

服務標記慣例

  • 🧑 = VisionA 終端使用者(人類)
  • 🖥️ = VisionA 前端(瀏覽器)
  • ⚙️ = visionA-backendGo 服務)
  • 🔐 = Member CenterAuth 中心)
  • 📦 = File Access Agent檔案閘道
  • 🏭 = Kneron Converter API本專案
  • 🗄️ = Converter BucketMinIO 暫存)
  • 💾 = NAS Bucket模型庫長期儲存

變更歷程

日期 變更內容
2026-04-25 原始模型上傳路徑改為 visionA-backend → Converter multipart 直連(不經過 File Access AgentPOST /api/v1/jobs 改為 multipart/form-data移除 input_object_key 欄位,user_id 改以 multipart field 帶入。Phase 1 Converter 不再從 File Access Agent 讀取原始模型,只在 promote 階段 PUT 結果檔。階段編號:原「階段 2上傳 FAA+ 階段 3建 job」合併為新「階段 2建 job + 上傳)」,後續階段編號往前挪一格。

情境 A使用者上傳新模型並轉檔Happy Path

A.1 使用者視角的流程摘要(非技術)

🧑 使用者在 VisionA 平台
     │
     ├─ 1. 在「模型庫」按「新增模型」→ 選本機 ONNX 檔
     │
     ├─ 2. 填寫 model_id / version / 選擇 Kneron 晶片平台520/720/...
     │
     ├─ 3. 按「上傳並轉檔」
     │       ↓
     │    [系統顯示進度條ONNX 優化 0% → 33% → BIE 量化 33% → 66% → NEF 編譯 66% → 100%]
     │
     ├─ 4. 轉檔完成!顯示成功訊息 + 「加進我的模型庫」按鈕
     │
     └─ 5. 按「加進我的模型庫」→ 短暫 loading → 顯示「已加入模型庫」
           ↓
        使用者在模型庫看到新的已轉檔模型

使用者感知到的總體體驗:從選檔到加進模型庫,一條流水線,使用者不需要知道背後有多個服務在協作(建 job 時涉及 visionA-backend / Member Center / Converterpromote 時才會再呼叫 File Access Agent


A.2 完整跨系統流程圖Mermaid Sequence

sequenceDiagram
    autonumber
    participant U as 🧑 使用者
    participant FE as 🖥️ VisionA 前端
    participant BE as ⚙️ visionA-backend
    participant MC as 🔐 Member Center
    participant FA as 📦 File Access Agent
    participant CV as 🏭 Converter API
    participant CB as 🗄️ Converter Bucket
    participant NB as 💾 NAS Bucket

    Note over U,FE: 階段 1選檔 + 填表
    U->>FE: 選本機 ONNX 檔
    U->>FE: 填 model_id / version / platform
    U->>FE: 按「上傳並轉檔」
    FE->>BE: 送出 (multipart: 檔案 + 參數)

    Note over BE,CB: 階段 2visionA-backend 呼叫 Converter 建 jobmultipart 同時帶原始模型)
    BE->>MC: POST /oauth/token (client_credentials, scope=converter:job.write)
    MC-->>BE: service token (aud=kneron_converter_api)
    BE->>CV: POST /api/v1/jobs<br/>Authorization: Bearer token<br/>Content-Type: multipart/form-data<br/>files: model (必填, ≤500MB), ref_images[] (optional, maxCount 100)<br/>fields: user_id, model_id, version, platform, enable_evaluate, enable_sim_fp, enable_sim_fixed, enable_sim_hw
    CV->>MC: 驗 token (JWKS)
    MC-->>CV: 驗證通過
    CV->>CV: 檢查user_id 是否有 in-progress job?<br/>US-11 同使用者一個轉檔限制)

    alt 有 in-progress job
        CV-->>BE: 409 Conflict + {code: user_has_active_job, active_job_id, active_job_status, active_job_stage}
        BE-->>FE: 409 + active job 詳情
        FE-->>U: 顯示「你有一個轉檔進行中,要切過去看嗎?」
        Note over U: 走情境 BRecovery
    else 沒有 in-progress job
        CV->>CB: 寫入原始模型 (jobs/{job_id}/input/{filename})<br/>(含 ref_images[] 如有)
        CV->>CV: 建 job 記錄,塞進 Redis<br/>Enqueue 到 onnx-worker
        CV-->>BE: 201 Created + {job_id, status: created}
        BE-->>FE: 201 + job_id
    end

    Note over FE,CV: 階段 3Polling 進度(每 2-5 秒一次)
    loop 直到 status=completed 或 failed
        FE->>BE: GET /api/jobs/{job_id}/status
        BE->>CV: GET /api/v1/jobs/{job_id}<br/>Authorization: Bearer token
        CV-->>BE: {status, stage, progress, stage_timings, expires_at, ...}
        BE-->>FE: 轉譯後的進度 JSON
        FE->>U: 更新進度條 + 階段顯示
    end

    Note over CV: Worker 背景處理ONNX → BIE → NEF<br/>Crash 即 Reset 設計,不保證跨 Crash 存活)
    CV->>CB: 儲存各階段結果out.onnx / out.bie / out.nef

    Note over FE,U: 階段 4轉檔完成顯示「加進模型庫」按鈕
    CV-->>BE: {status: completed, result_object_keys: [...], expires_at: "2026-05-02"}
    BE-->>FE: 已完成 + result 資訊
    FE->>U: 顯示「轉檔完成!」<br/>+「加進我的模型庫」按鈕<br/>+「檔案將於 7 天後自動清除」提示

    Note over U,NB: 階段 5使用者按「加進模型庫」→ promote
    U->>FE: 按「加進我的模型庫」
    FE->>BE: POST /api/models/{job_id}/add-to-library
    BE->>CV: POST /api/v1/jobs/{job_id}/promote<br/>Authorization: Bearer token<br/>Body: {target_object_key: "visionA/models/{user_id}/{model_id}/v{version}/out.nef", ...}
    CV->>MC: 取 files:upload.write token若 cache 過期)
    MC-->>CV: service token
    CV->>CB: 讀結果檔
    CV->>FA: PUT /files/{target_object_key}<br/>Authorization: Bearer token<br/>Body: out.nef
    FA->>MC: 驗 token
    MC-->>FA: 驗證通過
    FA->>NB: 儲存到 NAS使用者的模型庫區
    FA-->>CV: 200 OK
    CV-->>BE: 200 OK + promoted_object_keys
    BE-->>FE: 成功
    FE->>U: 顯示「已加入模型庫」
    Note over U: 使用者在模型庫看到新模型

A.3 使用者感知到什麼 vs 背後發生什麼

使用者看到 / 做的事 背後發生的事(簡述)
選檔並按「上傳並轉檔」 visionA-backend 以 multipart/form-data 直接把原始模型上傳到 Converter經 Member Center auth 取 converter:job.write service tokenConverter 收檔後暫存在自己的 Bucket
進度條跳動 visionA-backend 每 2-5 秒 polling Converter拿到新進度就更新 UI
「ONNX 優化 → BIE 量化 → NEF 編譯」階段切換 Converter 的 Task Scheduler 在 Redis 中推進 job stageWorker 消耗 stage queue
「檔案將於 7 天後自動清除」 Converter Bucket 有 7 天 lifecycle促使使用者做 promote
按「加進我的模型庫」 visionA-backend 呼叫 Converter /promoteConverter 自己把檔案 PUT 到 File Access Agent不經 visionA-backend省流量
模型出現在使用者的模型庫 NAS Bucket 已經收到檔案(在 VisionA 使用者模型庫的 objectKey path 下)

A.4 關鍵時間點與可能的等待體驗

時間點 使用者感受 影響 UX 的因素
按「上傳並轉檔」後 Loading / 上傳進度條 單一 multipart 上傳從 visionA-backend 到 Converter 的時間,與檔案尺寸相關(上限 500MB建議 UI 顯示 upload progress barmultipart 上傳可追蹤 byte 進度XHR upload progress event 或等效機制),不再像舊設計有「上傳 FAA + 拉檔入 Bucket」兩段式等待
進度條階段切換 期待每階段的時間均等,但實際上 NEF 通常最久 建議 UI 顯示各階段預估時間(可從 stage_timings 歷史推算)
轉檔完成 → 按「加進模型庫」 短暫 loading API p95 < 3s使用者體感應該 OK
轉檔失敗 希望看到具體原因 錯誤碼要結構化,error.details.stage + 人類可讀的 error.details.reason

情境 B使用者離開頁面後回來Recovery

B.1 使用者視角

🧑 使用者在轉檔進行中...
     │
     ├─ 按上一頁 / 關閉瀏覽器 / 切到其他 app
     │    [Converter 背景繼續轉檔,不受影響]
     │
     ├─ 15 分鐘後回來 VisionA進入「模型庫」或「轉檔中心」
     │
     ├─ 系統自動偵測到「你有一個轉檔進行中」
     │    └─ 顯示:「模型 XYZ 正在轉檔BIE 階段 60%),要繼續追蹤嗎?」
     │
     └─ 使用者按「繼續追蹤」→ 回到進度頁,正常 polling 進度

B.2 跨系統流程Mermaid Sequence

sequenceDiagram
    autonumber
    participant U as 🧑 使用者
    participant FE as 🖥️ VisionA 前端
    participant BE as ⚙️ visionA-backend
    participant MC as 🔐 Member Center
    participant CV as 🏭 Converter API

    Note over U,FE: 使用者重新打開 VisionA 模型庫頁
    U->>FE: 進入頁面
    FE->>BE: GET /api/models/in-progress?user_id=...
    BE->>MC: 取 service token若 cache 過期)<br/>scope=converter:job.read
    MC-->>BE: service token
    BE->>CV: GET /api/v1/jobs?user_id=...&status=in_progress<br/>Authorization: Bearer token
    CV->>MC: 驗 token
    MC-->>CV: 驗證通過
    CV->>CV: 從 Redis 查 user_id 對應的所有 in-progress job
    CV-->>BE: [{job_id, status, stage, progress, created_at}, ...]

    alt 有 in-progress job
        BE-->>FE: job 列表
        FE->>U: 顯示「你有一個轉檔進行中<br/>模型 XYZ - BIE 階段 60%<br/>[繼續追蹤] [放著不管]」
        U->>FE: 按「繼續追蹤」
        FE->>U: 進入進度頁,開始 polling<br/>(同情境 A 階段 4
    else 沒有 in-progress job
        BE-->>FE: 空陣列
        FE->>U: 正常顯示模型庫頁,不打擾使用者
    end

    Note over CV: ⚠️ 特別情境Converter 在使用者離開期間 Crash
    Note over CV: Redis 被重置 → in-progress job 消失<br/>符合「Crash 即 Reset」設計
    Note over U: 使用者回來看不到 job<br/>需要重新上傳US-12 已明示此限制)

B.3 Recovery 的 UX 考量

考量點 處理建議
使用者不記得自己有 job 在跑 進入頁面時主動查詢並顯示提示
使用者有多個裝置(手機+電腦)都登入 每個裝置都會看到相同的 in-progress job因為是 server-side 查詢)
Converter Crash 導致 job 消失 VisionA 前端顯示「上次的轉檔記錄已遺失,建議重新上傳」(需 visionA-backend 決定是否保留本地 cache
回來時 job 已完成 可查 GET /api/v1/jobs?user_id=...&status=completed 看最近完成的 job可選功能

情境 CPhase 2 — 使用者直接下載模型庫檔案(阻塞中)

⚠️ 重要提示:本情境的 POST /file-access/download-tokens endpoint 在 Member Center 尚未實作Phase 1 不做此情境

以下流程圖僅供未來 Phase 2 啟動時參考。Phase 1 上線時使用者如何處理下載需求,見 design-review.md 第 6 節「議題 #1」。

C.1 Phase 2 目標使用者體驗

🧑 使用者在 VisionA 模型庫
     │
     ├─ 看到已轉檔的模型
     │
     ├─ 按「下載 .nef 檔」
     │
     └─ 瀏覽器直接下載(快速,因為直連 File Access Agent不經 visionA-backend

C.2 Phase 2 跨系統流程Mermaid Sequence尚未實作

sequenceDiagram
    autonumber
    participant U as 🧑 使用者
    participant FE as 🖥️ VisionA 前端
    participant BE as ⚙️ visionA-backend
    participant MC as 🔐 Member Center
    participant FA as 📦 File Access Agent
    participant NB as 💾 NAS Bucket

    Note over U,FE: 使用者按下載按鈕
    U->>FE: 按「下載 .nef」
    FE->>BE: POST /api/models/{model_id}/download-token

    Note over BE,MC: ⚠️ Phase 2 阻塞中Member Center 尚未實作此 endpoint
    BE->>MC: POST /file-access/download-tokens<br/>Body: {tenant_id, user_id, object_key, scope: "files:download.delegate"}
    MC-->>BE: {delegated_token (opaque, exp <= 5min), expires_at}
    BE-->>FE: delegated_token + File Access Agent 的 download URL

    Note over FE,FA: 瀏覽器直接下載(不經 visionA-backend省流量
    FE->>FA: GET /files/{object_key}?token=<delegated_token>
    FA->>MC: POST /validate-delegated-token<br/>Body: {token}
    MC-->>FA: {valid: true, user_id, object_key, tenant_id}
    FA->>NB: 讀檔
    FA-->>FE: 檔案stream 下載)
    FE->>U: 瀏覽器儲存檔案

C.3 Phase 2 體驗 vs Phase 1 折衷方案的 UX 落差

項目 Phase 1 折衷方案(任一) Phase 2 完整方案
下載速度 慢(大檔走 visionA-backend proxy或無法下載隱藏按鈕 快(瀏覽器直連 File Access Agent
對 visionA-backend 的負擔 高(若 proxy
檔案流量路徑 使用者 → visionA-backend → File Access Agent → 使用者 使用者 ↔ File Access Agent直連
使用者 UX 有 spinner可能 timeout 瀏覽器原生下載體驗
安全性 同 Phase 2都走 Member Center auth

綜合:三個情境的狀態機

stateDiagram-v2
    [*] --> 選擇模型: 使用者進入 VisionA

    選擇模型 --> 上傳中: 選檔 + 填表 + 提交
    上傳中 --> 建 job: multipart 直接上傳到 Converter含原始模型 + ref_images

    建 job --> 有衝突: 檢查 user_id 已有 in-progress
    有衝突 --> 繼續追蹤舊 job: 使用者選擇查看既有 job

    建 job --> 轉檔中: 無衝突Converter 收檔並建立 job
    轉檔中 --> ONNX 階段
    ONNX 階段 --> BIE 階段: 完成
    BIE 階段 --> NEF 階段: 完成
    NEF 階段 --> 轉檔完成: 完成

    ONNX 階段 --> 轉檔失敗: 失敗
    BIE 階段 --> 轉檔失敗: 失敗
    NEF 階段 --> 轉檔失敗: 失敗

    轉檔中 --> 使用者離開: 使用者關頁面
    使用者離開 --> 繼續追蹤舊 job: 使用者回來(走情境 B Recovery
    使用者離開 --> Job 消失: Converter Crash符合設計哲學
    Job 消失 --> [*]

    轉檔完成 --> 已 promote: 使用者按「加進模型庫」Converter PUT 到 File Access Agent
    已 promote --> 下載: 使用者要用模型

    下載 --> Phase 1 折衷: Phase 1下載功能缺口
    下載 --> Phase 2 直連: Phase 2等 Member Center 補完)

    轉檔失敗 --> [*]: 使用者看錯誤訊息
    Phase 1 折衷 --> [*]
    Phase 2 直連 --> [*]
    繼續追蹤舊 job --> 轉檔中

附錄Token 類型快速對照

Token 誰持有 誰簽發 誰驗 用途
visionA-backend service tokenaud=kneron_converter_api, scope=converter:job.write / converter:job.read visionA-backend Member Centerclient_credentials grant Converter APIJWKS 驗簽) visionA-backend 呼叫 Converter API建 job / 查詢 / promote
Converter service tokenaud=file_access_api, scope=files:upload.write Converter API Member Centerclient_credentials grant File Access Agent Converter 在 promote 階段 PUT 結果檔到 NAS。Phase 1 不再需要 files:download.read / files:metadata.read,因為原始模型已改由 visionA-backend multipart 直接上傳到 ConverterConverter 不再從 FAA 拉檔
Delegated download tokenPhase 2 瀏覽器 Member Center代 user 簽) File Access Agent線上驗 使用者瀏覽器直連 File Access Agent 下載

附錄:錯誤情境快速對照

使用者看到的訊息 技術原因 對應 HTTP 狀態 + error code
「你有一個轉檔進行中,要切過去看嗎?」 同使用者同時一個轉檔限制觸發 POST /api/v1/jobs 回 409 user_has_active_job
「轉檔失敗BIE 量化階段 — [具體原因]」 Worker 內部失敗 Job 的 status=failed, error.details.stage=bie, error.details.reason=...
「上傳失敗,請確認檔案格式與欄位」 multipart body 格式錯 / model 欄位缺失 / 必填 field 缺失(例如 user_idmodel_id POST /api/v1/jobs 回 400 invalid_multipart
「檔案過大,請確認模型不超過 500MB」 上傳檔案超過 Converter 的大小上限 POST /api/v1/jobs 回 413 file_too_large
「模型庫服務暫時不可用,請稍後再試」 promote 時 File Access Agent 不可用 POST /promote 回 502 file_gateway_unavailable
「轉檔還沒完成,請等進度條到 100% 再加進模型庫」 promote 時 job 還沒 completed POST /promote 回 409 job_not_ready_for_promote
「你的登入已過期,請重新登入」 visionA-backend 的 user session 過期visionA 自己的 auth不是 Converter 的問題) visionA-backend 自己處理
「系統錯誤,請聯絡客服」 Member Center 或 File Access Agent 完全無法連線 POST /api/v1/jobs 回 503 auth_service_unavailable 或類似Phase 1 建 job 本身不依賴 FAAFAA 錯誤集中在 promote

結語

這份跨系統流程圖揭露的關鍵 UX 訊息:

  1. 使用者只看到「在 VisionA 平台內按幾下就轉完」背後有多個服務協作visionA-backend / Member Center / Converter / File Access Agent— 這是架構要盡力維持的體驗。值得注意的是 Phase 1 建 job 階段只涉及 3 方visionA-backend / Member Center / ConverterFile Access Agent 僅在 promote 階段參與,簡化了上傳時的故障面
  2. Phase 1 的 UX 閉環卡在「下載」,需要 VisionA 產品團隊協調 messagingdesign-review.md 議題 #1
  3. Recovery 體驗是 VisionA 的 UX 優勢但受限於「Crash 即 Reset」設計不保證跨 Crash 存活 — 要誠實告知使用者
  4. 錯誤訊息的人類可讀性直接決定使用者對系統的信任Architect 在 TDD 中要重視 error code 的結構化設計
  5. multipart 直連上傳的 UX 優勢相較於舊設計「visionA-backend → FAA → Converter 拉檔」兩段式,新設計從使用者按下「上傳並轉檔」到 Converter 建 job 成功,只有一次網路傳輸;上傳時間可用 progress bar 精準呈現,不再有中間「看不見的 Converter 拉檔等待」