visionA/docs/autoflow/03-design/feature-model-sharing-design.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

33 KiB
Raw Permalink Blame History

模型共享 設計規格 — visionA Cloud

L 級新功能「模型共享」的 Design 部分三方聯合規劃PM 寫 PRD / Architect 寫 TDD / Design 寫本檔)。

核心定位:本功能是擴充既有模型庫 UI不是全新模組。100% 沿用既有 Design Tokensdesign-tokens.md)、既有元件(components.md)、既有 /models 三區版型與 ModelCard / ModelGrid / ModelSection / ModelFilters / ModelDetailClient。本檔只定義「共享」這個維度帶來的新視覺 / 互動增量。

不新增 Design Token。狀態色沿用既有 chart-* token 與 §2.1 半語義約定。

對應頁面:/models(列表擴充)+ /models/[id](詳情頁擴充成 owner / 公開兩態)+ 新增「共享對象設定」互動Dialog+ 新增「共享模型庫」瀏覽維度。

配套格式參考:pages.md §8、flows/flow-model-upload.mdcomponents.md


0. 名詞與待確認前提(先給 PM / Architect

本設計基於以下假設,凡標 🔶 者為「需 PM 確認需求細節」、標 🔷 者為「需 Architect 確認技術可行性」。設計會標出因假設不同而分歧的 UI 分支。

# 名詞 / 假設 說明 標記
A1 公開對象visibility三態 假設分 private(僅自己)/ public(所有登入使用者可見)/ shared(指定對象)三種 🔶 PM是否只做 private/public 兩態「指定對象」Phase 0 是否需要?
A2 「指定對象」的粒度 假設可指定「個別使用者by email」。是否還有「群組 / 組織 / 團隊」概念? 🔶 PM + 🔷 Architect有無 org/team 資料模型?
A3 可見模型的三分類 列表要區分「我的owner/ 公開public/ 共享給我的shared-with-me 🔶 PM分類命名與是否需要「我公開出去的」獨立檢視
A4 共享 = 唯讀 假設別人共享 / 公開給我的模型我只能檢視 + 下載 + 燒錄,不能改名 / 刪除 / 再共享 🔶 PM可否「再共享」re-share可否下載
A5 profile 頁 = 擴充既有 detail 假設「模型 profile 頁」就是擴充現有 /models/[id],依 viewer 身份切 owner 版 / 公開版,不另建路由 🔷 Architect是否需要獨立 public 路由(如 /m/[shareId] 供分享連結)?
A6 分頁pagination 共享模型庫可能量大需分頁。假設用 offset/limit 或 cursor 🔷 Architect後端分頁機制offset vs cursor決定 UI頁碼 vs 無限捲動 / 載入更多)
A7 搜尋範圍 假設搜尋 = 對「當前可見的所有模型」搜名稱(+ 選填分類 / 晶片) 🔶 PM搜尋要不要跨到「公開但未共享給我」的全庫探索
A8 公開對象變更權限 假設只有 owner 能改自己模型的公開設定 🔷 Architect權限在 API 層把關(前端只是 UI 便利)

設計原則:以上假設我採「最完整但可降級」的畫法——先畫三態 visibility + 三分類列表PM 若砍到兩態 / 兩分類UI 直接移除對應分支即可,不需重畫。


1. User StoryDesign 視角)

作為 一個 Kneron 開發者, 我想要 把我的模型公開或共享給特定同事,並瀏覽別人共享給我的模型, 這樣 團隊就能共用模型,不用每個人重複上傳 / 轉檔。

