visionA/docs/autoflow/02-prd/features/feature-model-sharing.md
jim800121chen f6d15b7b14 docs(arch): B 設備管理 + C 模型共享 + camera ADR-020 規劃文件
- feature-device-mgmt-tdd.md + api-device-mgmt.md(B 設備管理 TDD)
- feature-model-sharing-tdd.md + api-model-sharing.md + PRD feature + 設計規格(C 模型共享三方規劃)
- adr-020-ffmpeg-camera-indev.md(camera 三平台 indev)
- PRD.md / TDD.md 索引增補

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-08-02 16:31:38 +08:00

228 lines
16 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Feature模型共享Model Sharing— L 級新功能
> 父文件:[PRD.md](../PRD.md) | 相依既有功能:[模型管理](feature-model-management.md)、[會員系統](feature-auth.md)
> 對應 User StoriesUS-31 ~ US-40本檔新增接續 user-stories.md 既有 US-01~US-30
> 狀態三方聯合討論中PM 產出草稿,待 Design / Architect 互審)
> 撰寫日期2026-08-02
---
## 0. 這份 PRD 的定位(先講清楚,避免誤解範圍)
**模型共享不是從零打造的功能,而是在既有「模型管理」功能上,疊加一個「可見性 / 權限」維度。**
反推自既有 code 的現況(重要,這是設計基礎):
| 面向 | 現況(已實作) | 本功能要加什麼 |
|------|---------------|---------------|
| 模型資料模型 | `Model``OwnerUserID``Source`(preset/uploaded/converted)、軟刪。**無 visibility 欄位** | 新增「可見性 / 公開對象」維度 |
| 存取控制 | 嚴格 owner-only`List` 只 filter `OwnerUserID``Get`/`download` 非 owner 回 403+ 系統 preset 公用 | 讓「非 owner 但被授權者」也能看到 / 下載 |
| 模型庫 UI`/models`| 按**來源**分三區preset / converted / uploaded只看自己的 | 新增「共享給我 / 我可見」的維度分頁、排序、搜尋、filter |
| 使用者 / 權限 | OIDCMember Center`sub`=userIDusers 表有 `org_id`(nullable, 未用)、`roles TEXT[]`(未用) | 「公開對象」要對齊這些既有欄位(同租戶 / 群組概念) |
| 下載 | handler 註解已寫明「第一階段 owner-only**B 分享後續階段**)」 | 本功能正是被預留的「B 分享階段」 |
**一句話**:既有系統已經為「分享」預留了骨架(`org_id``roles`、download handler 的註解),本功能把這個骨架填血。
---
## 1. 功能概述與價值主張
**使用者痛點**(反推自 Persona見 user-research.md
- **阿哲FAE**:轉檔 / 調校好一個客戶專用模型後,想給同組 FAE 或客戶直接用,現在只能「下載 → 私訊傳檔 → 對方重新上傳」,模型檔散落、版本混亂。
- **SarahSI**:在多個客戶現場佈署,想把一套驗證過的模型推給整個團隊 workspace現在每個工程師都要自己上傳一份。
- **Mike開發者**:想引用別人分享的公開模型做 A/B test 基準,現在沒有「探索別人模型」的入口。
**核心價值主張**:「**上傳一次,授權共享,團隊即用**」——把模型從「我的私有檔案」升級為「可依身份權限流通的資產」。
**北極星指標關聯**:模型共享降低「取得可用模型」的摩擦 → 提升首次推論成功率與每週推論次數WAD / 每週推論次數 per user見 success-metrics.md
---
## 2. 公開對象(可見性)權限模型 — PM 提案
> ⚠️ **本節是全功能的核心設計決策,需 Architect 確認技術可行性、Design 確認 UI 複雜度。**
### 2.1 設計原則
1. **對齊既有 auth 概念**,不自造平行權限系統。既有已有:`OwnerUserID`(擁有者)、`org_id`(租戶 / 組織nullable`roles TEXT[]`
2. **preset 模型維持不變**:系統 7 預設模型永遠對所有人公開,不納入本功能的可見性控制。
3. **owner 永遠有完整權限**:可設定 / 變更公開對象、可撤銷、可刪除。
4. **漸進式**Phase A 先做最有價值、技術最單純的層級;複雜的群組 / 租戶留 Phase B。
### 2.2 提案可見性層級Visibility Levels
`Model` 上新增 `Visibility` 欄位,四個層級由私到公:
| 層級 | 值(提案) | 誰能看到 / 下載 | 對齊既有概念 | 建議 Phase |
|------|-----------|----------------|-------------|-----------|
| **私有** | `private` | 只有 owner= 現況預設行為) | `OwnerUserID` | **P0預設值** |
| **指定使用者** | `restricted` | owner + 被明確授權的 user 清單 | 新增 share grant 關聯 | **P0** |
| **同租戶 / 組織** | `organization` | owner + 同 `org_id` 的所有 user | 既有 `users.org_id` | **P1**(依賴租戶功能成熟度) |
| **全公開** | `public` | 所有已登入 user | — | **P1** |
**P0MVP先做 `private` + `restricted` 兩級**,理由:
- `private` 是現況行為,成本近乎 0只是把隱含的「無 visibility = 私有」顯性化)。
- `restricted`(指定 user 分享)是**痛點最直接的解**(阿哲要給特定同事 / 客戶),且不依賴「租戶 / 群組」這種尚未成熟的概念。
- `organization` / `public` 依賴 `org_id` 租戶模型與內容治理(濫用、審核),成本與風險高,留 P1。
> **待 Architect 確認 A**`restricted` 的授權清單,建議新增一張 `model_shares` 關聯表(`model_id` × `grantee_user_id` × `permission` × `granted_by` × `created_at`)。這是否與現有 DB migration 策略相容?(既有 migration 到 0005models 表 index 全 owner-scoped共享查詢需要新 index / 新表。)
>
> **待 Architect 確認 B**`organization` 層級依賴 `users.org_id`但該欄位目前是「nullable + 未寫入」的 stub。若 P1 要做,需先有「租戶 / org 指派」機制。此依賴請 Architect 評估。
>
> **待 Design 確認 C**:四層級的 UI 呈現。P0 兩級相對單純(一個下拉 + 指定 user 的 email/名稱輸入);但「指定 user 清單」的 UX怎麼搜尋 user、怎麼移除、怎麼顯示已授權清單需要 Design 設計。
### 2.3 權限粒度permission
P0 先做**唯讀分享**(被授權者可**檢視 + 下載 + 用於推論**,但不能改 / 刪 / 二次分享)。
| 權限 | P0 | 說明 |
|------|-----|------|
| view看得到、看 profile | ✅ | 出現在對方的「共享給我」列表 |
| download下載 .nef | ✅ | 對齊 download handler 的「B 分享階段」 |
| use載入裝置推論 | ✅ | 分享的核心價值:對方能直接用 |
| edit / re-share / delete | ❌P1+ | 只有 owner 能做 |
> **待 Architect 確認 D**`use`(載入裝置推論)牽涉 `load-to-device` 與 download token 簽發。現在 download handler 對非 owner 回 403`restricted` 要放行「被授權者」——授權檢查要插在哪一層middleware / handler / repo filter
---
## 3. User Stories接續既有 US 編號)
> 格式對齊 user-stories.md。RICE 的 Effort 欄標「待 Architect 核對」,本檔先給 PM 相對估值。
### 3.1 模型公開設定owner 視角)
- **US-31P0**:作為模型擁有者,我要**在模型 profile 頁設定它的公開對象(私有 / 指定使用者)**,這樣我就能控制誰能用我的模型。
- **US-32P0**:作為模型擁有者,我要**把模型分享給指定的一位或多位使用者(用 email 或名稱搜尋)**,這樣特定同事 / 客戶就能直接使用。
- **US-33P0**:作為模型擁有者,我要**看到目前這個模型已分享給哪些人,並能移除某個人的存取權**,這樣我能隨時收回授權。
- **US-34P1**:作為模型擁有者,我要**把模型設為「同組織可見」或「全公開」**,這樣整個團隊 / 社群不用我逐一授權。
### 3.2 共享模型庫(被分享者 / 探索者視角)
- **US-35P0**:作為使用者,我要**在模型庫看到「共享給我」的模型(別人授權給我的)**,並清楚看到它是誰分享的、我的權限是什麼。
- **US-36P0**:作為使用者,我要**能對共享模型庫做分頁瀏覽**,這樣模型多時不會一次載入全部、頁面不卡。
- **US-37P0**:作為使用者,我要**對共享模型庫做排序(上傳時間 / 名稱 / 檔案大小)**,這樣我能快速找到最新或最相關的模型。
- **US-38P0**:作為使用者,我要**對共享模型庫做 filter依硬體晶片 / 來源 / 可見性 / 分享者)**,這樣我能縮小範圍。
- **US-39P0**:作為使用者,我要**用關鍵字搜尋模型(名稱 / 描述)**,這樣我能直接找到目標模型。
- **US-40P0**:作為使用者,我要**進入任一可見模型的 profile 頁看到完整資訊metadata、支援硬體、擁有者、分享者、我的權限、下載 / 載入按鈕)**,這樣我在使用前能確認它是我要的。
### 3.3 依身份權限的可見性(貫穿所有 story 的規則)
**共享模型庫「我能看到的模型」= 聯集**
```
我擁有的owner
明確分享給我的restricted grantUS-32
我所屬 org 的 organization 模型P1US-34
全公開模型P1US-34
系統 preset既有永遠可見
```
> **待 Architect 確認 E**:這個「聯集查詢」在現有 `Repository.List(ListFilter)` 介面下無法表達(現在只支援 owner filter。需擴充 `ListFilter`(加 grantee / visibility / org 維度)或新增 method。請評估對現有 in-memory + postgres 兩個實作的衝擊。
---
## 4. RICE 排序 / 優先級
| # | Story | Reach | Impact | Conf. | Effort待 Architect 核對) | RICE | Phase |
|---|-------|-------|--------|-------|------|------|-------|
| US-32 | 分享給指定使用者 | 70 | 3 | 80% | 2 | 84 | **P0** |
| US-35 | 「共享給我」列表 | 70 | 3 | 80% | 1.5 | 112 | **P0** |
| US-31 | 公開設定(私有/指定) | 70 | 2 | 80% | 1 | 112 | **P0** |
| US-40 | 模型 profile 頁 | 80 | 2 | 90% | 1.5 | 96 | **P0** |
| US-39 | 關鍵字搜尋 | 80 | 1 | 90% | 1 | 72 | **P0** |
| US-33 | 檢視 / 撤銷授權清單 | 60 | 2 | 80% | 1 | 96 | **P0** |
| US-38 | filter晶片/來源/可見性/分享者)| 80 | 1 | 80% | 1 | 64 | **P0** |
| US-37 | 排序 | 80 | 1 | 90% | 0.5 | 144 | **P0** |
| US-36 | 分頁 | 80 | 1 | 90% | 0.8 | 90 | **P0** |
| US-34 | org 可見 / 全公開 | 50 | 2 | 60% | 3 | 20 | **P1** |
> RICE 說明沿用 user-stories.md §5.1Reach 為 Phase 相對估值、Impact 對北極星 WAD。Effort 全部標「待 Architect 核對」——尤其 US-32 / US-35 的授權表 + 聯集查詢是技術重點。
### P0 / P1 切分總結
**P0MVP本次做**
- 可見性兩級:`private`(預設)+ `restricted`(指定 user 分享)
- 公開設定 UI在 profile 頁)+ 授權清單管理(新增 / 移除)
- 共享模型庫:「共享給我」維度 + 分頁 + 排序 + filter + 搜尋
- 模型 profile 頁(擴充既有 `/models/[id]`,加分享資訊與權限顯示)
**P1後續**
- `organization`(同租戶可見)— 依賴租戶 / org 指派機制成熟
- `public`(全公開)— 需內容治理(濫用回報、審核)
- 二次分享、edit 權限、分享通知email / in-app
---
## 5. 與既有模型功能的關係(擴充 vs 全新)
| 元件 / 檔案 | 現況 | 本功能 | 類型 |
|------------|------|--------|------|
| `Model` domainmodel.go | 無 visibility | 加 `Visibility` 欄位 + 可能的 share 關聯 | **擴充** |
| `models`migration 0001 | owner-scoped index | 新 migration加 visibility 欄 + `model_shares` 表 + 新 index | **擴充 + 新表** |
| `Repository.List(ListFilter)` | 只 owner filter | 擴充 filtergrantee / visibility或新 method | **擴充** |
| `GET /api/models`models.go | preset + 自己的 | 加「共享給我」聯集 + 分頁 / 排序 / 搜尋 query params | **擴充** |
| `GET /api/models/:id``download` | 非 owner 403 | 放行被授權者 | **擴充** |
| 新 API設定可見性 / 管理授權 | — | `PUT /api/models/:id/visibility``POST/DELETE /api/models/:id/shares` | **全新** |
| `/models`page.tsx | 按 source 三區 | 加「共享給我」維度 + 分頁 / 排序 / 搜尋列 | **擴充** |
| `ModelFilters`model-filters.tsx | 只 targetChip | 加來源 / 可見性 / 分享者 filter + 搜尋框 | **擴充** |
| `/models/[id]` profile 頁 | 基本資訊 + 下載 / 刪除 | 加:公開設定區、授權清單管理、分享者 / 我的權限顯示 | **擴充** |
| 「公開設定」互動 | — | 新 UI可見性下拉 + user 搜尋授權) | **全新Design 重點)** |
**關鍵**:搜尋 / 排序 / 分頁在既有 code 是被標為「Phase 1 TODO」的見 model-filters.tsx 註解、feature-model-management.md TODO-3。本功能把它們正式做出來且**同時服務「我的模型」與「共享模型」兩個維度**——不是只給共享用。
---
## 6. 成功指標
| 類別 | 指標 | Baseline | P0 目標 | 追蹤方式 |
|------|------|----------|---------|---------|
| 採用 | 建立過至少一次分享的 owner 比例 | N/A新功能baseline=0 | 內測 FAE 中 ≥ 40% | 埋點:`model_share_created`(待 Architect 確認埋點清單) |
| 採用 | 「共享給我」列表被點開的 WAU 比例 | N/A | ≥ 30% | 埋點:`shared_library_viewed` |
| 價值 | 用「別人分享的模型」跑過推論的 user 比例 | N/A | ≥ 25% | 埋點:`inference_with_shared_model` |
| 效率 | 共享模型庫首屏載入時間(含分頁) | N/A | P95 < 1.5s | 前端 perf Architect / 非功能需求對齊 nonfunctional.md |
| 效率 | 搜尋 找到目標模型的操作步數 | 現況需私訊傳檔不可量測 | 3 搜尋 / filter profile 使用 | 可用性測試 |
| 護欄 | 未授權存取被正確拒絕率 | 現況 owner-only 403 | 100%不可退化 | 安全測試 Security / Architect |
| 護欄 | 既有我的模型列表載入時間不退化 | 現況 P95 | 不劣於現況 | 回歸 perf 測試 |
> Baseline 多為 N/A全新功能、無歷史數據。目標值為內測 FAE 群體的估算門檻launch 後 2 週校正。護欄指標「未授權存取拒絕率」是**本功能最重要的把關**——分享功能最大的風險是權限漏洞導致模型外洩。
---
## 7. 待三方確認事項彙總(互審重點)
### 給 Architect技術可行性
| # | 事項 | 位置 |
|---|------|------|
| A | `model_shares` 授權關聯表設計是否相容既有 migration 策略0001~0005 owner-scoped index | §2.2 |
| B | `organization` 層級依賴 `users.org_id`現為未寫入 stubP1 前需先有租戶指派機制 | §2.2 |
| C | `use`被授權者載入裝置推論 download token 簽發 + 授權檢查插入層級middleware / handler / repo | §2.3 |
| D | `Repository.List` 聯集查詢owner granted org public in-memory + postgres 兩實作的衝擊 | §3.3 |
| E | 分頁 / 排序 / 搜尋在 List 介面的表達offset/cursor 分頁搜尋用 LIKE 還是全文索引 | §3.2 |
| F | RICE Effort 欄核對尤其 US-32 / US-35 | §4 |
| G | 成功指標的埋點事件清單可行性 | §6 |
### 給 Design體驗面
| # | 事項 | 位置 |
|---|------|------|
| C | 指定 user 分享 UX怎麼搜尋 user加入 / 移除已授權清單呈現 | §2.2 |
| | 可見性層級的 UI下拉分段控制如何讓 owner 一眼看懂私有 vs 指定 vs 公開的差異與風險 | §2.2 |
| | 共享模型庫的資訊架構:「我的模型共享給我怎麼並存分頁 tab分區既有已按 source 分三區再加維度會不會過載 | §3.2 / §5 |
| | profile 頁如何同時呈現我是 owner可管理)」vs我是被授權者唯讀)」兩種狀態 | US-40 |
| | 分頁 / 排序 / 搜尋 / filter 控制列的整合設計既有 filter 只有 targetChip 一個下拉要擴成完整工具列 | §3.2 |
### 給雙方(需一起拍板)
- **P0 是否確認只做 `private` + `restricted` 兩級**PM 主張是理由見 §2.2 Design / Architect 認為 org 層級成本可控且需求急可討論上調。)
- **可見性預設值 = `private`**(不主動公開任何東西,安全優先)——三方確認無異議。
---
## 8. 連結
- [PRD 索引](../PRD.md)
- 相依[模型管理](feature-model-management.md)[會員系統](feature-auth.md)[介面契約](../interface-contracts.md)
- 待更新user-stories.mdUS-31~US-40 併入主表)、success-metrics.md分享指標