依 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)。
26 KiB
Phase 0.8 三方交叉審閱 — Architect 視角
作者:Architect Agent 日期:2026-04-30 審閱對象:PM PRD(
feature-converter-integration.md)、Design wireframe(wireframe-conversion.md)、Design flow(flow-conversion.md) 對照基準:Architect ADR-014 v1.1、conversion.mdv0.3、api/api-conversion.mdv0.3
摘要
| 對象 | 嚴重 | 中 | 小 / nit |
|---|---|---|---|
| PM PRD | 1 | 4 | 2 |
| Design wireframe | 1 | 2 | 2 |
| Design flow | 1 | 1 | 1 |
嚴重 = 直接導致實作有歧義或 frontend / backend 對不上;中 = 文件不精確但可推測;小 = 命名 / 措辭。
Architect 自己的 TDD 修訂:4 個章節(議題 #2 / #5 / #6 / #7)已寫進 conversion.md v0.3 + api/api-conversion.md v0.3。詳見 §3。
需要使用者裁決的事項:1 件(API endpoint 路徑命名 — /api/conversion/* vs /api/converter/jobs/*,目前三方文件不一致)。
1. 對 PM PRD 的審閱(02-prd/features/feature-converter-integration.md)
1.1 ✅ 同意的部分
- §1 概要 / §2 User Stories:MVP 範圍清楚,半自動設計理由明確
- §3 F1–F5 的功能定義:與我 TDD 的 endpoint 行為對齊(status enum、5–10s polling、500MB cap、ref images 上限、translated error messages)
- §4 非功能需求:500MB / 10MB / 100 張上限、polling 間隔、active job 限制 — 全部已在 TDD §4 / §9 / §10 cover
- §5 Non-Goals:完整且符合 MVP 邊界(不做歷史 / 取消 UI / SSE / 多 chip)
- §6 整合決策 D1–D6:與 ADR-014 完全一致(streaming proxy / FAA 直連 / 半自動 / polling / converter API 不動 / sidebar 獨立 tab)
- §7 Dependency 一覽:清楚標出 converter / FAA / MC / visionA-backend / visionA-frontend 各自要做什麼
- §9 驗收條件:可測、與 TDD 行為對齊
- §11 給 Architect 的注意事項:streaming proxy 用
io.Pipe不 buffer 全 RAM、user-scoped 授權、idempotent promote — 全部已落地
1.2 ⚠️ 嚴重 — API endpoint 路徑命名與 TDD 不一致
位置:PRD §F6 / §F7
PRD §F6:POST /api/converter/jobs/{id}/import-to-models
PRD §F7:POST /api/converter/jobs/{id}/download-token
Wireframe §3.3 / Flow §3:GET /api/converter/jobs/active
Wireframe §6.3:GET /api/converter/jobs/{id}(polling)
TDD(Architect):
POST /api/conversion/init
GET /api/conversion/{job_id}
POST /api/conversion/{job_id}/promote-to-models
GET /api/conversion/{job_id}/download ← 注意:是 GET、不是 POST `/download-token`
GET /api/conversion/active
三個衝突點:
- path prefix:
/api/converter/jobs/*(PM/Design)vs/api/conversion/*(Architect) - action 命名:
import-to-models(PM)vspromote-to-models(Architect) - download endpoint method + 形式:PRD/Design 假設
POST /download-token回{url, expires_at}JSON;TDD 已改為GET /downloadserver-side 302 redirect(ADR-014 v1.1 議題 #9 已決議的安全升級)
建議改法:
採 Architect 的版本(/api/conversion/* + promote-to-models + GET /download 302)— 理由:
- 路徑前綴
/conversion/對應 visionA 內部模組名(internal/conversion/),命名一致 /converter/jobs/*容易讓人誤以為是「轉發給 converter 的 raw API」(其實 visionA backend 有自己的 ownership / 半自動邏輯,不是純 proxy)promote-to-models對齊 converter 的/promote動詞、語意精確GET /download+ 302 已在 ADR-014 v1.1 完成決策(安全考量壓倒 UX 微差)
請 PM 修(新增到 §1.3 PM 修訂建議清單):
- §F6 endpoint 改
POST /api/conversion/{job_id}/promote-to-models - §F7 endpoint 改
GET /api/conversion/{job_id}/download(server 302 redirect)+ 移除「visionA backend 跟 Member Center 換 delegated download token」的描述(這仍正確但藏在 server-side),把「回傳{url, expires_at}」改為「browser 自動 follow 302 直連 FAA」
請 Design 修(同節 §2.2):
- wireframe §3.3、wireframe §6.3、flow §3 / §5.5 / §8.2 全部
/api/converter/jobs/*→/api/conversion/* - flow §3 sequence diagram 的 download 那段
POST /api/converter/jobs/{id}/download-token+200 { url, expires_at }→GET /api/conversion/{id}/download+302 Location: faa-url - wireframe §7.2「下載」流程描述:移除「拿到
{ url, expires_at }」,改為「按鈕觸發 anchor click 或window.location.href = '/api/conversion/{id}/download',browser 自動處理 302」
1.3 ⚠️ 中 — Active job 端點未列入 PRD
位置:PRD §F 段(功能需求)
PRD §F1–F7 沒有列出「Active job pre-check」這個功能,但 §3 F3 隱含提到「同 user 同時只能跑一個 active job」。Design wireframe §3.3 與 flow §5.1 明確使用 GET /api/converter/jobs/active(建議改名 /api/conversion/active)做 idle / 重新整理 / 多分頁的恢復邏輯。
建議:PRD §F 段補一條 F0:
### F0:進入「轉檔」頁面時的 active job 偵測
- 進入 /conversion 時前端打 GET /api/conversion/active
- 後端回應 `{ has_active: bool, job? }`
- has_active=true → 直接顯示「進行中」畫面(同 F3)+ banner「您離開前的轉檔仍在進行中」
- has_active=false → 顯示空狀態 + CTA
理由:這個端點是 wireframe 的核心(§3.3、§6.4 多分頁同步、§6.6 重啟頁面恢復),在 PRD 沒列就成了「設計依賴的隱形 contract」,三方對齊時容易遺漏。
1.4 ⚠️ 中 — Streaming upload 進度語意未明示
位置:PRD §F2「上傳行為」、§F3「轉檔執行與進度」
PRD §F2 寫「使用者看到的是『上傳到 visionA』的單一進度條(XHR upload event)」— 這裡有歧義:
- 語意 A:XHR
upload.onprogress顯示 browser → backend 的進度。當 browser send 完 100% 後,backend 還在 forward 給 converter 的階段,前端顯示什麼? - 語意 B:「上傳到 visionA」= browser → backend 的單一進度,使用者看到 100% 就視為完成
實作上若採 B,則 backend 需要 background goroutine + 額外 ownership 狀態(upload_in_progress)才能 early-return;採 A 則 backend 等 converter 201 才回 200,前端進度顯示 100% 後到實際切 processing 之間有 1-3 秒「即將完成…」/「伺服器處理中…」。
TDD 採用語意 A(見 conversion.md §4.3.1 v0.3 新增)— 理由:
- 100% 接近端到端真實狀態,使用者不會被欺騙
- 實作簡單,失敗處理路徑清楚
- 1-3 秒延遲對 500MB 上傳體感影響極小
建議 PM 補在 §F2 / §F3:
> **進度條語意說明**:上傳進度條顯示 browser → visionA-backend 的進度。當顯示 100% 但
> backend 還在轉發給 converter 時,文案會切為「即將完成…」/「伺服器處理中…」(1–3 秒),
> 然後才切到「轉檔進行中」畫面。對使用者誠實 — 不謊報已完成。
1.5 ⚠️ 中 — Promote-to-models request body 對齊 Design
位置:PRD §F6「加到模型庫」流程
PRD §F6 沒有提到「需要使用者輸入名稱」,但 Design wireframe §7.1 設計了 import Dialog 含名稱輸入欄。我這邊 API spec(v0.3)已對齊 Design 的「單欄位 name only」決議。
建議 PM 補在 §F6:
- 點「加到模型庫」開確認 Dialog(單欄位):
- 模型名稱(預設 `{source_filename_stem}_{target_chip.lower()}`,可改)
- 描述欄位 Phase 1 才開放
- 確認後呼叫 POST /api/conversion/{id}/promote-to-models
或在 §F6 末尾加註:「Dialog UI 與欄位定義詳見設計規格 wireframe §7.1。」
1.6 ⚠️ 中 — visionA-backend 重啟後的 UX
位置:PRD §11 給 Architect 的注意事項 / 應該補在 §6 整合決策或 §F0
PRD 沒有討論 visionA-backend 重啟(部署、crash recovery)後使用者 UX 該怎樣。我 TDD §2.6.1 v0.3 補了 lazy rebuild 機制(A4 方案 — /active 端點 fallback 對 converter 查 ?user_id=&status=in_progress),讓使用者重啟後仍能看到自己的 active job。
這需要 converter Phase 1 提供 GET /api/v1/jobs?user_id=&status=in_progress endpoint(converter Phase 1 已實作,但 PRD §7 dependency 表未列入「visionA 會用此 endpoint」)。
建議 PM 補在 §7 Dependency 表:
| kneron_model_converter | ❌ 完全不用動 | 沿用既有 endpoint:`POST /api/v1/jobs`、`GET /api/v1/jobs/{id}`、`POST /promote`、`GET /api/v1/jobs?user_id=&status=in_progress`(visionA-backend 重啟後 lazy rebuild ownership 用)、`POST /api/v1/jobs/{id}/cancel`(visionA-backend 偵測 client disconnect 時內部 cleanup 用) |
也建議在 §6 整合決策表加一條 D7:
| D7 | visionA-backend in-memory ownership 重啟遺失 | Phase 0.8 採 lazy rebuild(`/active` fallback 對 converter 查);Phase 0.9+ 評估 DB persist | converter 7 天 expires_at 兜底;UX 上使用者重進頁面仍看得到 active job |
1.7 小 — KPI「上傳到拿 NEF P95 < 10 分鐘」量測點
位置:PRD §8 KPI
PRD §8 寫「visionA backend 在 import / download 觸發點 log timestamp」— 但 import/download 是「使用者拿到 NEF 後的下一步」,不是「拿到 NEF 的當下」。建議改:
- 量測點 = converter status 從
running→succeeded的當下時間 -init收到 request 的時間 - 這是 backend 視角的端到端時間,不依賴使用者按按鈕
非阻擋議題,建議調整。
1.8 小 — 4 個 chip 數量
PRD §F2 寫「目標 chip:KL520 / KL630 / KL720 / KL730」(4 個),但 TDD api-conversion.md §1 與 converter platform 欄位的 enum 寫的是 520 / 720(2 個)。需確認:
- converter Phase 1 實際支援哪幾個 platform?
- 如果只支援 520 / 720,PRD 應改為 2 個(避免使用者選了 630/730 然後被 converter 拒絕)
- 如果 converter Phase 1 已擴充到 4 個,TDD
platformenum 應改為520 / 630 / 720 / 730
建議 PM:請與 converter 團隊確認 Phase 1 實際支援的 chip list,PRD 與 TDD 同步更新。
2. 對 Design 的審閱
2.1 對 Wireframe(03-design/wireframes/wireframe-conversion.md)
2.1.1 ✅ 同意的部分
- §0 設計對齊備註:複用既有元件、不新增 Design Tokens、走 i18n — 全部對的方向
- §1 Sidebar 進入點:放模型庫之後,心智模型清楚;Wand2 icon 選擇合理
- §2 頁面狀態總覽:state 機切 4 種畫面,無 URL query state — 簡潔正確
- §3.3 邊界 — 已有 active job:用
GET /jobs/active做進入恢復是正確的設計(解決多分頁 / 重新整理 / 重啟) - §4 Upload Dialog:階段切換(select / uploading)合理;§4.4 上傳失敗的 4 種 case 完整
- §5 主畫面 vs Dialog 進度:分開顯示避免使用者困惑、tab title 動態更新
- §6 Processing 畫面:3-stage indicator 設計、indeterminate progress、polling 間隔(5s 前 60 秒、之後 10s)— 都與 TDD 對齊
- §6.4 邊界情境:4 種情境(關分頁、多分頁、長排隊、長執行)有 cover
- §7 Success 結果:兩按鈕互不互斥 / 過期倒數 / 「開始新轉檔」放外面 — 與 PRD §F4 對齊
- §8 Failed 狀態 + suggestions:依 error code 切換建議很棒
- §8.2 Job 已過期:對 TDD
expires_at機制依賴正確 - §9 響應式 / §11 i18n / §12 無障礙:全部到位
2.1.2 ⚠️ 嚴重 — endpoint 路徑與 TDD 不一致
同 §1.2。請改 /api/converter/jobs/* → /api/conversion/*、POST /download-token 形式 → GET /download + 302 redirect。
具體要改的位置:
- §3.3 邊界表「
GET /api/converter/jobs/active」 →GET /api/conversion/active - §6.3 polling 表「端點
GET /api/converter/jobs/{id}」 →GET /api/conversion/{id} - §7.1 「呼叫 POST /api/converter/jobs/{id}/import-to-models」 →
POST /api/conversion/{id}/promote-to-models - §7.2 整段流程:去掉
POST /download-token+ 拿{ url, expires_at }→ 改為 anchor tag 觸發GET /api/conversion/{id}/download,browser 自動 follow 302
§7.2 流程修改範例:
- 1. 點擊 → 按鈕進 loading 狀態(spinner + 「準備下載…」)
- 2. 呼叫 POST /api/converter/jobs/{id}/download-token
- 3. 200 OK:
- - 拿到 { url, expires_at }
- - 立即 window.location.href = url(瀏覽器內建下載管理器接手)
- - 按鈕回到原狀態(不變灰,使用者可重複下載)
+ 1. 點擊 → 觸發 anchor 行為 / window.location.href = '/api/conversion/{id}/download'
+ 2. visionA-backend server-side 302 → browser 自動 follow → 直連 FAA
+ 3. 按鈕不需 loading 狀態(navigation 由 browser 接管)
+ 若需要錯誤處理(例 job_not_completed),可改用 fetch + 檢 302 status
附註:這個改動實際上「簡化」了 Design 的 §7.2 描述(不用處理 token、不用 fetch then redirect)— 是 ADR-014 v1.1 帶來的好處。
2.1.3 ⚠️ 中 — Stage indicator 對應實際狀態
位置:wireframe §6.1 「Stage 對應」表
Design 把 converter 的 running 狀態切成兩個視覺 stage(「解析模型」、「編譯 NEF」),純粹是 UI 上的分段,不對應 converter 內部真實階段。
問題:converter Phase 1 的 GET /api/v1/jobs/{id} response 其實有 stage 欄位(onnx / bie / nef,見 api-conversion.md §2 Job response),這比 wireframe 假設的「單一 running 狀態」更精細。
建議:
- 選項 A:wireframe 的 3-stage 對應到 converter
stage欄位(onnx→ 解析、bie→ 量化、nef→ 編譯),這樣 stage indicator 是真實狀態而不是視覺 fake - 選項 B:維持現狀(fake stage)— 簡單但不夠誠實
Architect 建議選項 A。理由:converter stage 已經提供 — 不利用反而浪費。具體 mapping:
| converter stage | UI stage 名稱 | 觸發條件 |
|---|---|---|
onnx |
解析模型 | converter status=running, stage=onnx |
bie |
量化模型 | converter status=running, stage=bie |
nef |
編譯 NEF | converter status=running, stage=nef |
stage 名稱建議改為 3 個:「解析」/「量化」/「編譯」(更貼近 converter 實際做的事)。
請 Design 對齊 + 改 §6.1:把 stage 名稱與 converter stage 欄位 mapping,並更新 wireframe §11.6 i18n key。
2.1.4 ⚠️ 中 — Upload XHR 進度 100% 後的文案
位置:wireframe §4.2 階段 B「上傳中」
wireframe §4.2 設計「進度條 + 預估剩餘」,但沒明確規定 XHR loaded === total 後但 backend 還沒回 200 的這 1-3 秒要顯示什麼。flow §5.3 有提到「即將完成…」/「伺服器處理中…」— 這需要在 wireframe 對齊:
建議:wireframe §4.2 加註:
**進度 100% 後但伺服器還沒回**:
| XHR 狀態 | 文案 |
|---------|-----|
| progress < 100% | 已上傳 X / Y · 預估剩餘 N |
| progress = 100%, 等待 < 5 秒 | 即將完成… |
| progress = 100%, 等待 ≥ 5 秒 | 伺服器處理中… |
對應 i18n key(§11.5)已有 conversion.uploading.almostDone,建議再加 conversion.uploading.serverProcessing。
2.1.5 小 — 「加到模型庫」按鈕 vs Dialog 確認
wireframe §7.1 設計了確認 Dialog(複用 import flow)— 在 §14 給 PM 的補充第 1 條已正確標記為「待 PM 決定」。
Architect 立場:保留 Dialog 是對的(model record 是永久資源、使用者控制名稱比較自然)。已在 TDD api-conversion.md v0.3 的 promote-to-models request body 對齊「單欄位 name only」。
2.1.6 小 — Wand2 icon 替代
§10 給的替代方案合理(FileCog / Replace),不是 Architect 領地,由 Design / 使用者決定。
2.2 對 Flow(03-design/flows/flow-conversion.md)
2.2.1 ✅ 同意的部分
- §3 全景圖(Mermaid):完整且與 ADR-014 對齊,包含所有 5 個 stage(active check / select / uploading / processing / completed)
- §4 State Machine + 5 狀態保存策略:「不持久化 jobId 全部由 backend
/active提供」是核心原則,正確 - §5.4 Polling 策略:visibilitychange 暫停、退避、終止條件 — 全部與 TDD §9 對齊
- §6 邊界情境:6.1 active job、6.2 上傳失敗、6.3 過期、6.4 多分頁、6.5/6.6 重新整理 — 全部 cover
- §7 UX Writing 要點:誠實呈現狀態、避免技術語 — 對齊 design-spec
- §8.2 給 Architect 的補充:5 條建議,第 1/2/3/4/5 條我都已採納並補進 TDD(謝謝)
2.2.2 ⚠️ 嚴重 — endpoint 路徑與 TDD 不一致
同 §1.2 / §2.1.2。具體位置:
- §3 全景圖 sequence diagram 中所有
POST /api/converter/jobs/GET /api/converter/jobs/{id}/POST /api/converter/jobs/{id}/promote-to-models/POST /api/converter/jobs/{id}/download-token→ 全部改/api/conversion/*前綴 - §3 stage 3b sequence diagram「下載」那段
POST /api/converter/jobs/{id}/download-token+ 「{ url, expires_at }」→GET /api/conversion/{id}/download+HTTP 302 Found, Location: faa-url - §5.5 「下載」分支步驟 1-4 改成 anchor 觸發、browser 自動 302 follow
- §8.2 給 Architect 第 1 條建議端點名稱
修法同 §2.1.2。
2.2.3 ⚠️ 中 — Cancel 後 backend 對 converter 的 cleanup
位置:flow §5.3「取消」末尾、§8.2 給 Architect 第 4 條
flow §5.3 寫「visionA backend 收到取消信號後也要對 converter 發 cancel(避免孤立 job)」— 我在 TDD conversion.md §4.3.2 v0.3 補了完整的 cleanup 鏈分析(C1–C4 情境表 + best-effort cancel via POST /api/v1/jobs/{id}/cancel)。
Design 的這段描述沒問題,但沒講清楚 converter 是否提供 cancel endpoint。事實上 converter Phase 1 已實作 POST /jobs/{id}/cancel(PRD §5 N2 提到),但 PM Phase 0.8 Non-Goals 把「使用者主動取消」列在 N2。
澄清:「使用者主動取消」(PM 不做)≠ 「backend 內部 best-effort cancel 做 cleanup」(TDD 做)。前者是 UI feature、後者是 reliability infra。兩者用同一個 converter endpoint 但語義不同。
建議 Design:在 flow §5.3「取消」末尾加註:
> **澄清**:使用者按「取消上傳」是 frontend 端的 `xhr.abort()`,TCP RST 觸發 backend
> cleanup 鏈,backend 內部會 best-effort 對 converter 發 cancel。這個 cancel **是內部
> 韌性處理**,不暴露 UI;PRD Phase 0.8 Non-Goals N2 講的是「進行中 job 的取消 UI」,
> 兩者不衝突。
2.2.4 小 — expires_at 來源 + frontend 顯示
flow §5.5 success 階段「過期提醒」描述:
計算
expires_at - now()→ 顯示「6 天 21 小時後自動清除」
正確,且 TDD api-conversion.md v0.3 已確保 expires_at 在 Job response 必出現(無論 converter 給或 backend 推算)。✅ 對齊。
3. Architect 自己的 TDD 修訂(這次補上的)
3.1 議題 #2 — visionA backend 重啟後 ownership 全失
修訂:conversion.md §2.6.1(新增)
採方案 A4:lazy rebuild:/active endpoint 在 in-memory miss 時,fallback 對 converter 查 GET /api/v1/jobs?user_id=<sub>&status=in_progress 並重建 ownership。對 frontend 完全透明。
為什麼選 A4 不選 A2(啟動時批次掃):A2 對 converter 是 hammer;A4 是 lazy(user 行為觸發),cost 對應實際需求。
新增依賴:converter Phase 1 的 GET /api/v1/jobs?user_id=&status=in_progress endpoint(converter Phase 1 已實作)。已要求 PM 補進 §7 dependency 表(§1.6)。
3.2 議題 #3 — GET /api/conversion/active 端點
修訂:原本 TDD 已有 GET /api/conversion/active,這次只是把它的 response shape 補上 expires_at / source_filename / target_chip,並文件化「lazy rebuild」行為(議題 #2)。
修訂位置:api/api-conversion.md §5
已對齊 Design 需求:wireframe §3.3 / flow §5.1 進入 /conversion 打 /active 直接落 processing 的設計,能拿到所有需要顯示的欄位(檔名、目標 chip、過期時間)。
3.3 議題 #5 — Cancel 清理鏈
修訂:conversion.md §4.3.2(新增完整章節)
新增內容:
- 4 種 cancel 觸發情境(C1 使用者取消 / C2 重新整理 / C3 網路斷 / C4 converter 拒絕)
- cleanup 鏈:
xhr.abort()→ TCP RST →gin Context.Done()→ goroutinepw.Close()→ io.Pipe EOF → converter multer abort - Best-effort
POST /api/v1/jobs/{id}/cancel:當 backend 已拿到 job_id 但 streaming 失敗時,主動對 converter 發 cancel 避免孤立 job - §9 retry 表新增
cancelrow(best-effort、不重試)
重要區分:「使用者主動取消 UI」(PM Non-Goals N2,Phase 1+ 才做)vs 「backend 內部 best-effort cancel cleanup」(TDD 此次補)— 兩者不衝突,後者是韌性 infra。
3.4 議題 #6 — Upload XHR 進度語意
修訂:conversion.md §4.3.1(新增完整章節)
設計選擇表(選項 A vs B),明確採選項 A:backend 等 converter 201 才回 200,不 early-return。理由:
- 進度 100% 接近端到端真實狀態
- 實作簡單(同步等)
- 失敗處理路徑清楚(同步錯誤直接回)
- 1-3 秒 io.Pipe drain 延遲對 500MB 上傳可接受
Frontend UX 補償:100% 後到 backend 回 200 之間,文案切「即將完成…」/「伺服器處理中…」(已在 flow-conversion.md §5.3 提到)。已要求 Design 在 wireframe §4.2 對齊文案表(§2.1.4)。
3.5 議題 #7 — expires_at 來源
修訂:conversion.md §2.6.2(新增)+ api/api-conversion.md §1 / §2 / §5(response shape 補欄位)
決策:
- 優先從 converter response 直接讀(converter Phase 1 是否提供 — 給 Backend Agent 確認)
- 若 converter 沒給,backend 自行
created_at + 7d推算 - Frontend 永遠拿到
expires_at,無論來源
Job response shape 統一補欄位(v0.3):
expires_at:必有source_filename:必有(給 success card 顯示「yolov5s.onnx → yolov5s_kl720.nef」)target_chip:必有(給 wireframe §6 / §7 顯示「→ KL720」)
3.6 同步影響的小修訂
conversion.md§3 endpoint 表加註「不對外暴露但內部使用的 converter endpoint」(cancel + lazy rebuild)conversion.md§9 retry 表新增 cancel / lazy rebuild 兩 rowapi/api-conversion.md§3 promote-to-models request body 對齊 Design 單欄位(議題 #4)
4. 給 Orchestrator 的決策清單
三方修訂大部分各自進行,以下是需要 Orchestrator 協調或使用者裁決的事項。
4.1 [使用者裁決] API endpoint 路徑命名統一
問題:PM PRD 用 /api/converter/jobs/*、Design wireframe / flow 用 /api/converter/jobs/*、Architect TDD 用 /api/conversion/*,三方不一致。
選項:
-
選項 A(Architect 建議):統一用
/api/conversion/*、promote-to-models、GET /download302- 優點:對齊 visionA 內部模組名(
internal/conversion/);ADR-014 v1.1 download 安全升級已採;命名語意清楚 - 改動:PM PRD §F6 / F7、Design wireframe / flow(多處)
- 優點:對齊 visionA 內部模組名(
-
選項 B:統一用
/api/converter/jobs/*- 優點:與 converter 真實 path(
/api/v1/jobs/*)名字相近、有「轉發」直覺 - 缺點:誤導使用者以為是 raw proxy(其實 backend 有 ownership / 半自動邏輯);download flow 已決議用 GET 302,不能維持
POST /download-token
- 優點:與 converter 真實 path(
Architect 強烈建議選 A。
決策後:
- 選 A → PM 改 PRD §F6/F7、Design 改 wireframe / flow(標記位置已在 §1.2 / §2.1.2 / §2.2.2 列出);TDD 不動
- 選 B → Architect 改 TDD 全部(
internal/conversion/package 名也要改)— 不建議
4.2 [PM 待補] 修訂建議清單(嚴重度)
| # | 嚴重度 | 修訂位置 | 內容 |
|---|---|---|---|
| P1 | 嚴重 | §F6 / §F7 | 對齊 endpoint 命名(見 §4.1) |
| P2 | 中 | §F 段(新增 F0) | 補「Active job pre-check」功能 |
| P3 | 中 | §F2 / §F3 | 補上傳進度 100% 後的文案語意說明 |
| P4 | 中 | §F6 | 補「加到模型庫」Dialog 含名稱欄位(對齊 Design) |
| P5 | 中 | §6 + §7 | 補 D7(重啟 lazy rebuild)+ converter dependency 補 2 個內部用 endpoint |
| P6 | 小 | §8 KPI | 量測點改為 backend log job 完成時間 |
| P7 | 小 | §F2 | 確認 chip 數量(4 個 vs 2 個),與 converter 對齊 |
4.3 [Design 待補] 修訂建議清單(嚴重度)
| # | 嚴重度 | 修訂位置 | 內容 |
|---|---|---|---|
| D1 | 嚴重 | wireframe §3.3 / §6.3 / §7.1 / §7.2、flow §3 / §5.5 / §8.2 | 對齊 endpoint 命名(見 §4.1) |
| D2 | 中 | wireframe §6.1 | stage indicator 改用 converter stage 欄位(onnx/bie/nef → 解析/量化/編譯) |
| D3 | 中 | wireframe §4.2、flow §5.3 | 補 100% 後等待文案表 + i18n key |
| D4 | 中 | flow §5.3 / §8.2 | 補「使用者取消」vs「backend 內部 cancel cleanup」的區分 |
| D5 | 小 | wireframe §10 | Wand2 icon 採用(不需改) |
4.4 [需與其他團隊確認]
- Backend Agent:確認 converter Phase 1 的
GET /api/v1/jobs/{id}response 是否含expires_at,決定 backend 是直接透傳還是自行推算 - DevOps:確認 visionA stage → 192.168.0.130 converter 網路可達性(ADR-014 合規清單仍未勾)+ MC service client 4 scope 已授權
- Converter 團隊:確認 Phase 1
platform欄位實際支援哪幾個 chip enum(520 / 720或520 / 630 / 720 / 730)
5. 結論
已落地(Architect 端):4 個議題(#2 / #5 / #6 / #7)已寫進 conversion.md v0.3 + api/api-conversion.md v0.3。
待 Orchestrator 協調:
- 1 個使用者裁決:API endpoint 命名統一(§4.1)
- 7 個 PM 修訂:1 嚴重 + 4 中 + 2 小
- 5 個 Design 修訂:1 嚴重 + 3 中 + 1 小
- 3 個跨團隊確認
建議下一步:
- Orchestrator 把 §4.1 提給使用者裁決(這是阻擋三方對齊的單一最大議題)
- 使用者決定後,PM / Design 同步修訂(兩邊都在改 endpoint,可平行進行)
- PM / Design 第二輪產出後,Architect 再做最終 review(確認沒新衝突)
- 完成後進 Phase 0.8 實作階段
版本記錄
| 日期 | 版本 | 變更 |
|---|---|---|
| 2026-04-30 | 1.0 | 初版 — Phase 0.8 三方交叉審閱(Architect 視角) |