體驗成功條件:

  • 使用者一眼能分辨列表中哪些是「我的 / 公開 / 共享給我的」(不只靠顏色,用 badge 文字 + 圖示雙編碼)
  • 設定公開對象在 2 次點擊內可達(卡片選單 or 詳情頁按鈕 → Dialog
  • 共享模型庫量大時,瀏覽 / 搜尋 / 篩選 / 排序不卡頓、狀態清楚(載入 / 空 / 無結果 / 無權限四態齊備)
  • 公開版 profile 頁不洩漏 owner 的私有操作(刪除 / 改公開設定按鈕對非 owner 隱藏)

2. 範圍與 Phase 0 降級

項目 Phase 0本次 Phase 1+
Visibility 態 private / public / shared🔶 待 PM 砍) + 到期共享 / 密碼保護連結
指定對象粒度 個別使用者 by email🔶 + 群組 / 組織
列表分類 我的 / 公開 / 共享給我的 三分類(🔶 + 我公開出去的獨立檢視
分頁 「載入更多」按鈕 or 頁碼(依 🔷 A6 無限捲動 + 虛擬列表
排序 名稱 / 建立時間 / 共享時間3 選項) + 熱門度 / 下載數
篩選 既有 targetChip + 新增「共享狀態」維度 + 分類 / 標籤 / owner
搜尋 名稱模糊搜(前端 or 後端依 🔷 A6 全文 + tag
profile 公開版 owner 版 / 公開版兩態 分享連結 /m/[shareId]
再共享 / 轉讓 不做(🔶 A4 視需求

3. 資訊架構變更IA

沿用既有 /models/models/[id],不新增頂層導航。共享是「模型」的一個屬性維度,落在既有模型庫內。

/models  (模型庫 — 擴充:新增「共享」瀏覽維度)
│
├── 檢視模式切換(新增):
│     ┌─ 依來源分區既有preset / converted / uploaded  ← 預設,僅「我的」模型
│     └─ 依共享關係分區(新增):我的 / 公開 / 共享給我的
│
├── 搜尋框(新增,跨當前檢視)
├── 篩選(擴充 ModelFilterstargetChip + 共享狀態)
├── 排序(新增:名稱 / 建立時間 / 共享時間)
├── 分頁 / 載入更多(新增)
│
└── /models/[id]  (模型 profile 頁 — 擴充成雙態)
      ├── owner 版:既有全操作(改名 / 刪除 / 下載 / 燒錄 / 【新增】公開設定)
      └── 公開 / 共享版:唯讀(檢視 / 下載 / 燒錄),隱藏 owner-only 操作
            + 新增「擁有者」資訊列(誰共享的 / 共享時間 / 公開對象徽章)

🔶 待 PM 確認:兩種檢視模式(來源分區 vs 共享關係分區)是否都要?還是共享關係分區直接取代來源分區?我建議保留切換Tab 或 Segmented Control因為「來源分區」對管理自己的模型仍有用「共享關係分區」才是本功能重點。


4. 共享模型庫列表設計

4.1 檢視模式切換(新增元件 ModelViewToggle

/models 頁標題列下、ModelFilters 上方,新增一個 Segmented Control用既有 Tabs 元件實作,variant 沿用):

┌─────────────────────────────────────────────────────────────┐
│  模型庫                                          [上傳模型]    │
│  管理、公開與共享你的 Kneron 模型                              │
├─────────────────────────────────────────────────────────────┤
│  ┌──────────────┬──────────────┐                             │
│  │ 依來源  ●    │  依共享關係   │   ← Tabs既有元件        │
│  └──────────────┴──────────────┘                             │
├─────────────────────────────────────────────────────────────┤
│  🔍 [搜尋模型名稱...........]   [晶片 ▾] [共享狀態 ▾] [排序 ▾]│  ← 篩選列(擴充)
├─────────────────────────────────────────────────────────────┤
│  (分區內容依所選檢視模式渲染)                                │
└─────────────────────────────────────────────────────────────┘
  • 依來源既有預設不變preset / converted / uploaded 三區,僅顯示「我的」模型。
  • 依共享關係(新增):三區 —
    • 🟢 我的ownerchart-1 色點呼應
    • 🔵 公開public含我公開的 + 別人公開的,🔶 A7 待確認範圍):chart-2
    • 🟣 共享給我的shared-with-mechart-3

沿用既有 ModelSection 的「色點 + 標題 + 計數」樣式,只是換分組維度。SOURCE_DOT_CLASS 邏輯延伸出一份 SHARE_DOT_CLASS,色 token 一致。

4.2 卡片上的共享標示(擴充 ModelCard

既有 ModelCard 已有 status badge + targetChip badge + source badge。新增一個 visibility badge,放在 badge 列,用圖示 + 文字雙編碼(不僅靠顏色,滿足無障礙 De1

Visibility 圖示Lucide 文字 配色(沿用 token tint 風格) 顯示條件
private Lock 私有 text-muted-foreground + border-border(中性) owner 檢視自己模型時
public Globe 公開 border-chart-2/30 bg-chart-2/10 text-chart-2 任何人
shared Users 已共享 / 共享給我 border-chart-3/30 bg-chart-3/10 text-chart-3 owner 看到「已共享給 N 人」receiver 看到「{owner} 共享」

owner 額外資訊private/shared/public 卡片右上角owner 檢視時可在 badge 顯示對象數,如「公開」「共享 · 3 人」。

receiver 視角:卡片新增一行次要資訊text-xs text-muted-foreground):「由 {ownerEmail} 共享 · {relativeTime}」。沿用 RemoteDeviceBadge 的相對時間格式化 util剛剛 / X 分鐘前 / 絕對時間)。

卡片操作差異

  • owner 卡片:既有下載按鈕(若 downloadable+ 新增卡片右上角 選單Dropdown內含「公開設定」「刪除」等見 §5 觸發點)。
  • receiver 卡片:只保留「下載」(若 A4 允許)+ 點擊進 profile 頁。無 選單(無 owner 權限)。

🔷 Architect 確認ModelSummary 需新增欄位 visibility: 'private' | 'public' | 'shared'ownerEmail?sharedAt?sharedCount?owner 視角)、isOwner: boolean。前端 UI 依這些欄位渲染,實際權限由 API 把關。

4.3 篩選擴充(擴充 ModelFilters

既有 ModelFilters 只有 targetChip。新增「共享狀態」維度第二個 Select),僅在「依共享關係」檢視模式下顯示:

export interface ModelFilterValue {
  targetChip: TargetChip | "all";
  visibility?: "all" | "private" | "public" | "shared"; // 新增,僅共享關係檢視用
}
  • targetChip 篩選跨所有分區作用(沿用既有行為)。
  • visibility 篩選:選「公開」時只顯示 public 區,其餘區收合為 0沿用「區內為空仍顯示標題 + 精簡空狀態」的既有慣例)。

