- 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>
228 lines
16 KiB
Markdown
228 lines
16 KiB
Markdown
# Feature:模型共享(Model Sharing)— L 級新功能
|
||
|
||
> 父文件:[PRD.md](../PRD.md) | 相依既有功能:[模型管理](feature-model-management.md)、[會員系統](feature-auth.md)
|
||
> 對應 User Stories:US-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 |
|
||
| 使用者 / 權限 | OIDC(Member Center)`sub`=userID;users 表有 `org_id`(nullable, 未用)、`roles TEXT[]`(未用) | 「公開對象」要對齊這些既有欄位(同租戶 / 群組概念) |
|
||
| 下載 | handler 註解已寫明「第一階段 owner-only(**B 分享後續階段**)」 | 本功能正是被預留的「B 分享階段」 |
|
||
|
||
**一句話**:既有系統已經為「分享」預留了骨架(`org_id`、`roles`、download handler 的註解),本功能把這個骨架填血。
|
||
|
||
---
|
||
|
||
## 1. 功能概述與價值主張
|
||
|
||
**使用者痛點**(反推自 Persona,見 user-research.md):
|
||
|
||
- **阿哲(FAE)**:轉檔 / 調校好一個客戶專用模型後,想給同組 FAE 或客戶直接用,現在只能「下載 → 私訊傳檔 → 對方重新上傳」,模型檔散落、版本混亂。
|
||
- **Sarah(SI)**:在多個客戶現場佈署,想把一套驗證過的模型推給整個團隊 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** |
|
||
|
||
**P0(MVP)先做 `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 到 0005,models 表 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-31(P0)**:作為模型擁有者,我要**在模型 profile 頁設定它的公開對象(私有 / 指定使用者)**,這樣我就能控制誰能用我的模型。
|
||
- **US-32(P0)**:作為模型擁有者,我要**把模型分享給指定的一位或多位使用者(用 email 或名稱搜尋)**,這樣特定同事 / 客戶就能直接使用。
|
||
- **US-33(P0)**:作為模型擁有者,我要**看到目前這個模型已分享給哪些人,並能移除某個人的存取權**,這樣我能隨時收回授權。
|
||
- **US-34(P1)**:作為模型擁有者,我要**把模型設為「同組織可見」或「全公開」**,這樣整個團隊 / 社群不用我逐一授權。
|
||
|
||
### 3.2 共享模型庫(被分享者 / 探索者視角)
|
||
|
||
- **US-35(P0)**:作為使用者,我要**在模型庫看到「共享給我」的模型(別人授權給我的)**,並清楚看到它是誰分享的、我的權限是什麼。
|
||
- **US-36(P0)**:作為使用者,我要**能對共享模型庫做分頁瀏覽**,這樣模型多時不會一次載入全部、頁面不卡。
|
||
- **US-37(P0)**:作為使用者,我要**對共享模型庫做排序(上傳時間 / 名稱 / 檔案大小)**,這樣我能快速找到最新或最相關的模型。
|
||
- **US-38(P0)**:作為使用者,我要**對共享模型庫做 filter(依硬體晶片 / 來源 / 可見性 / 分享者)**,這樣我能縮小範圍。
|
||
- **US-39(P0)**:作為使用者,我要**用關鍵字搜尋模型(名稱 / 描述)**,這樣我能直接找到目標模型。
|
||
- **US-40(P0)**:作為使用者,我要**進入任一可見模型的 profile 頁,看到完整資訊(metadata、支援硬體、擁有者、分享者、我的權限、下載 / 載入按鈕)**,這樣我在使用前能確認它是我要的。
|
||
|
||
### 3.3 依身份權限的可見性(貫穿所有 story 的規則)
|
||
|
||
**共享模型庫「我能看到的模型」= 聯集**:
|
||
```
|
||
我擁有的(owner)
|
||
∪ 明確分享給我的(restricted grant,US-32)
|
||
∪ 我所屬 org 的 organization 模型(P1,US-34)
|
||
∪ 全公開模型(P1,US-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.1(Reach 為 Phase 相對估值、Impact 對北極星 WAD)。Effort 全部標「待 Architect 核對」——尤其 US-32 / US-35 的授權表 + 聯集查詢是技術重點。
|
||
|
||
### P0 / P1 切分總結
|
||
|
||
**P0(MVP,本次做)**:
|
||
- 可見性兩級:`private`(預設)+ `restricted`(指定 user 分享)
|
||
- 公開設定 UI(在 profile 頁)+ 授權清單管理(新增 / 移除)
|
||
- 共享模型庫:「共享給我」維度 + 分頁 + 排序 + filter + 搜尋
|
||
- 模型 profile 頁(擴充既有 `/models/[id]`,加分享資訊與權限顯示)
|
||
|
||
**P1(後續)**:
|
||
- `organization`(同租戶可見)— 依賴租戶 / org 指派機制成熟
|
||
- `public`(全公開)— 需內容治理(濫用回報、審核)
|
||
- 二次分享、edit 權限、分享通知(email / in-app)
|
||
|
||
---
|
||
|
||
## 5. 與既有模型功能的關係(擴充 vs 全新)
|
||
|
||
| 元件 / 檔案 | 現況 | 本功能 | 類型 |
|
||
|------------|------|--------|------|
|
||
| `Model` domain(model.go) | 無 visibility | 加 `Visibility` 欄位 + 可能的 share 關聯 | **擴充** |
|
||
| `models` 表(migration 0001) | owner-scoped index | 新 migration:加 visibility 欄 + `model_shares` 表 + 新 index | **擴充 + 新表** |
|
||
| `Repository.List(ListFilter)` | 只 owner filter | 擴充 filter(grantee / 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`(現為未寫入 stub),P1 前需先有租戶指派機制 | §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.md(US-31~US-40 併入主表)、success-metrics.md(分享指標)
|