4.4 搜尋框(新增)

  • 位置:篩選列最左,Input + 前綴 Search icon既有 Input 元件 h-9
  • 行為:🔷 A6 —
    • 若後端分頁搜尋走後端debounce 300ms送 query配合分頁。
    • 若前端全量:即時前端 filter無 debounce 需求)。
  • Placeholder搜尋模型名稱...
  • 清除:有輸入時右側顯示 X 清除鈕(ghost icon button
  • 無障礙:role="searchbox"aria-label="搜尋模型";搜尋無結果時 aria-live="polite" 播報結果數。

4.5 排序(新增 ModelSortSelect

Selecth-9選項

key 文字 說明
name-asc 名稱 A→Z 預設(我的區)
createdAt-desc 最新建立
sharedAt-desc 最近共享 僅「共享給我的」區有意義;其他區隱藏此選項

🔷 排序在後端還前端由 A6 決定。若後端分頁 → 排序參數送後端。

4.6 分頁(新增,依 🔷 A6 二選一)

方案 P1cursor / 無限捲動友善)→「載入更多」按鈕Phase 0 建議,實作簡單、無頁碼狀態同步問題):

┌────────────────────────────────────────────┐
│  [卡片] [卡片] [卡片] [卡片]                 │
│  [卡片] [卡片] [卡片] [卡片]                 │
│                                             │
│            [ 載入更多 (顯示 24 / 87) ]       │  ← Button variant=outlineloading 時 Spinner
└────────────────────────────────────────────┘

方案 P2offset / 傳統頁碼)→ 底部 Pagination 元件(若後端只支援 offset

               上一頁   1  2 [3] 4  5 … 12   下一頁 

🔷 Architect 裁決 A6:後端分頁是 cursor 還 offset建議 P1「載入更多」——對「瀏覽型」的共享庫體驗較順、行動裝置友善、無「換頁後捲動位置重置」問題。若 Architect 已定 offset則走 P2。兩案我都出規格,選一即可,不需重畫卡片。

分頁 UX 細節

  • 每頁 24 筆3 欄 × 8 列 desktop卡片沿用既有 grid-cols-1 sm:2 lg:3 xl:4)。
  • 載入更多 loading按鈕內 Spinner + 文字「載入中」;同時底部補 4 個 Skeleton 卡片(沿用既有 skeleton 樣式)。
  • 搜尋 / 篩選 / 排序變更 → 重置分頁到第 1 頁 / 清空已載入。

5. 模型公開設定 UI新增 ModelVisibilityDialog

5.1 觸發點兩處owner-only

  1. 列表卡片 選單 →「公開設定」§4.2 新增的 Dropdown
  2. profile 頁owner 版)操作列 → 新增按鈕 [公開設定]variant=outline + Globe icon放在既有「下載 / 刪除」旁。

🔶 PM觸發點以上兩處是否足夠是否需要在上傳完成後直接引導設定公開對象我建議上傳 Dialog 完成後加一句「模型預設為私有,之後可在詳情頁設定公開」的提示,不強迫當下設定。)

5.2 Dialog 版型(沿用既有 Dialog

┌──────────────────────────────────────────────────┐
│  公開設定 — {模型名稱}                         [X] │
├──────────────────────────────────────────────────┤
│  誰可以看到並使用這個模型?                        │
│                                                    │
│  ○ 🔒 私有         只有你自己                       │
│  ○ 🌐 公開         所有 visionA 使用者              │
│  ● 👥 指定對象     只有你選的人                      │  ← RadioGroup
│                                                    │
│  ┌─ 指定對象(僅「指定對象」選中時展開) ──────────┐ │
│  │  [輸入 email 加入........]  [加入]              │ │
│  │  ┌──────────────────────────────────────────┐ │ │
│  │  │ alice@corp.com          可檢視+下載   [✕] │ │ │
│  │  │ bob@corp.com            可檢視+下載   [✕] │ │ │
│  │  └──────────────────────────────────────────┘ │ │
│  └────────────────────────────────────────────────┘ │
│                                                    │
│  ⚠ 公開後,所有使用者都能下載此模型(若允許下載)  │  ← public 選中時的提示
├──────────────────────────────────────────────────┤
│                            [取消]   [儲存變更]      │
└──────────────────────────────────────────────────┘

元件組成(全部沿用既有 shadcn 元件):

  • 三態選擇:RadioGroup🔷 若 components.md 未列 RadioGroup需 Architect / Frontend 確認 shadcn 是否已有,或用 Select 降級)。
  • 圖示:Lock / Globe / Users(與列表 badge 同圖示,維持一致性)。
  • 指定對象加入:Inputemail+ Button加入。email 格式即時驗證(失焦時),錯誤走既有 aria-invalid + border-destructive 樣式。
  • 對象清單:每列 = email + 權限標籤Phase 0 固定「可檢視+下載」,🔶 A4+ 移除鈕(ghost icon X)。
  • public 警告:選 public 時顯示 bg-amber-50 dark:bg-amber-950/30 提示條(沿用 §2.1 半語義約定)。
  • 底部:[取消]variant=outline+ [儲存變更]variant=defaultloading 時 Spinner

🔶 待 PM 確認

  • 「指定對象」若 Phase 0 不做Dialog 降為 private / public 兩選RadioGroup 兩項,移除展開區),版型不變。
  • 權限粒度Phase 0 是否只有「可檢視+下載」單一權限?還是要分「僅檢視 / 檢視+下載 / 檢視+燒錄」?

5.3 互動與回饋

動作 回饋
切換 private→public 顯示 amber 警告條;儲存前不生效
加入 email格式錯 Input 紅框 + 下方「Email 格式不正確」
加入 email不存在的使用者 🔷 Architect後端驗證回錯時 toast「找不到使用者 {email}」
加入重複 email Input 提示「已在清單中」,不重複加入
儲存成功 關 Dialog + toast「已更新公開設定」+ 列表 / 卡片 badge 即時更新
儲存失敗 Dialog 內 error banner「儲存失敗請重試」不關閉
public→private曾共享給人 AlertDialog 二次確認「改為私有後,已共享的對象將無法再存取,確定?」

5.4 UX Writing本功能新增文案

key 繁中 English
models.visibility.title 公開設定 Visibility
models.visibility.question 誰可以看到並使用這個模型? Who can access this model?
models.visibility.private 私有 Private
models.visibility.private.desc 只有你自己 Only you
models.visibility.public 公開 Public
models.visibility.public.desc 所有 visionA 使用者 All visionA users
models.visibility.shared 指定對象 Specific people
models.visibility.shared.desc 只有你選的人 Only people you choose
models.visibility.addEmail 輸入 email 加入 Add by email
models.visibility.publicWarning 公開後,所有使用者都能下載此模型 Once public, anyone can download this model
models.visibility.saved 已更新公開設定 Visibility updated
models.visibility.emailInvalid Email 格式不正確 Invalid email format
models.visibility.emailDuplicate 已在清單中 Already in the list
models.visibility.userNotFound 找不到使用者 {email} User {email} not found
models.visibility.revokeConfirm 改為私有後,已共享的對象將無法再存取,確定? Setting to private revokes access for shared users. Continue?
models.sharedBy 由 {email} 共享 Shared by {email}

6. 模型 profile 頁設計(擴充 /models/[id]

6.1 設計取捨:擴充既有 detail依身份切兩態

決策:不另建路由,沿用 /models/[id] + ModelDetailClient,依 model.isOwner🔷 Architect 提供)分支渲染。理由:

  • 既有 detail 頁已有完整資訊展示(描述 / 大小 / framework / inputShape / classes / checksum共享 profile 需要的資訊 90% 重疊,重畫浪費。
  • 唯一差異是「操作區權限」與「擁有者資訊」,用條件渲染即可。

🔷 Architect 確認 A5:若未來要「分享連結給未登入者 / 站外」,才需獨立 public 路由 /m/[shareId]免登入、SEO 友善。Phase 0 假設僅站內登入使用者可見,沿用 /models/[id] 即可。若需求包含站外分享連結,請 PM 明確,會影響是否要新路由。

6.2 兩態差異表

區塊 owner 版(既有) 公開 / 共享版(新增分支)
返回鈕 ← 返回(回 /models
標題 + badge 列 name + targetChip + status + source + visibility badge(公開 / 共享)
擁有者資訊列(新增) 不顯示(自己就是 owner 顯示:由 {ownerEmail} 共享 · {time} + owner 頭像(首字母圓形,沿用 UserMenu avatar 樣式)
操作列 下載 + 刪除 + 【新增】公開設定 下載(若 A4 允許);隱藏刪除 / 公開設定
描述 / metadata 卡片 完整 完整(唯讀,相同)
classes 區塊 完整 完整(唯讀)
燒錄至裝置(未來 F7+ 列出自己在線裝置 同(共享模型也能燒錄到自己的裝置)

6.3 公開版 profile 版型

┌──────────────────────────────────────────────────────┐
│  ← 返回                                                │
│                                                        │
│  ResNet50-KL720               👥 共享給我              │  ← 標題 + visibility badge
│  [KL720] [就緒] [轉檔]                                 │  ← 既有 badge 列
│                                          [⬇ 下載]      │  ← 僅下載(無刪除/公開設定)
│  ┌──────────────────────────────────────────────────┐│
│  │ 👤 由 alice@corp.com 共享 · 3 天前                 ││  ← 擁有者資訊列(新增)
│  └──────────────────────────────────────────────────┘│
│                                                        │
│  ┌─ 模型描述 ─────────────────────────────────────┐  │  ← 既有卡片,唯讀
│  │ 一般物件偵測模型...                              │  │
│  │ 大小: 24.3 MB    建立: 2026/07/20                │  │
│  │ Framework: onnx  Input: 1×3×224×224             │  │
│  │ Classes (80): [person][car][dog] +77            │  │
│  └────────────────────────────────────────────────┘  │
└──────────────────────────────────────────────────────┘

6.4 擁有者資訊列規格(新增小元件 ModelOwnerBar

  • 容器:flex items-center gap-2 + bg-muted/50 rounded-md px-3 py-2 text-sm
  • 頭像40px→改 24pxh-6 w-6 rounded-full圓形email 首字母,沿用 UserMenu avatar 配色
  • 文字:由 {ownerEmail} 共享 · {relativeTime}(相對時間 util 沿用 RemoteDeviceBadge
  • 僅在非 owner 檢視時渲染
  • 無障礙:aria-label="模型擁有者資訊"

7. 各狀態設計(空 / 載入 / 無權限 / 無結果)

沿用既有 EmptyState / Skeleton / toast文案走本功能語氣。

狀態 觸發 呈現 文案
載入中 首次載入 / 換頁 / 搜尋 既有 Skeleton 卡片網格8 個)
空 · 共享給我的(無) 「共享給我的」區無資料 EmptyState icon=Users 標題「還沒有人共享模型給你」/ 描述「當同事把模型共享給你時,會出現在這裡」
空 · 公開(無) 公開區無資料 精簡 inline 空狀態(沿用區內空狀態樣式) 「目前沒有公開的模型」
搜尋無結果 搜尋 query 無 match EmptyState icon=SearchX + [清除搜尋] CTA 標題「找不到符合『{query}』的模型」/ 描述「試試其他關鍵字或清除篩選」
無權限 直接開別人私有模型的 /models/[id] 全頁 EmptyState icon=Lock + [返回模型庫] 標題「沒有權限檢視此模型」/ 描述「這個模型未公開或未共享給你」
公開設定儲存失敗 API 錯 Dialog 內 error banner 「儲存失敗,請重試」
載入更多失敗 分頁 API 錯 「載入更多」按鈕轉為 [重試] + toast 「載入失敗,點擊重試」

無權限狀態(/models/[id] 403版型

┌──────────────────────────────────────┐
│  ← 返回                                │
│                                        │
│              🔒                        │
│      沒有權限檢視此模型                 │
│  這個模型未公開或未共享給你             │
│                                        │
│         [ 返回模型庫 ]                  │
└──────────────────────────────────────┘

🔷 Architect403 vs 404 的取捨——為避免「模型是否存在」的資訊洩漏,建議私有模型對無權限者回 404當作不存在UI 走「找不到模型」而非「無權限」。請 Architect 確認採 403 揭露存在 or 404 隱藏存在UI 兩版文案我都備。


8. 響應式(沿用既有斷點)

沿用 pages.md §11 的斷點與 /models 既有規則Mobile 單欄 / Tablet 2 欄 / Desktop 34 欄)。本功能新增元素的響應式:

元素 Mobile (<640) Tablet (6401024) Desktop (≥1024)
檢視模式 Tabs 全寬 2 等分 靠左自然寬
篩選 / 搜尋 / 排序列 堆疊(搜尋佔滿寬一行 + 篩選鈕 wrap 下一行) 部分同行 wrap 單行
visibility badge 顯示badge 列 flex-wrap 既有)
擁有者資訊列 全寬email 過長 truncate
公開設定 Dialog max-w-[calc(100vw-2rem)],對象清單可捲動 max-w-lg max-w-lg
分頁「載入更多」 全寬按鈕 置中 置中
頁碼P2 精簡(僅 頁 X/Y 完整頁碼 完整頁碼

9. 無障礙(沿用既有 + 本功能新增)

  • visibility badge:圖示(aria-hidden+ 文字雙編碼不僅靠顏色De1。SR 讀得到「公開」「已共享」文字。
  • 檢視模式 TabsRadix Tabs 內建 role="tablist" + Arrow 鍵導航 + aria-selected
  • 公開設定 RadioGroupArrow 鍵切換選項、aria-checked、每選項有可見 label。
  • email 加入Input aria-label;加入成功後焦點回 input 便於連續加入;對象清單移除鈕 aria-label="移除 {email}"
  • 搜尋框role="searchbox";無結果 aria-live="polite" 播報「找到 0 個模型」。
  • 載入更多aria-label 含當前 / 總數「載入更多,已顯示 24 之 87」。
  • 狀態改變(儲存 / 共享toast 走既有 Sonneraria-live 內建)。
  • 觸控目標:所有新增互動元素( 選單鈕、移除鈕、Tab、清除鈕≥ 44×44pxicon size = 36px 需注意,建議 profile / 卡片上用 size=icon 但外圍點擊區補到 44px或用既有 button 慣例)。🔷 Frontend 實作注意。
  • 對比度:所有新 badge 用既有 chart-* token tint 風格(/10 底 + 純色文字),與既有 source badge 同做法,既有已通過 WCAG AA。Dark Mode 由 token 自動處理。

Dark Mode:本功能不新增顏色,全用既有 tokenchart-1/2/3mutedamber-* 半語義Dark Mode 自動生效。無需獨立 Dark 版設計。(本任務 A 層 Dark Mode 截圖延到 B 層 / 實作期補,因為零新 token、純沿用。


10. 沿用 vs 新增總表

10.1 沿用既有(不改)

既有資產 用途
Design Tokens 全部 零新增
ModelGrid 卡片網格 + skeleton + 空狀態(分頁時擴充「載入更多」)
ModelSection 分區色點 + 標題 + 計數(共享關係分區沿用)
Card / Badge / Button / Dialog / AlertDialog / Select / Input / Tabs / EmptyState / Skeleton / Sonner 全部
RemoteDeviceBadge 的相對時間 util 共享時間 / owner 資訊列
UserMenu avatar 樣式 owner 頭像
§2.1 amber 半語義 public 警告條

10.2 新增Design 定義Frontend 實作)

新增 類型 基底
ModelViewToggle 元件 Tabs
visibility badge含於 ModelCard 擴充) 元件擴充 Badge + Lucide Lock/Globe/Users
ModelCard owner 選單 元件擴充 DropdownMenu🔷 確認 shadcn 已有)
ModelFilters 共享狀態維度 元件擴充 Select
搜尋框 元件擴充 Input + Search icon
ModelSortSelect 元件 Select
分頁「載入更多」or Pagination 元件 Button / 新 Pagination🔷 A6 二選一)
ModelVisibilityDialog 元件 Dialog + RadioGroup + Input + Button
ModelOwnerBar 元件 Card/div + avatar
ModelDetailClient owner/公開雙態分支 頁面擴充 條件渲染
無權限 / 搜尋無結果 / 共享空狀態 狀態 EmptyState

11. 給三方互審的重點清單

需 PM 確認需求細節 🔶

  1. A1 Visibility 態數private/public/shared 三態 vs 只 private/public 兩態「指定對象」Phase 0 要不要做?
  2. A2 指定對象粒度:個別 email vs 群組/組織/團隊?
  3. A3 列表分類:「我的 / 公開 / 共享給我的」三分類命名 OK 嗎?要不要「我公開出去的」獨立區?
  4. A4 共享權限receiver 能否下載能否再共享re-share權限是否分「僅檢視 / 檢視+下載 / 檢視+燒錄」?
  5. A7 搜尋範圍:搜尋只搜「可見的」還是要能「探索全站公開庫」?
  6. 檢視模式:「依來源」與「依共享關係」兩種 Tab 都保留,還是共享關係取代來源?
  7. 觸發引導:上傳完成後要不要引導設定公開對象?

需 Architect 確認可行性 🔷

  1. A5 / 6.1 profile 路由:沿用 /models/[id] 雙態 vs 需獨立 public 路由 /m/[shareId](站外分享連結)?
  2. A6 分頁機制:後端 cursor→ P1 載入更多)還 offset→ P2 頁碼)?搜尋 / 排序在前端還後端?
  3. ModelSummary 新欄位visibility / ownerEmail / sharedAt / sharedCount / isOwner 可否由 API 提供?
  4. 7 無權限回應碼:私有模型對無權限者回 403揭露存在還 404隱藏存在影響 UI 文案。
  5. RadioGroup / DropdownMenushadcn 元件庫是否已含這兩個?未含則需先補 or 用 Select 降級。
  6. email 對象驗證:加入指定對象時,後端能否即時驗證使用者存在?

12. Verification本設計任務自檢

  • De-A1 三斷點§8 已定義 mobile/tablet/desktop 三斷點行為(純規格 + ASCII 版型;實際截圖於 prototype / 實作期補,本階段為規格文件無渲染產出)。
  • De-A2 對比度:零新 token全沿用既有 chart-* tint + muted + amber 半語義,既有已過 WCAG AAdesign-tokens.md 已確認)。
  • De-A3 無 hardcode:本檔所有色彩引用皆為 token 名(chart-1/2/3muted-foregroundamber-50 半語義約定),無裸 hex / rgb。
  • De-A4 三態覆蓋§7 已定義空 / 載入 / 無結果 / 無權限 / 失敗多態。
  • De-A5 觸控目標§9 已標註新增互動元素 ≥ 44px 需求 + 鈕注意事項。
  • De-B1 互動五狀態 / De-B2 Dark Mode / De-B4 三方互審:延到 milestone互動狀態沿用既有元件既有態Dark Mode 零新 token 自動生效;三方互審即本檔 §11 待 PM/Architect 回審)。
  • No silent failures:所有 🔶🔷 未定項已明確標「待 PM/Architect 確認」+ 對應假設無「TBD 無負責人」。
  • Doc 同步本檔為新增pages.md / components.md 的增補建議見下方回報(本任務未直接改,避免撞名覆蓋,交 Orchestrator 決定增補方式)。