From da4ed18dfc58fe7a39000c51165d1dde527b5893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B3=E6=AC=A3=E6=80=A1?= Date: Thu, 2 Apr 2026 11:05:41 +0800 Subject: [PATCH 1/5] docs: update roles and IA to align with confirmed four-role model Update functional map and information architecture to reflect the professor-confirmed four roles: Super Admin, Data Creator / Project Leader, Annotator, and Reviewer. Add Journey D for Super Admin, expand Journey A to full project lifecycle from Project Leader view, and adjust role-settings descriptions accordingly. Co-Authored-By: Claude Sonnet 4.6 --- docs/functional-map/functional-map.md | 123 +++++++------- docs/ia/information-architecture.md | 236 ++++++++++++++++++-------- 2 files changed, 228 insertions(+), 131 deletions(-) diff --git a/docs/functional-map/functional-map.md b/docs/functional-map/functional-map.md index 2323cb1..610ceed 100644 --- a/docs/functional-map/functional-map.md +++ b/docs/functional-map/functional-map.md @@ -14,62 +14,69 @@ flowchart LR n0 --> n5["系統管理模組"] n5 --> n6["使用者管理頁"] n5 --> n7["角色權限設定頁"] - n7 --> n8["管理員"] - n7 --> n9["標記員"] - n7 --> n10["審核員"] - n0 --> n11["帳號模組"] - n11 --> n12["登入頁"] - n12 --> n13["Google"] - n12 --> n14["Github"] - n11 --> n15["個人設定頁"] - n0 --> n16["任務管理模組"] - n16 --> n17["任務列表頁"] - n16 --> n18["新增任務頁"] - n18 --> n19["任務名稱"] - n18 --> n20["資料匯入"] - n20 --> n21["Text"] - n21 --> n22["txt"] - n20 --> n23["Structured data"] - n23 --> n24["csv"] - n23 --> n25["tsv"] - n23 --> n26["json"] - n18 --> n27["範本檔案"] - n16 --> n28["任務詳情頁"] - n28 --> n29["單句任務(分類 / 評分)"] - n28 --> n30["句對任務(相似度 / 蘊含)"] - n28 --> n31["序列標記(NER、詞性標記)"] - n28 --> n32["生成式標記(人工撰寫 / 評分)"] - n0 --> n33["資料集分析模組"] - n33 --> n34["統計總覽頁"] - n34 --> n35["統計指標"] - n35 --> n36["Sentence 數量"] - n35 --> n37["token 數量"] - n35 --> n38["label 分佈"] - n33 --> n39["品質監控頁"] - n39 --> n40["監控項目"] - n40 --> n41["標記一致性"] - n40 --> n42["異常偵測"] - n0 --> n43["標記任務模組"] - n43 --> n44["試標模式(Dry Run)"] - n43 --> n45["正式標記模式(Official Run)"] - n43 --> n46["標記作業頁"] - n46 --> n47["標記操作區"] - n46 --> n48["說明與範例"] - n46 --> n49["進度指示器"] - n46 --> n50["儲存及提交"] - n46 --> n51["標記審查"] - n43 --> n52["標記結果匯出"] - n52 --> n53["JSON"] - n52 --> n54["JSON-MIN"] - n52 --> n55["CSV"] - n52 --> n56["TSV"] - n0 --> n57["標記員管理模組"] - n57 --> n58["標記員列表頁"] - n57 --> n59["新增標記員頁"] - n57 --> n60["工時紀錄頁"] - n60 --> n61["出缺勤紀錄"] - n57 --> n62["薪資試算頁"] - n62 --> n63["按時計酬"] - n62 --> n64["按件計酬"] - n62 --> n65["混合計算"] + n7 --> n8["系統超級管理員 (Super Admin)"] + n7 --> n9["資料建立者 / 計畫負責人 (Data Creator / Project Leader)"] + n7 --> n10["標記員(Annotator)"] + n7 --> n11["審核員(Reviewer)"] + n0 --> n12["帳號模組"] + n12 --> n13["登入頁"] + n13 --> n14["Google"] + n13 --> n15["email/password"] + n12 --> n16["個人設定頁"] + n16 --> n17["聯絡方式"] + n16 --> n18["姓名"] + n0 --> n19["任務管理模組"] + n19 --> n20["任務列表頁"] + n19 --> n21["新增任務頁"] + n21 --> n22["任務名稱"] + n21 --> n23["資料匯入"] + n23 --> n24["Text"] + n24 --> n25["txt"] + n23 --> n26["Structured data"] + n26 --> n27["csv"] + n26 --> n28["tsv"] + n26 --> n29["json"] + n21 --> n30["範本檔案"] + n19 --> n31["任務詳情頁"] + n31 --> n32["單句任務(分類 / 評分)"] + n31 --> n33["句對任務(相似度 / 蘊含)"] + n31 --> n34["序列標記(NER、詞性標記)"] + n31 --> n35["生成式標記(人工撰寫 / 評分)"] + n0 --> n36["資料集分析模組"] + n36 --> n37["統計總覽頁"] + n37 --> n38["統計指標"] + n38 --> n39["Sentence 數量"] + n38 --> n40["token 數量"] + n38 --> n41["label 分佈"] + n36 --> n42["品質監控頁"] + n42 --> n43["監控項目"] + n43 --> n44["標記一致性"] + n43 --> n45["異常偵測"] + n0 --> n46["標記任務模組"] + n46 --> n47["試標模式(Dry Run)"] + n47 --> n48["可上傳少量相同資料"] + n47 --> n49["指派多名標記員"] + n47 --> n50["計算一致性(IAA)"] + n47 --> n51["討論標記準則,直到共識度達標(如 0.8 以上)"] + n46 --> n52["正式標記模式(Official Run)"] + n52 --> n53["分派不同資料給標記員"] + n46 --> n54["標記作業頁"] + n54 --> n55["標記操作區"] + n54 --> n56["說明與範例"] + n54 --> n57["進度指示器"] + n54 --> n58["儲存及提交"] + n54 --> n59["標記審查"] + n46 --> n60["審核員抽查驗證"] + n60 --> n61["修正結果"] + n60 --> n62["產出標準答案"] + n46 --> n63["標記結果匯出"] + n63 --> n64["JSON"] + n63 --> n65["JSON-MIN"] + n0 --> n66["標記員管理模組"] + n66 --> n67["標記員列表頁"] + n66 --> n68["新增標記員頁"] + n66 --> n69["工時紀錄頁"] + n69 --> n70["出缺勤紀錄"] + n69 --> n71["任務標記時間"] + n69 --> n72["任務標記數量"] ``` diff --git a/docs/ia/information-architecture.md b/docs/ia/information-architecture.md index 89dd968..bb6c876 100644 --- a/docs/ia/information-architecture.md +++ b/docs/ia/information-architecture.md @@ -3,7 +3,7 @@ > **用途:** 作為 SDD 開發的參考基準。每份 `spec.md` 撰寫前,應先對照本文件確認頁面歸屬、使用者角色、進入條件與導覽關係。 > > **基礎來源:** [`functional-map.md`](../functional-map/functional-map.md) -> **版本:** v2(2026-04-01) +> **版本:** v3(2026-04-02) --- @@ -11,31 +11,33 @@ | 角色 | 識別碼 | 主要職責 | 可存取模組 | |------|--------|----------|------------| -| 管理員 | `admin` | 建立任務、管理使用者、設定系統 | 全部 | -| 標記員 | `annotator` | 執行標記作業、查看自己的進度 | 儀表板(個人)、帳號模組、標記任務模組 | -| 審核員 | `reviewer` | 審查標記結果、查看品質報告 | 儀表板、標記任務模組(審查)、資料集分析模組 | +| 資料建立者 / 計畫負責人 | `project_leader` | 建立任務、管理標記員、監控進度、設定試標與正式標、匯出資料 | 儀表板(全局)、任務管理、標記任務(唯讀)、資料集分析、標記員管理 | +| 標記員 | `annotator` | 執行標記作業(試標 / 正式標)、查看個人進度 | 儀表板(個人)、帳號模組、標記任務模組 | +| 審核員 | `reviewer` | 審查標記結果、協助產出標準答案、查看品質報告 | 儀表板、標記任務模組(審查模式)、資料集分析模組 | +| 系統超級管理員 | `super_admin` | 平台維護、跨專案使用者管理、帳號與角色設定 | 全部模組 + 系統管理模組 | + +> **注意:** Reviewer 可以是同一位 Project Leader 擔任(雙重角色)。系統以 **role** 判斷權限,而非 user,同一使用者可同時持有多個角色。 --- ## 2. 頁面清單與角色存取矩陣 -| 頁面 ID | 頁面名稱 | 所屬模組 | Admin | Annotator | Reviewer | 備註 | -|---------|----------|----------|:-----:|:---------:|:--------:|------| -| `login` | 登入頁 | 帳號模組 | ✅ | ✅ | ✅ | 未登入唯一可進入的頁面 | -| `profile` | 個人設定頁 | 帳號模組 | ✅ | ✅ | ✅ | | -| `dashboard` | 儀表板 | — | ✅ | ✅(限個人) | ✅ | 登入後預設落地頁 | -| `task-list` | 任務列表頁 | 任務管理模組 | ✅ | ❌ | ❌ | | -| `task-new` | 新增任務頁 | 任務管理模組 | ✅ | ❌ | ❌ | | -| `task-detail` | 任務詳情頁 | 任務管理模組 | ✅ | ❌ | ✅(唯讀) | | -| `annotation-workspace` | 標記作業頁 | 標記任務模組 | ❌ | ✅ | ✅(審查模式) | | -| `dataset-stats` | 統計總覽頁 | 資料集分析模組 | ✅ | ❌ | ✅ | | -| `dataset-quality` | 品質監控頁 | 資料集分析模組 | ✅ | ❌ | ✅ | | -| `annotator-list` | 標記員列表頁 | 標記員管理模組 | ✅ | ❌ | ❌ | | -| `annotator-new` | 新增標記員頁 | 標記員管理模組 | ✅ | ❌ | ❌ | | -| `work-log` | 工時紀錄頁 | 標記員管理模組 | ✅ | ❌ | ❌ | | -| `payroll` | 薪資試算頁 | 標記員管理模組 | ✅ | ❌ | ❌ | | -| `user-management` | 使用者管理頁 | 系統管理模組 | ✅ | ❌ | ❌ | | -| `role-settings` | 角色權限設定頁 | 系統管理模組 | ✅ | ❌ | ❌ | | +| 頁面 ID | 頁面名稱 | 所屬模組 | Project Leader | Annotator | Reviewer | Super Admin | 備註 | +|---------|----------|----------|:--------------:|:---------:|:--------:|:-----------:|------| +| `login` | 登入頁 | 帳號模組 | ✅ | ✅ | ✅ | ✅ | 未登入唯一可進入的頁面 | +| `profile` | 個人設定頁 | 帳號模組 | ✅ | ✅ | ✅ | ✅ | | +| `dashboard` | 儀表板 | — | ✅(全局) | ✅(個人) | ✅ | ✅ | 登入後預設落地頁 | +| `task-list` | 任務列表頁 | 任務管理模組 | ✅ | ❌ | ❌ | ✅ | | +| `task-new` | 新增任務頁 | 任務管理模組 | ✅ | ❌ | ❌ | ✅ | | +| `task-detail` | 任務詳情頁 | 任務管理模組 | ✅ | ❌ | ✅(唯讀) | ✅ | | +| `annotation-workspace` | 標記作業頁 | 標記任務模組 | ❌ | ✅ | ✅(審查模式) | ✅ | | +| `dataset-stats` | 統計總覽頁 | 資料集分析模組 | ✅ | ❌ | ✅ | ✅ | | +| `dataset-quality` | 品質監控頁 | 資料集分析模組 | ✅ | ❌ | ✅ | ✅ | | +| `annotator-list` | 標記員列表頁 | 標記員管理模組 | ✅ | ❌ | ❌ | ✅ | | +| `annotator-new` | 新增標記員頁 | 標記員管理模組 | ✅ | ❌ | ❌ | ✅ | | +| `work-log` | 工時紀錄頁 | 標記員管理模組 | ✅ | ✅(僅自己) | ❌ | ✅ | | +| `user-management` | 使用者管理頁 | 系統管理模組 | ❌ | ❌ | ❌ | ✅ | 平台級帳號管理 | +| `role-settings` | 角色權限設定頁 | 系統管理模組 | ❌ | ❌ | ❌ | ✅ | | --- @@ -52,29 +54,28 @@ flowchart TD PROFILE["👤 profile\n個人設定頁"] end - subgraph 任務管理模組["任務管理模組(Admin)"] + subgraph 任務管理模組["任務管理模組(Project Leader)"] TLIST["task-list\n任務列表頁"] TNEW["task-new\n新增任務頁"] TDETAIL["task-detail\n任務詳情頁"] end subgraph 標記任務模組["標記任務模組(Annotator / Reviewer)"] - ANNOT["annotation-workspace\n標記作業頁"] + ANNOT["annotation-workspace\n標記作業頁\n(Dry Run / Official Run)"] end - subgraph 資料集分析模組["資料集分析模組(Admin / Reviewer)"] + subgraph 資料集分析模組["資料集分析模組(Project Leader / Reviewer)"] STATS["dataset-stats\n統計總覽頁"] - QUALITY["dataset-quality\n品質監控頁"] + QUALITY["dataset-quality\n品質監控頁\n(IAA / 異常偵測)"] end - subgraph 標記員管理模組["標記員管理模組(Admin)"] + subgraph 標記員管理模組["標記員管理模組(Project Leader)"] ALIST["annotator-list\n標記員列表頁"] ANEW["annotator-new\n新增標記員頁"] WLOG["work-log\n工時紀錄頁"] - PAY["payroll\n薪資試算頁"] end - subgraph 系統管理模組["系統管理模組(Admin)"] + subgraph 系統管理模組["系統管理模組(Super Admin)"] USERS["user-management\n使用者管理頁"] ROLES["role-settings\n角色權限設定頁"] end @@ -84,17 +85,19 @@ flowchart TD DASH --> TLIST DASH --> ANNOT DASH --> STATS + DASH --> ALIST DASH --> USERS TLIST --> TNEW TLIST --> TDETAIL - TDETAIL -->|指派任務| ANNOT + TDETAIL -->|指派 Dry Run| ANNOT + TDETAIL -->|指派 Official Run| ANNOT ANNOT -->|完成標記| TDETAIL + TDETAIL -->|匯出資料| TDETAIL ALIST --> ANEW ALIST --> WLOG - ALIST --> PAY USERS --> ROLES @@ -109,12 +112,12 @@ flowchart TD #### `login` 登入頁 - **進入方式:** 未登入時唯一可見頁面;所有未授權跳轉均導回此頁 -- **功能:** Email / Password 登入、Google SSO、GitHub SSO +- **功能:** Email / Password 登入、Google SSO - **離開方式:** 登入成功 → `dashboard` #### `profile` 個人設定頁 - **進入方式:** Navbar 使用者頭像 → `profile` -- **功能:** 修改顯示名稱、上傳頭像、修改密碼、查看角色 +- **功能:** 修改姓名、修改聯絡方式、修改密碼、查看角色 - **離開方式:** 儲存成功 → 停留;取消 → `dashboard` --- @@ -123,33 +126,76 @@ flowchart TD #### `dashboard` 儀表板 - **進入方式:** 登入後預設落地頁;Navbar Logo 點擊 -- **功能(Admin):** 全系統任務概況、所有標記員進度、系統公告 -- **功能(Annotator):** 個人被指派的任務清單、個人標記進度 -- **功能(Reviewer):** 待審查任務清單、整體進度 -- **離開方式:** 導覽列 → 各模組 +- **離開方式:** 導覽列 → 各模組;卡片快捷入口 → 對應頁面 + +**Project Leader 視角:** +- **任務總覽卡:** 所有任務列表,每筆顯示任務名稱、任務類型、當前狀態(草稿 / Dry Run 進行中 / 等待 IAA 確認 / Official Run 進行中 / 已完成)、整體完成率進度條 +- **待處理事項區:** IAA 結果待確認(附快速連結至 `dataset-quality`)、Dry Run 已全員完成待啟動 Official Run +- **標記員進度區:** 各標記員本任務完成數 / 今日完成數 / 平均速度,速度異常者標示警示 +- **系統公告區** +- **空狀態(尚未建立任何任務):** 說明文字 + 「建立第一個任務」按鈕(→ `task-new`) + +**Annotator 視角:** +- **我的任務列表:** 分「Dry Run」與「Official Run」兩區,每筆顯示任務名稱、已完成數 / 總分配數、狀態(未開始 / 進行中 / 已提交) +- **個人進度摘要:** 今日完成數、累計完成數、距離本任務完成還剩幾筆 +- **快速繼續按鈕:** 直接進入上次未完成的任務(`annotation-workspace`) +- **空狀態(尚未被指派任務):** 說明文字「尚未有指派任務,請等待管理員分配」,次要按鈕:「查看個人工時紀錄」(→ `work-log`)、「編輯個人資料」(→ `profile`) + +**Reviewer 視角:** +- **待審查任務列表:** 每筆顯示任務名稱、待審核筆數、已審核 / 總筆數 +- **Dry Run IAA 摘要:** 顯示當前 Dry Run 的 IAA 分數(依任務類型顯示對應指標),達標 / 未達標狀態 +- **快速進入審查按鈕:** 直接進入 `annotation-workspace` 審查模式 +- **空狀態(目前無待審查任務):** 說明文字,次要按鈕:「查看統計報告」(→ `dataset-stats`) + +**Super Admin 視角:** +- 同 Project Leader 全局視角(所有任務 + 標記員進度) +- **平台使用者快覽:** 各角色帳號數量、快速進入 `user-management` --- ### 任務管理模組 #### `task-list` 任務列表頁 -- **進入方式:** 儀表板 Navbar → 任務管理 +- **進入方式:** Navbar → 任務管理 - **功能:** 顯示所有任務(含狀態 badge)、搜尋 / 篩選、進入任務詳情 - **離開方式:** 點選任務 → `task-detail`;「新增任務」按鈕 → `task-new` #### `task-new` 新增任務頁 - **進入方式:** `task-list` → 新增任務 -- **功能:** 填寫任務名稱、上傳資料集(txt / csv / tsv / json)、選擇任務類型、上傳範本 +- **流程:** 分三步驟完成(Step 1 → Step 2 → Step 3) +- **Step 1 — 基本資料:** + - 填寫任務名稱 + - 上傳資料集(txt / csv / tsv / json) + - 選擇任務類型(決定 Step 2 的 Config Builder 內容) +- **Step 2 — Config Builder(介面輔助設定,無需手寫 config):** + - **分類任務:** 新增 / 編輯標籤清單(Label Name + 說明),支援多標籤 / 單標籤切換 + - **評分 / 回歸任務:** 設定分數範圍(最小值 / 最大值)、刻度單位、介面顯示方式(滑桿 / 數字輸入 / 選項按鈕) + - **句對任務:** 選擇關係類型(相似度 / 蘊含 / 自訂),設定評分或分類標籤 + - **序列標記(NER):** 新增 / 編輯實體類型清單(Entity Name + 顏色 + 說明) + - **關係抽取:** 設定實體類型清單(同 NER)+ 關係類型清單(Relation Name + 說明),標記介面呈現 Entity List / Relation Type / Triple List 三區 + - **生成式標記:** 設定評分維度(如流暢度 / 正確性)或開放文字輸入 + - 系統在背後將設定轉為 YAML/JSON config;可預覽 / 下載 config 原始檔(供技術人員驗證) +- **Step 3 — 標記說明(選填):** + - 上傳標記範本 / 說明文件(PDF / 圖片 / 文字),顯示於 `annotation-workspace` 的「說明與範例」區 - **任務類型:** - 單句任務(分類 / 評分) - 句對任務(相似度 / 蘊含) - 序列標記(NER、詞性標記) + - 關係抽取(Entity + Relation + Triple) - 生成式標記(人工撰寫 / 評分) +- **空狀態:** 不適用(此頁為建立流程,永遠有內容) - **離開方式:** 建立成功 → `task-detail`;取消 → `task-list` #### `task-detail` 任務詳情頁 - **進入方式:** `task-list` 點選任務 -- **功能:** 查看任務設定、指派標記員、發布試標 / 正式標記、查看標記進度 +- **功能:** + - 查看任務設定與任務類型 + - 指派標記員(從 `annotator-list` 選取) + - 發布試標(Dry Run):選取共用樣本集(建議 20 句),發布給所有標記員 + - 發布正式標記(Official Run):在 IAA 達標(≥ 0.8)後啟動,分派不重疊資料給各標記員 + - 查看標記進度(各標記員完成數 / 速度) + - 匯出標記結果(JSON / JSON-MIN) +- **資料隔離原則:** Dry Run 資料與 Official Run 資料必須隔離,不得混入正式標記集 - **離開方式:** 「開始標記」→ `annotation-workspace`;返回 → `task-list` --- @@ -158,25 +204,43 @@ flowchart TD #### `annotation-workspace` 標記作業頁 - **進入方式:** `dashboard` 任務卡片;`task-detail` 指派後 -- **兩種模式:** - - **Dry Run(試標):** 正式開始前的介面驗證,結果不計入正式資料 - - **Official Run(正式標記):** 正式資料收集 -- **功能(Annotator):** 標記操作區、說明與範例、進度指示器、儲存 / 提交 -- **功能(Reviewer):** 審查模式,可通過 / 退回標記結果 +- **兩種模式(run_type):** + - **Dry Run(試標):** 所有標記員標記相同樣本,結果不計入正式資料,用於計算 IAA 與討論標記準則 + - **Official Run(正式標記):** 每位標記員分配不重疊的資料,結果計入正式資料集 +- **功能(Annotator):** 標記操作區、說明與範例、進度指示器(即時顯示完成數)、儲存 / 提交 +- **功能(Reviewer):** 審查模式,可通過 / 退回標記結果、直接修改或刪除錯誤標記、協助產出 Dry Run 標準答案(多數決或手動確認) - **離開方式:** 提交 → 停留(下一筆)或返回 `dashboard`;中途離開 → 自動儲存草稿 --- ### 資料集分析模組 +> 本模組依任務類型動態調整顯示內容。所有頁面均以當前任務的 `task_type` 作為分析維度切換依據。 + #### `dataset-stats` 統計總覽頁 - **進入方式:** Navbar → 資料集分析 → 統計總覽 -- **功能:** Sentence 數量、Token 數量、Label 分佈視覺化圖表 +- **共用指標(所有任務):** Sentence 數量、Token 數量、整體完成率 +- **任務類型特定指標:** + - **分類任務:** 各標籤次數 / 比例長條圖、多標籤共現矩陣 + - **評分 / 回歸任務:** 分數分佈直方圖、平均值 / 標準差 / 中位數 + - **序列標記(NER):** 實體類型分佈、每句平均實體數、Entity span 長度分佈 + - **關係抽取:** 實體類型分佈 + 關係類型分佈、Triple 數量統計 + - **句對任務:** 依標籤或分數呈現(同分類 / 評分) + - **生成式標記:** 輸出文字長度分佈;若含評分維度則同評分任務 +- **空狀態(尚無標記資料):** 說明文字「尚無標記資料,請先發布 Dry Run」,次要按鈕「前往任務詳情」(→ `task-detail`) - **離開方式:** 切換至 `dataset-quality` #### `dataset-quality` 品質監控頁 - **進入方式:** `dataset-stats` 切換;或 Navbar 直接進入 -- **功能:** 標記一致性分析(Inter-Annotator Agreement)、異常偵測(低信心標記 / 離群值) +- **IAA 計算方法(依任務類型):** + - **分類任務:** Cohen's Kappa(兩人)/ Fleiss' Kappa(多人),目標 ≥ 0.8 + - **評分 / 回歸任務:** Krippendorff's Alpha、Pearson / Spearman 相關係數 + - **序列標記(NER):** Entity-level F1(標記員兩兩比較) + - **關係抽取:** Triple-level agreement(Entity + Relation 完全一致才算匹配) + - **句對任務:** 同分類或評分(依 config 類型) +- **異常偵測(所有任務):** 標記速度異常(過快 / 過慢)、離群標記值 +- **標記員個別速度統計** +- **空狀態(Dry Run 尚未完成):** 說明文字「IAA 報告將在 Dry Run 完成後產生」,次要按鈕「前往任務詳情」(→ `task-detail`) - **離開方式:** 返回 `dataset-stats` --- @@ -186,62 +250,70 @@ flowchart TD #### `annotator-list` 標記員列表頁 - **進入方式:** Navbar → 標記員管理 - **功能:** 查看所有標記員帳號、啟用 / 停用、進入個別詳情 +- **空狀態(尚未新增任何標記員):** 說明文字 + 「新增第一位標記員」按鈕(→ `annotator-new`) - **離開方式:** 「新增標記員」→ `annotator-new`;點選標記員 → `work-log` #### `annotator-new` 新增標記員頁 - **進入方式:** `annotator-list` → 新增 -- **功能:** 填寫基本資料、設定薪資計算方式(按時 / 按件 / 混合) +- **功能:** 填寫基本資料(名稱、Email) - **離開方式:** 儲存 → `annotator-list`;取消 → `annotator-list` #### `work-log` 工時紀錄頁 -- **進入方式:** `annotator-list` → 點選標記員 -- **功能:** 出缺勤紀錄、每日工時、標記任務次數 -- **離開方式:** 返回 `annotator-list`;導向 `payroll` - -#### `payroll` 薪資試算頁 -- **進入方式:** `work-log` → 薪資試算;或 `annotator-list` 薪資按鈕 -- **功能:** - - 按時計酬(時薪 × 工時) - - 按件計酬(件數 × 單價) - - 混合計算(自訂比例) -- **離開方式:** 返回 `annotator-list` +- **進入方式(Project Leader):** `annotator-list` → 點選標記員 → 查看該標記員紀錄 +- **進入方式(Annotator):** Navbar → 工時紀錄 → 僅顯示自己的紀錄 +- **功能:** 出缺勤紀錄、任務標記時間(系統自動追蹤)、任務標記數量 +- **資料範圍:** Project Leader 可查看所有標記員;Annotator 只能查看自己的紀錄 +- **用途說明:** 作為工時結算的依據記錄;實際計薪由系統外部處理,系統不提供計薪功能 +- **空狀態(尚無工時紀錄):** 說明文字「尚無工時紀錄」,無需額外按鈕 +- **離開方式:** 返回 `annotator-list`(Project Leader);返回 `dashboard`(Annotator) --- ### 系統管理模組 +> 本模組僅 `super_admin` 可存取。`project_leader` 的人員管理(標記員帳號)在「標記員管理模組」中進行。 + #### `user-management` 使用者管理頁 - **進入方式:** Navbar → 系統管理 → 使用者管理 -- **功能:** 查看所有使用者、新增 / 編輯 / 停用帳號、指派角色 +- **功能:** 查看所有平台使用者(跨專案)、新增 / 編輯 / 停用帳號、指派角色(含 project_leader / annotator / reviewer / super_admin) - **離開方式:** 點選角色設定 → `role-settings` #### `role-settings` 角色權限設定頁 - **進入方式:** `user-management` → 角色設定 -- **功能:** 設定管理員 / 標記員 / 審核員的功能存取範圍 +- **功能:** 設定各角色(project_leader / annotator / reviewer / super_admin)的功能存取範圍 - **離開方式:** 儲存 → `user-management` --- ## 5. 核心使用者旅程 -### 旅程 A — 管理員建立任務並指派標記員 +### 旅程 A — 完整專案生命週期(Project Leader 視角) ```mermaid sequenceDiagram - participant A as Admin - participant TL as task-list + participant PL as Project Leader participant TN as task-new participant TD as task-detail participant AL as annotator-list + participant AW as annotation-workspace + participant DQ as dataset-quality - A->>TL: 進入任務列表 - A->>TN: 點擊「新增任務」 - A->>TN: 上傳資料集 + 選擇任務類型 + PL->>TN: 上傳資料集 + 設定任務類型 TN-->>TD: 建立成功,跳轉詳情頁 - A->>TD: 指派標記員(從 annotator-list 選取) - A->>TD: 發布 Dry Run - TD-->>A: 試標完成通知 - A->>TD: 確認後發布 Official Run + PL->>AL: 新增標記員帳號 + PL->>TD: 指派標記員 + 發布 Dry Run(共同樣本 ~20 句) + Note over AW: 所有標記員標記相同樣本 + AW-->>TD: 試標完成通知 + PL->>DQ: 查看 IAA 結果 + alt IAA ≥ 0.8 + PL->>TD: 確認標記準則,發布 Official Run + Note over AW: 各標記員分配不重疊資料 + AW-->>TD: 標記進度更新 + PL->>TD: 全部完成後,匯出標記結果(JSON / JSON-MIN) + else IAA < 0.8 + PL->>DQ: 查看差異報告,召開討論修正準則 + PL->>TD: 重新發布 Dry Run + end ``` ### 旅程 B — 標記員完成標記作業 @@ -252,11 +324,11 @@ sequenceDiagram participant D as dashboard participant AW as annotation-workspace - AN->>D: 登入後查看待標記任務 + AN->>D: 登入後查看待標記任務(Dry Run 或 Official Run) AN->>AW: 點擊任務卡片進入標記頁 loop 逐筆標記 AN->>AW: 完成當筆標記 - AW-->>AN: 自動儲存 + 進度更新 + AW-->>AN: 自動儲存 + 即時更新完成數 end AN->>AW: 全部完成 → 提交 AW-->>D: 跳轉回儀表板,任務狀態更新為 Submitted @@ -264,6 +336,8 @@ sequenceDiagram ### 旅程 C — 審核員審查並查看品質報告 +> 審核員可以是 Project Leader 本人(雙重角色)。 + ```mermaid sequenceDiagram participant R as Reviewer @@ -273,8 +347,24 @@ sequenceDiagram R->>AW: 進入審查模式,逐筆審核 R->>AW: 通過 / 退回標記結果 + Note over AW: Dry Run 階段:協助產出標準答案(多數決 / 手動確認) R->>DS: 查看統計總覽(Sentence / Token / Label 分佈) - R->>DQ: 查看標記一致性與異常偵測報告 + R->>DQ: 查看 IAA 報告與異常偵測結果 +``` + +### 旅程 D — Super Admin 使用者管理 + +```mermaid +sequenceDiagram + participant SA as Super Admin + participant UM as user-management + participant RS as role-settings + + SA->>UM: 查看所有使用者帳號 + SA->>UM: 新增 Project Leader 帳號(研究員 / 負責人) + SA->>UM: 指派角色(project_leader / reviewer / super_admin) + SA->>RS: 調整角色功能存取範圍 + Note over SA: 標記員帳號由 Project Leader 自行在標記員管理模組新增 ``` --- From 2877d27a0189e6599c18289e826442f3533e2f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B3=E6=AC=A3=E6=80=A1?= Date: Thu, 2 Apr 2026 15:04:54 +0800 Subject: [PATCH 2/5] docs: update IA with confirmed roles, empty states, and Label Studio insights MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add Super Admin role, rename admin → project_leader - Add task-type-specific dashboard cards and empty states for all pages - Add Config Builder with Visual/Code dual mode and template entry point - Add annotation workspace History tab and labeling instruction modal - Add relation extraction task type and task-type-aware dataset analysis - Add .serena/ to .gitignore Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 3 +++ docs/ia/information-architecture.md | 24 ++++++++++++++++-------- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index a208825..07a0049 100644 --- a/.gitignore +++ b/.gitignore @@ -44,3 +44,6 @@ assets/logo/*.png # Qodo code review bot working directory .qodo/ + +# Serena MCP server project config (local dev environment) +.serena/ diff --git a/docs/ia/information-architecture.md b/docs/ia/information-architecture.md index bb6c876..2c6e0e6 100644 --- a/docs/ia/information-architecture.md +++ b/docs/ia/information-architecture.md @@ -150,6 +150,7 @@ flowchart TD **Super Admin 視角:** - 同 Project Leader 全局視角(所有任務 + 標記員進度) - **平台使用者快覽:** 各角色帳號數量、快速進入 `user-management` +- **空狀態(平台剛部署,尚無任務與使用者):** 說明文字「平台尚未有任何資料」,次要按鈕:「管理使用者」(→ `user-management`) --- @@ -158,6 +159,7 @@ flowchart TD #### `task-list` 任務列表頁 - **進入方式:** Navbar → 任務管理 - **功能:** 顯示所有任務(含狀態 badge)、搜尋 / 篩選、進入任務詳情 +- **空狀態(尚未建立任何任務):** 說明文字 + 「建立第一個任務」按鈕(→ `task-new`) - **離開方式:** 點選任務 → `task-detail`;「新增任務」按鈕 → `task-new` #### `task-new` 新增任務頁 @@ -168,15 +170,18 @@ flowchart TD - 上傳資料集(txt / csv / tsv / json) - 選擇任務類型(決定 Step 2 的 Config Builder 內容) - **Step 2 — Config Builder(介面輔助設定,無需手寫 config):** - - **分類任務:** 新增 / 編輯標籤清單(Label Name + 說明),支援多標籤 / 單標籤切換 - - **評分 / 回歸任務:** 設定分數範圍(最小值 / 最大值)、刻度單位、介面顯示方式(滑桿 / 數字輸入 / 選項按鈕) - - **句對任務:** 選擇關係類型(相似度 / 蘊含 / 自訂),設定評分或分類標籤 - - **序列標記(NER):** 新增 / 編輯實體類型清單(Entity Name + 顏色 + 說明) - - **關係抽取:** 設定實體類型清單(同 NER)+ 關係類型清單(Relation Name + 說明),標記介面呈現 Entity List / Relation Type / Triple List 三區 - - **生成式標記:** 設定評分維度(如流暢度 / 正確性)或開放文字輸入 - - 系統在背後將設定轉為 YAML/JSON config;可預覽 / 下載 config 原始檔(供技術人員驗證) + - 提供「從範本開始」入口:常用任務類型的預設 config(如三分類情感、NER 醫療實體),可直接套用後微調,降低設定門檻 + - **Visual 模式(預設):** + - **分類任務:** 新增 / 編輯標籤清單(Label Name + 說明),支援多標籤 / 單標籤切換 + - **評分 / 回歸任務:** 設定分數範圍(最小值 / 最大值)、刻度單位、介面顯示方式(滑桿 / 數字輸入 / 選項按鈕) + - **句對任務:** 選擇關係類型(相似度 / 蘊含 / 自訂),設定評分或分類標籤 + - **序列標記(NER):** 新增 / 編輯實體類型清單(Entity Name + 顏色 + 說明) + - **關係抽取:** 設定實體類型清單(同 NER)+ 關係類型清單(Relation Name + 說明),標記介面呈現 Entity List / Relation Type / Triple List 三區 + - **生成式標記:** 設定評分維度(如流暢度 / 正確性)或開放文字輸入 + - **Code 模式(進階):** 直接檢視 / 編輯系統產生的 YAML/JSON config 原始碼,供技術人員驗證或手動調整;Visual 與 Code 模式可互相切換 - **Step 3 — 標記說明(選填):** - 上傳標記範本 / 說明文件(PDF / 圖片 / 文字),顯示於 `annotation-workspace` 的「說明與範例」區 + - 可設定「開始標記前強制顯示」:Annotator 每次進入任務時先跳出說明 modal,確認後才進入標記介面 - **任務類型:** - 單句任務(分類 / 評分) - 句對任務(相似度 / 蘊含) @@ -207,8 +212,10 @@ flowchart TD - **兩種模式(run_type):** - **Dry Run(試標):** 所有標記員標記相同樣本,結果不計入正式資料,用於計算 IAA 與討論標記準則 - **Official Run(正式標記):** 每位標記員分配不重疊的資料,結果計入正式資料集 -- **功能(Annotator):** 標記操作區、說明與範例、進度指示器(即時顯示完成數)、儲存 / 提交 +- **功能(Annotator):** 標記操作區、說明與範例(側欄)、進度指示器(即時顯示完成數)、儲存 / 提交 + - **標記說明強制顯示:** 若 Project Leader 在任務設定中啟用,Annotator 每次進入任務前會先看到說明 modal,確認後才進入標記介面 - **功能(Reviewer):** 審查模式,可通過 / 退回標記結果、直接修改或刪除錯誤標記、協助產出 Dry Run 標準答案(多數決或手動確認) +- **標記歷程(History):** 每筆資料的所有標記修改紀錄(誰、何時、改成什麼),Reviewer 可追溯標記變更歷程 - **離開方式:** 提交 → 停留(下一筆)或返回 `dashboard`;中途離開 → 自動儲存草稿 --- @@ -276,6 +283,7 @@ flowchart TD #### `user-management` 使用者管理頁 - **進入方式:** Navbar → 系統管理 → 使用者管理 - **功能:** 查看所有平台使用者(跨專案)、新增 / 編輯 / 停用帳號、指派角色(含 project_leader / annotator / reviewer / super_admin) +- **空狀態(尚無任何使用者):** 說明文字「尚未建立任何使用者帳號」 + 「新增第一位使用者」按鈕 - **離開方式:** 點選角色設定 → `role-settings` #### `role-settings` 角色權限設定頁 From 620329d430cd1c0217c578d55d42176ed28ccbab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B3=E6=AC=A3=E6=80=A1?= Date: Thu, 2 Apr 2026 15:16:13 +0800 Subject: [PATCH 3/5] docs: update functional map to v2, sync with IA v3 - Add role-specific dashboard views (Project Leader / Annotator / Reviewer / Super Admin) - Expand task-new to 3-step flow with Config Builder (Visual/Code modes, template library) - Add relation extraction task type (Entity + Relation + Triple) - Add task-detail details: assign annotators, Dry/Official Run publish, data isolation, export - Add annotation-workspace: forced instruction modal, History tab - Add reviewer direct edit capability - Expand dataset-stats with task-type-specific metrics - Expand dataset-quality with IAA methods per task type (Cohen/Fleiss Kappa, Krippendorff's Alpha, Entity-level F1, Triple-level agreement) - Add work-log note: settlement record only, payroll handled externally - Update role-settings node names to match IA identifiers Co-Authored-By: Claude Sonnet 4.6 --- docs/functional-map/functional-map.md | 201 ++++++++++++++++---------- 1 file changed, 128 insertions(+), 73 deletions(-) diff --git a/docs/functional-map/functional-map.md b/docs/functional-map/functional-map.md index 610ceed..247e49a 100644 --- a/docs/functional-map/functional-map.md +++ b/docs/functional-map/functional-map.md @@ -1,82 +1,137 @@ # Label Suite — Functional Map -> **線上版:** [在 XMind 開啟](https://app.xmind.com/share/PKjJEIHD) +> **線上版:** [在 XMind 開啟](https://app.xmind.com/share/PKjJEIHD)(線上版可能落後本文件,以本文件為準) +> +> **版本:** v2(2026-04-02)— 依 [IA v3](../ia/information-architecture.md) 同步更新 --- ```mermaid flowchart LR n0(["Label Suite"]) - n0 --> n1["儀表板"] - n1 --> n2["任務概況"] - n1 --> n3["標記進度"] - n1 --> n4["系統公告"] - n0 --> n5["系統管理模組"] - n5 --> n6["使用者管理頁"] - n5 --> n7["角色權限設定頁"] - n7 --> n8["系統超級管理員 (Super Admin)"] - n7 --> n9["資料建立者 / 計畫負責人 (Data Creator / Project Leader)"] - n7 --> n10["標記員(Annotator)"] - n7 --> n11["審核員(Reviewer)"] - n0 --> n12["帳號模組"] - n12 --> n13["登入頁"] - n13 --> n14["Google"] - n13 --> n15["email/password"] - n12 --> n16["個人設定頁"] - n16 --> n17["聯絡方式"] - n16 --> n18["姓名"] - n0 --> n19["任務管理模組"] - n19 --> n20["任務列表頁"] - n19 --> n21["新增任務頁"] - n21 --> n22["任務名稱"] - n21 --> n23["資料匯入"] - n23 --> n24["Text"] - n24 --> n25["txt"] - n23 --> n26["Structured data"] - n26 --> n27["csv"] - n26 --> n28["tsv"] - n26 --> n29["json"] - n21 --> n30["範本檔案"] - n19 --> n31["任務詳情頁"] - n31 --> n32["單句任務(分類 / 評分)"] - n31 --> n33["句對任務(相似度 / 蘊含)"] - n31 --> n34["序列標記(NER、詞性標記)"] - n31 --> n35["生成式標記(人工撰寫 / 評分)"] - n0 --> n36["資料集分析模組"] - n36 --> n37["統計總覽頁"] - n37 --> n38["統計指標"] - n38 --> n39["Sentence 數量"] - n38 --> n40["token 數量"] - n38 --> n41["label 分佈"] - n36 --> n42["品質監控頁"] - n42 --> n43["監控項目"] - n43 --> n44["標記一致性"] - n43 --> n45["異常偵測"] - n0 --> n46["標記任務模組"] - n46 --> n47["試標模式(Dry Run)"] - n47 --> n48["可上傳少量相同資料"] - n47 --> n49["指派多名標記員"] - n47 --> n50["計算一致性(IAA)"] - n47 --> n51["討論標記準則,直到共識度達標(如 0.8 以上)"] - n46 --> n52["正式標記模式(Official Run)"] - n52 --> n53["分派不同資料給標記員"] - n46 --> n54["標記作業頁"] - n54 --> n55["標記操作區"] - n54 --> n56["說明與範例"] - n54 --> n57["進度指示器"] - n54 --> n58["儲存及提交"] - n54 --> n59["標記審查"] - n46 --> n60["審核員抽查驗證"] - n60 --> n61["修正結果"] - n60 --> n62["產出標準答案"] - n46 --> n63["標記結果匯出"] - n63 --> n64["JSON"] - n63 --> n65["JSON-MIN"] - n0 --> n66["標記員管理模組"] - n66 --> n67["標記員列表頁"] - n66 --> n68["新增標記員頁"] - n66 --> n69["工時紀錄頁"] - n69 --> n70["出缺勤紀錄"] - n69 --> n71["任務標記時間"] - n69 --> n72["任務標記數量"] + + %% ── 帳號模組 ── + n0 --> nACC["帳號模組"] + nACC --> nLOGIN["登入頁"] + nLOGIN --> nLG["Google SSO"] + nLOGIN --> nLE["Email / Password"] + nACC --> nPROF["個人設定頁"] + nPROF --> nPN["姓名"] + nPROF --> nPC["聯絡方式"] + nPROF --> nPPW["修改密碼"] + nPROF --> nPR["查看角色"] + + %% ── 儀表板 ── + n0 --> nDASH["儀表板"] + nDASH --> nDPL["Project Leader 視角"] + nDPL --> nDPL1["任務總覽卡(狀態 / 進度條)"] + nDPL --> nDPL2["待處理事項(IAA 確認 / Dry Run 完成)"] + nDPL --> nDPL3["標記員進度區(速度 / 異常警示)"] + nDPL --> nDPL4["系統公告"] + nDASH --> nDAN["Annotator 視角"] + nDAN --> nDAN1["我的任務列表(Dry Run / Official Run)"] + nDAN --> nDAN2["個人進度摘要(今日 / 累計)"] + nDAN --> nDAN3["快速繼續按鈕"] + nDASH --> nDRV["Reviewer 視角"] + nDRV --> nDRV1["待審查任務列表(待審核筆數)"] + nDRV --> nDRV2["Dry Run IAA 摘要(達標 / 未達標)"] + nDASH --> nDSA["Super Admin 視角"] + nDSA --> nDSA1["全局任務 + 標記員進度"] + nDSA --> nDSA2["平台使用者角色帳號快覽"] + + %% ── 任務管理模組 ── + n0 --> nTASK["任務管理模組"] + nTASK --> nTL["任務列表頁"] + nTASK --> nTN["新增任務頁"] + nTN --> nTN1["Step 1 — 基本資料"] + nTN1 --> nTN1A["任務名稱"] + nTN1 --> nTN1B["上傳資料集(txt / csv / tsv / json)"] + nTN1 --> nTN1C["選擇任務類型"] + nTN --> nTN2["Step 2 — Config Builder"] + nTN2 --> nTN2A["Visual 模式(預設)"] + nTN2A --> nTN2A1["分類:標籤清單(多選 / 單選)"] + nTN2A --> nTN2A2["評分:分數範圍 / 刻度 / 介面型式"] + nTN2A --> nTN2A3["句對:關係類型 / 評分或分類"] + nTN2A --> nTN2A4["NER:實體類型清單(名稱+顏色)"] + nTN2A --> nTN2A5["關係抽取:實體類型 + 關係類型清單"] + nTN2A --> nTN2A6["生成式:評分維度 / 開放文字"] + nTN2 --> nTN2B["Code 模式(進階 YAML/JSON)"] + nTN2 --> nTN2C["從範本開始(預設 config 快速套用)"] + nTN --> nTN3["Step 3 — 標記說明(選填)"] + nTN3 --> nTN3A["上傳說明文件(PDF / 圖片 / 文字)"] + nTN3 --> nTN3B["強制顯示設定(進入任務前 modal)"] + nTN --> nTNTYPE["任務類型"] + nTNTYPE --> nTT1["單句任務(分類 / 評分)"] + nTNTYPE --> nTT2["句對任務(相似度 / 蘊含)"] + nTNTYPE --> nTT3["序列標記(NER / 詞性標記)"] + nTNTYPE --> nTT4["關係抽取(Entity + Relation + Triple)"] + nTNTYPE --> nTT5["生成式標記(人工撰寫 / 評分)"] + nTASK --> nTD["任務詳情頁"] + nTD --> nTD1["指派標記員(從標記員列表選取)"] + nTD --> nTD2["發布 Dry Run(共同樣本 ~20 句)"] + nTD --> nTD3["發布 Official Run(IAA ≥ 0.8 後啟動)"] + nTD --> nTD4["資料隔離(Dry Run / Official Run 不混用)"] + nTD --> nTD5["查看標記進度(各標記員完成數 / 速度)"] + nTD --> nTD6["匯出標記結果"] + nTD6 --> nEX1["JSON"] + nTD6 --> nEX2["JSON-MIN"] + + %% ── 標記任務模組 ── + n0 --> nANN["標記任務模組"] + nANN --> nDR["試標模式(Dry Run)"] + nDR --> nDR1["共同樣本 ~20 句,全員標記"] + nDR --> nDR2["計算 IAA(目標 ≥ 0.8)"] + nDR --> nDR3["討論標記準則直至達標"] + nANN --> nOR["正式標記模式(Official Run)"] + nOR --> nOR1["分派不重疊資料給各標記員"] + nANN --> nAW["標記作業頁(Annotator)"] + nAW --> nAW1["標記操作區"] + nAW --> nAW2["說明與範例(側欄)"] + nAW --> nAW3["進度指示器(即時完成數)"] + nAW --> nAW4["儲存及提交(自動儲存草稿)"] + nAW --> nAW5["強制說明 modal(由 Project Leader 設定)"] + nAW --> nAW6["History 標記歷程(誰 / 何時 / 改成什麼)"] + nANN --> nREV["審核員功能(Reviewer)"] + nREV --> nREV1["審查模式(通過 / 退回)"] + nREV --> nREV2["直接修改或刪除錯誤標記"] + nREV --> nREV3["產出 Dry Run 標準答案(多數決 / 手動確認)"] + + %% ── 資料集分析模組 ── + n0 --> nDS["資料集分析模組"] + nDS --> nST["統計總覽頁"] + nST --> nST0["共用指標(Sentence / Token / 完成率)"] + nST --> nST1["分類任務:標籤分佈 / 多標籤共現矩陣"] + nST --> nST2["評分任務:分佈直方圖 / 平均 / 標準差"] + nST --> nST3["NER:實體分佈 / span 長度分佈"] + nST --> nST4["關係抽取:實體 + 關係 + Triple 統計"] + nST --> nST5["生成式:輸出長度分佈 / 評分維度"] + nDS --> nQC["品質監控頁"] + nQC --> nIAA["IAA 計算方法(依任務類型)"] + nIAA --> nIAA1["分類:Cohen's Kappa / Fleiss' Kappa"] + nIAA --> nIAA2["評分:Krippendorff's Alpha / Pearson / Spearman"] + nIAA --> nIAA3["NER:Entity-level F1"] + nIAA --> nIAA4["關係抽取:Triple-level agreement"] + nQC --> nAD["異常偵測"] + nAD --> nAD1["標記速度異常(過快 / 過慢)"] + nAD --> nAD2["離群標記值"] + nQC --> nSPD["標記員個別速度統計"] + + %% ── 標記員管理模組 ── + n0 --> nAMGR["標記員管理模組"] + nAMGR --> nAL["標記員列表頁(啟用 / 停用)"] + nAMGR --> nANW["新增標記員頁(名稱 / Email)"] + nAMGR --> nWL["工時紀錄頁"] + nWL --> nWL1["出缺勤紀錄"] + nWL --> nWL2["任務標記時間(系統自動追蹤)"] + nWL --> nWL3["任務標記數量"] + nWL --> nWL4["工時結算依據(計薪由外部處理)"] + + %% ── 系統管理模組 ── + n0 --> nSYS["系統管理模組(Super Admin)"] + nSYS --> nUM["使用者管理頁(跨專案帳號管理)"] + nSYS --> nRS["角色權限設定頁"] + nRS --> nRS1["project_leader(資料建立者 / 計畫負責人)"] + nRS --> nRS2["annotator(標記員)"] + nRS --> nRS3["reviewer(審核員)"] + nRS --> nRS4["super_admin(系統超級管理員)"] ``` From 0528f1f941cb02db0350a2bac4edb5cfdd49d1b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B3=E6=AC=A3=E6=80=A1?= Date: Thu, 2 Apr 2026 15:30:40 +0800 Subject: [PATCH 4/5] =?UTF-8?q?docs:=20address=20UX=20review=20findings=20?= =?UTF-8?q?=E2=80=94=20task=20types,=20Reviewer=20nav,=20Dry=20Run=20state?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove 生成式標記 task type from all locations (IA + functional map) - Split 單句任務 into Classification and Scoring/Regression (5 task_types total) - Add Reviewer Navbar definition (儀表板 | 標記審查 | 資料集分析) - Clarify Reviewer entry points for annotation-workspace and task-detail (read-only) - Add task status transition chain to task-detail (草稿→Dry Run進行中→等待IAA確認→Official Run進行中→已完成) - Add Dry Run completion notification mechanism (auto status switch + Dashboard badge) - Fix annotation-workspace entry: separate Annotator / Reviewer paths - Fix task-detail export: remove self-loop, clarify as in-page Toast action - Update flowchart: add Reviewer→task-detail read-only edge, Dry Run→Dashboard badge edge - Update Journey A: show state transition and badge notification step - Bump functional map to v3 Co-Authored-By: Claude Sonnet 4.6 --- docs/functional-map/functional-map.md | 31 ++++++++++++++--------- docs/ia/information-architecture.md | 36 ++++++++++++++++----------- 2 files changed, 40 insertions(+), 27 deletions(-) diff --git a/docs/functional-map/functional-map.md b/docs/functional-map/functional-map.md index 247e49a..2d4dacc 100644 --- a/docs/functional-map/functional-map.md +++ b/docs/functional-map/functional-map.md @@ -2,7 +2,7 @@ > **線上版:** [在 XMind 開啟](https://app.xmind.com/share/PKjJEIHD)(線上版可能落後本文件,以本文件為準) > -> **版本:** v2(2026-04-02)— 依 [IA v3](../ia/information-architecture.md) 同步更新 +> **版本:** v3(2026-04-02)— 依 [IA v3](../ia/information-architecture.md) 同步更新 --- @@ -33,8 +33,10 @@ flowchart LR nDAN --> nDAN2["個人進度摘要(今日 / 累計)"] nDAN --> nDAN3["快速繼續按鈕"] nDASH --> nDRV["Reviewer 視角"] - nDRV --> nDRV1["待審查任務列表(待審核筆數)"] + nDRV --> nDRV0["Navbar:儀表板 | 標記審查 | 資料集分析"] + nDRV --> nDRV1["待審查任務列表(點選 → annotation-workspace 審查模式)"] nDRV --> nDRV2["Dry Run IAA 摘要(達標 / 未達標)"] + nDRV --> nDRV3["快速進入審查按鈕(上次未完成任務)"] nDASH --> nDSA["Super Admin 視角"] nDSA --> nDSA1["全局任務 + 標記員進度"] nDSA --> nDSA2["平台使用者角色帳號快覽"] @@ -54,27 +56,33 @@ flowchart LR nTN2A --> nTN2A3["句對:關係類型 / 評分或分類"] nTN2A --> nTN2A4["NER:實體類型清單(名稱+顏色)"] nTN2A --> nTN2A5["關係抽取:實體類型 + 關係類型清單"] - nTN2A --> nTN2A6["生成式:評分維度 / 開放文字"] nTN2 --> nTN2B["Code 模式(進階 YAML/JSON)"] nTN2 --> nTN2C["從範本開始(預設 config 快速套用)"] nTN --> nTN3["Step 3 — 標記說明(選填)"] nTN3 --> nTN3A["上傳說明文件(PDF / 圖片 / 文字)"] nTN3 --> nTN3B["強制顯示設定(進入任務前 modal)"] - nTN --> nTNTYPE["任務類型"] - nTNTYPE --> nTT1["單句任務(分類 / 評分)"] - nTNTYPE --> nTT2["句對任務(相似度 / 蘊含)"] - nTNTYPE --> nTT3["序列標記(NER / 詞性標記)"] - nTNTYPE --> nTT4["關係抽取(Entity + Relation + Triple)"] - nTNTYPE --> nTT5["生成式標記(人工撰寫 / 評分)"] + nTN --> nTNTYPE["任務類型(5 種 task_type)"] + nTNTYPE --> nTT1["單句分類(Classification)"] + nTNTYPE --> nTT2["單句評分 / 回歸(Scoring / Regression)"] + nTNTYPE --> nTT3["句對任務(相似度 / 蘊含)"] + nTNTYPE --> nTT4["序列標記(NER / 詞性標記)"] + nTNTYPE --> nTT5["關係抽取(Entity + Relation + Triple)"] nTASK --> nTD["任務詳情頁"] + nTD --> nTDS["任務狀態轉換"] + nTDS --> nTDS1["草稿 → Dry Run 進行中 → 等待 IAA 確認"] + nTDS --> nTDS2["→ Official Run 進行中 → 已完成"] + nTD --> nTDN["Dry Run 完成通知機制"] + nTDN --> nTDN1["狀態自動切換 → 等待 IAA 確認"] + nTDN --> nTDN2["Dashboard badge 提醒 Project Leader"] nTD --> nTD1["指派標記員(從標記員列表選取)"] nTD --> nTD2["發布 Dry Run(共同樣本 ~20 句)"] nTD --> nTD3["發布 Official Run(IAA ≥ 0.8 後啟動)"] nTD --> nTD4["資料隔離(Dry Run / Official Run 不混用)"] nTD --> nTD5["查看標記進度(各標記員完成數 / 速度)"] - nTD --> nTD6["匯出標記結果"] + nTD --> nTD6["匯出標記結果(Toast 提示下載)"] nTD6 --> nEX1["JSON"] nTD6 --> nEX2["JSON-MIN"] + nTD --> nTDRV["Reviewer 唯讀視角(操作按鈕隱藏)"] %% ── 標記任務模組 ── n0 --> nANN["標記任務模組"] @@ -84,7 +92,7 @@ flowchart LR nDR --> nDR3["討論標記準則直至達標"] nANN --> nOR["正式標記模式(Official Run)"] nOR --> nOR1["分派不重疊資料給各標記員"] - nANN --> nAW["標記作業頁(Annotator)"] + nANN --> nAW["標記作業頁(Annotator / Reviewer)"] nAW --> nAW1["標記操作區"] nAW --> nAW2["說明與範例(側欄)"] nAW --> nAW3["進度指示器(即時完成數)"] @@ -104,7 +112,6 @@ flowchart LR nST --> nST2["評分任務:分佈直方圖 / 平均 / 標準差"] nST --> nST3["NER:實體分佈 / span 長度分佈"] nST --> nST4["關係抽取:實體 + 關係 + Triple 統計"] - nST --> nST5["生成式:輸出長度分佈 / 評分維度"] nDS --> nQC["品質監控頁"] nQC --> nIAA["IAA 計算方法(依任務類型)"] nIAA --> nIAA1["分類:Cohen's Kappa / Fleiss' Kappa"] diff --git a/docs/ia/information-architecture.md b/docs/ia/information-architecture.md index 2c6e0e6..f842bab 100644 --- a/docs/ia/information-architecture.md +++ b/docs/ia/information-architecture.md @@ -91,10 +91,11 @@ flowchart TD TLIST --> TNEW TLIST --> TDETAIL + DASH -->|Reviewer 唯讀| TDETAIL TDETAIL -->|指派 Dry Run| ANNOT TDETAIL -->|指派 Official Run| ANNOT - ANNOT -->|完成標記| TDETAIL - TDETAIL -->|匯出資料| TDETAIL + ANNOT -->|Dry Run 全員完成\n→ Dashboard badge 通知| DASH + ANNOT -->|Official Run 完成標記| TDETAIL ALIST --> ANEW ALIST --> WLOG @@ -142,9 +143,10 @@ flowchart TD - **空狀態(尚未被指派任務):** 說明文字「尚未有指派任務,請等待管理員分配」,次要按鈕:「查看個人工時紀錄」(→ `work-log`)、「編輯個人資料」(→ `profile`) **Reviewer 視角:** -- **待審查任務列表:** 每筆顯示任務名稱、待審核筆數、已審核 / 總筆數 +- **Navbar(Reviewer):** 儀表板 | 標記審查(→ `annotation-workspace` 審查模式)| 資料集分析(→ `dataset-stats`) +- **待審查任務列表:** 每筆顯示任務名稱、待審核筆數、已審核 / 總筆數;點選任務卡 → 直接進入 `annotation-workspace` 審查模式 - **Dry Run IAA 摘要:** 顯示當前 Dry Run 的 IAA 分數(依任務類型顯示對應指標),達標 / 未達標狀態 -- **快速進入審查按鈕:** 直接進入 `annotation-workspace` 審查模式 +- **快速進入審查按鈕:** 進入上次未完成的審查任務(`annotation-workspace`) - **空狀態(目前無待審查任務):** 說明文字,次要按鈕:「查看統計報告」(→ `dataset-stats`) **Super Admin 視角:** @@ -177,23 +179,26 @@ flowchart TD - **句對任務:** 選擇關係類型(相似度 / 蘊含 / 自訂),設定評分或分類標籤 - **序列標記(NER):** 新增 / 編輯實體類型清單(Entity Name + 顏色 + 說明) - **關係抽取:** 設定實體類型清單(同 NER)+ 關係類型清單(Relation Name + 說明),標記介面呈現 Entity List / Relation Type / Triple List 三區 - - **生成式標記:** 設定評分維度(如流暢度 / 正確性)或開放文字輸入 - **Code 模式(進階):** 直接檢視 / 編輯系統產生的 YAML/JSON config 原始碼,供技術人員驗證或手動調整;Visual 與 Code 模式可互相切換 - **Step 3 — 標記說明(選填):** - 上傳標記範本 / 說明文件(PDF / 圖片 / 文字),顯示於 `annotation-workspace` 的「說明與範例」區 - 可設定「開始標記前強制顯示」:Annotator 每次進入任務時先跳出說明 modal,確認後才進入標記介面 -- **任務類型:** - - 單句任務(分類 / 評分) +- **任務類型(共 5 種 `task_type`):** + - 單句分類(Classification) + - 單句評分 / 回歸(Scoring / Regression) - 句對任務(相似度 / 蘊含) - 序列標記(NER、詞性標記) - 關係抽取(Entity + Relation + Triple) - - 生成式標記(人工撰寫 / 評分) - **空狀態:** 不適用(此頁為建立流程,永遠有內容) - **離開方式:** 建立成功 → `task-detail`;取消 → `task-list` #### `task-detail` 任務詳情頁 -- **進入方式:** `task-list` 點選任務 -- **功能:** +- **進入方式(Project Leader):** `task-list` 點選任務 +- **進入方式(Reviewer):** `dashboard` 待審查任務列表 → 任務卡(唯讀視角;指派、發布、匯出等操作按鈕隱藏) +- **任務狀態轉換:** + - `草稿` → `Dry Run 進行中` → `等待 IAA 確認` → `Official Run 進行中` → `已完成` + - **Dry Run 完成通知:** 當所有標記員完成 Dry Run 後,系統自動將任務狀態切換至「等待 IAA 確認」,並在 Dashboard 待處理事項區新增 badge 提醒 Project Leader;Project Leader 從 badge 連結進入 `dataset-quality` 查看 IAA 結果 +- **功能(Project Leader):** - 查看任務設定與任務類型 - 指派標記員(從 `annotator-list` 選取) - 發布試標(Dry Run):選取共用樣本集(建議 20 句),發布給所有標記員 @@ -201,14 +206,15 @@ flowchart TD - 查看標記進度(各標記員完成數 / 速度) - 匯出標記結果(JSON / JSON-MIN) - **資料隔離原則:** Dry Run 資料與 Official Run 資料必須隔離,不得混入正式標記集 -- **離開方式:** 「開始標記」→ `annotation-workspace`;返回 → `task-list` +- **離開方式:** 返回 → `task-list`;匯出為頁面內操作(Toast 提示下載),不觸發頁面跳轉 --- ### 標記任務模組 #### `annotation-workspace` 標記作業頁 -- **進入方式:** `dashboard` 任務卡片;`task-detail` 指派後 +- **進入方式(Annotator):** `dashboard` 任務卡片「開始 / 繼續標記」按鈕;快速繼續按鈕 +- **進入方式(Reviewer):** `dashboard` 待審查任務列表中的任務卡;Navbar → 標記審查 - **兩種模式(run_type):** - **Dry Run(試標):** 所有標記員標記相同樣本,結果不計入正式資料,用於計算 IAA 與討論標記準則 - **Official Run(正式標記):** 每位標記員分配不重疊的資料,結果計入正式資料集 @@ -233,7 +239,6 @@ flowchart TD - **序列標記(NER):** 實體類型分佈、每句平均實體數、Entity span 長度分佈 - **關係抽取:** 實體類型分佈 + 關係類型分佈、Triple 數量統計 - **句對任務:** 依標籤或分數呈現(同分類 / 評分) - - **生成式標記:** 輸出文字長度分佈;若含評分維度則同評分任務 - **空狀態(尚無標記資料):** 說明文字「尚無標記資料,請先發布 Dry Run」,次要按鈕「前往任務詳情」(→ `task-detail`) - **離開方式:** 切換至 `dataset-quality` @@ -311,8 +316,9 @@ sequenceDiagram PL->>AL: 新增標記員帳號 PL->>TD: 指派標記員 + 發布 Dry Run(共同樣本 ~20 句) Note over AW: 所有標記員標記相同樣本 - AW-->>TD: 試標完成通知 - PL->>DQ: 查看 IAA 結果 + AW-->>TD: 任務狀態切換 → 等待 IAA 確認 + TD-->>PL: Dashboard 待處理事項 badge:「Dry Run 已全員完成」 + PL->>DQ: 從 badge 連結進入,查看 IAA 結果 alt IAA ≥ 0.8 PL->>TD: 確認標記準則,發布 Official Run Note over AW: 各標記員分配不重疊資料 From 97eb2646324fa54c777127bb12cca3f405ac4b61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=B3=E6=AC=A3=E6=80=A1?= Date: Thu, 2 Apr 2026 15:45:44 +0800 Subject: [PATCH 5/5] fix: address PR #18 review findings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - §1 Annotator: add 標記員管理模組(僅自己的工時)to accessible modules - §1 Project Leader: remove 標記任務(唯讀)— contradicted by §2 access matrix (❌) - §3 nav diagram: add DASH→WLOG edge for Annotator personal path - specs/001-sso-login: replace GitHub OAuth with Email/Password throughout - Process flow: add email/password branch in sequence diagram - Step table: split step 2 into 2a (Google) / 2b (Email/Password) - User Story 1: update acceptance criteria for both login methods - User Story 2: remove GitHub scenario, add admin-created email account - Edge cases: replace GitHub no-email case with forgot-password policy - FR-001/FR-002: remove GitHub, add bcrypt password validation - Entity model: provider=(google|email), add hashed_password field, update role enum - SC-009: replace GitHub provider merge with email/password provider merge Co-Authored-By: Claude Sonnet 4.6 --- docs/ia/information-architecture.md | 5 +- specs/001-sso-login/spec.md | 85 ++++++++++++++++------------- 2 files changed, 49 insertions(+), 41 deletions(-) diff --git a/docs/ia/information-architecture.md b/docs/ia/information-architecture.md index f842bab..d29b29a 100644 --- a/docs/ia/information-architecture.md +++ b/docs/ia/information-architecture.md @@ -11,8 +11,8 @@ | 角色 | 識別碼 | 主要職責 | 可存取模組 | |------|--------|----------|------------| -| 資料建立者 / 計畫負責人 | `project_leader` | 建立任務、管理標記員、監控進度、設定試標與正式標、匯出資料 | 儀表板(全局)、任務管理、標記任務(唯讀)、資料集分析、標記員管理 | -| 標記員 | `annotator` | 執行標記作業(試標 / 正式標)、查看個人進度 | 儀表板(個人)、帳號模組、標記任務模組 | +| 資料建立者 / 計畫負責人 | `project_leader` | 建立任務、管理標記員、監控進度、設定試標與正式標、匯出資料 | 儀表板(全局)、任務管理、資料集分析、標記員管理 | +| 標記員 | `annotator` | 執行標記作業(試標 / 正式標)、查看個人進度 | 儀表板(個人)、帳號模組、標記任務模組、標記員管理模組(僅自己的工時) | | 審核員 | `reviewer` | 審查標記結果、協助產出標準答案、查看品質報告 | 儀表板、標記任務模組(審查模式)、資料集分析模組 | | 系統超級管理員 | `super_admin` | 平台維護、跨專案使用者管理、帳號與角色設定 | 全部模組 + 系統管理模組 | @@ -87,6 +87,7 @@ flowchart TD DASH --> STATS DASH --> ALIST + DASH -->|Annotator 個人| WLOG DASH --> USERS TLIST --> TNEW diff --git a/specs/001-sso-login/spec.md b/specs/001-sso-login/spec.md index e59b6ad..feaf72f 100644 --- a/specs/001-sso-login/spec.md +++ b/specs/001-sso-login/spec.md @@ -3,7 +3,7 @@ **功能分支**:`001-sso-login` **建立日期**:2026-03-25 **狀態**:Clarified -**需求來源**:「先做一個簡單的登入畫面,需要串接 Google、GitHub 登入的 SSO 功能」 +**需求來源**:「先做一個簡單的登入畫面,需要串接 Google SSO 與 Email / Password 登入」 ## Process Flow @@ -21,16 +21,21 @@ sequenceDiagram 瀏覽器->>後端API: GET /login(未驗證) 後端API-->>瀏覽器: 回傳登入頁面 - 使用者->>瀏覽器: 點擊「以 Google / GitHub 登入」 - 瀏覽器->>OAuthProvider: 導向授權頁(client_id、redirect_uri) - OAuthProvider-->>使用者: 顯示授權請求 - 使用者->>OAuthProvider: 允許授權 - - OAuthProvider->>後端API: callback(authorization code) - 後端API->>OAuthProvider: 交換 access token - OAuthProvider-->>後端API: access token - 後端API->>OAuthProvider: 取得使用者資料 - OAuthProvider-->>後端API: name、email、avatar + alt Google SSO 登入 + 使用者->>瀏覽器: 點擊「以 Google 登入」 + 瀏覽器->>OAuthProvider: 導向授權頁(client_id、redirect_uri) + OAuthProvider-->>使用者: 顯示授權請求 + 使用者->>OAuthProvider: 允許授權 + OAuthProvider->>後端API: callback(authorization code) + 後端API->>OAuthProvider: 交換 access token + OAuthProvider-->>後端API: access token + 後端API->>OAuthProvider: 取得使用者資料 + OAuthProvider-->>後端API: name、email、avatar + else Email / Password 登入 + 使用者->>瀏覽器: 填寫 Email + Password,點擊登入 + 瀏覽器->>後端API: POST /auth/login(email、password) + 後端API->>後端API: 驗證密碼雜湊 + end 後端API->>資料庫: 查詢或建立使用者記錄(以 email 比對) 資料庫-->>後端API: User record 後端API-->>瀏覽器: 設定 JWT cookie + 導向 /dashboard @@ -39,51 +44,53 @@ sequenceDiagram | 步驟 | 角色 | 動作 | 系統回應 | |------|------|------|---------| | 1 | 使用者 | 開啟 `/login` | 回傳登入頁面 | -| 2 | 使用者 | 點擊 OAuth 按鈕 | 導向 Provider 授權頁 | -| 3 | OAuth Provider | 使用者授權後回調 | 後端接收 `code` | -| 4 | 後端 | 交換 token + 取得資料 | 查詢或建立 User 記錄 | -| 5 | 後端 | 簽發 JWT | 導向 `/dashboard` | -| E1 | 使用者 | 取消授權 | 停留 `/login` 並顯示錯誤 | -| E2 | 後端 | JWT 過期 | 導向 `/login`,不靜默更新 | +| 2a | 使用者 | 點擊「以 Google 登入」 | 導向 Google 授權頁 | +| 2b | 使用者 | 填寫 Email / Password 並送出 | 後端驗證密碼雜湊 | +| 3 | OAuth Provider / 後端 | 驗證完成 | 查詢或建立 User 記錄 | +| 4 | 後端 | 簽發 JWT | 導向 `/dashboard` | +| E1 | 使用者 | 取消 Google 授權 | 停留 `/login` 並顯示錯誤 | +| E2 | 使用者 | Email / Password 錯誤 | 停留 `/login` 並顯示錯誤訊息 | +| E3 | 後端 | JWT 過期 | 導向 `/login`,不靜默更新 | --- ## 使用者情境與測試 *(必填)* -### User Story 1 — 使用 Google 或 GitHub 登入(優先級:P1) +### User Story 1 — 登入(Google SSO 或 Email / Password)(優先級:P1) 使用者(研究生或工讀生)進入 Label Suite 入口,看到簡潔的登入頁面。 -點擊「以 Google 登入」或「以 GitHub 登入」,完成 OAuth 流程後, +可選擇點擊「以 Google 登入」完成 OAuth 流程,或直接填寫 Email / Password 送出, 系統完成身份驗證並導向儀表板。 -**此優先級原因**:身份驗證是所有功能的入口,沒有登入就無法使用任何功能。Google 與 GitHub 是目標使用者(NLP 研究者與工程師)最熟悉的兩個身份提供者。 +**此優先級原因**:身份驗證是所有功能的入口,沒有登入就無法使用任何功能。Google SSO 提供便利性;Email / Password 提供不依賴 Google 帳號的備用方案。 -**獨立測試方式**:進入 `/login`,點擊身份提供者按鈕,完成 OAuth,驗證導向 `/dashboard` 並存有有效 session token。 +**獨立測試方式**:進入 `/login`,分別測試 Google SSO 路徑與 Email / Password 路徑,驗證兩者均可導向 `/dashboard` 並存有有效 session token。 **驗收情境**: 1. **Given** 未登入使用者在 `/login`,**When** 點擊「以 Google 登入」並完成 Google OAuth,**Then** 導向 `/dashboard` 且 session token 已儲存。 -2. **Given** 未登入使用者在 `/login`,**When** 點擊「以 GitHub 登入」並完成 GitHub OAuth,**Then** 導向 `/dashboard` 且 session token 已儲存。 -3. **Given** 使用者取消或拒絕 OAuth 授權,**When** 被導回,**Then** 停留在 `/login` 並顯示明確的錯誤訊息。 -4. **Given** 已登入使用者,**When** 導向 `/login`,**Then** 自動導向 `/dashboard`。 +2. **Given** 未登入使用者在 `/login`,**When** 填寫正確的 Email / Password 並送出,**Then** 導向 `/dashboard` 且 session token 已儲存。 +3. **Given** 未登入使用者在 `/login`,**When** 填寫錯誤的 Email 或 Password,**Then** 停留在 `/login` 並顯示明確的錯誤訊息(不揭露哪個欄位錯誤)。 +4. **Given** 使用者取消或拒絕 Google OAuth 授權,**When** 被導回,**Then** 停留在 `/login` 並顯示明確的錯誤訊息。 +5. **Given** 已登入使用者,**When** 導向 `/login`,**Then** 自動導向 `/dashboard`。 --- ### User Story 2 — 首次使用者帳號建立(優先級:P2) -從未登入過的使用者透過 Google 或 GitHub 完成身份驗證。 -系統自動使用身份提供者的個人資料(姓名、Email、頭像)建立新帳號, -不需要額外填寫任何註冊表單。 +從未登入過的使用者透過 Google SSO 完成身份驗證。 +系統自動使用 Google 個人資料(姓名、Email、頭像)建立新帳號, +不需要額外填寫任何註冊表單。Email / Password 帳號由 Project Leader 或 Super Admin 預先建立並提供初始密碼。 -**此優先級原因**:流暢的首次使用體驗很重要,但核心登入流程(P1)必須先完成。自動開通帳號可降低新使用者的操作摩擦。 +**此優先級原因**:流暢的首次使用體驗很重要,但核心登入流程(P1)必須先完成。自動開通帳號可降低 Google 使用者的操作摩擦。 -**獨立測試方式**:以新的 OAuth 身份登入,驗證資料庫中建立了正確個人資料的使用者記錄。 +**獨立測試方式**:以新的 Google 帳號登入,驗證資料庫中建立了正確個人資料的使用者記錄。 **驗收情境**: 1. **Given** 首次使用者完成 Google OAuth,**When** callback 處理完成,**Then** 建立包含 Google 個人資料的 `name`、`email`、`avatar_url` 使用者記錄。 -2. **Given** 首次使用者完成 GitHub OAuth,**When** callback 處理完成,**Then** 建立包含 `login`、`email`(若為公開)、`avatar_url` 的使用者記錄。 -3. **Given** 回訪使用者(email 已存在),**When** 再次登入,**Then** 不建立重複帳號,回傳既有帳號的 session。 +2. **Given** 回訪使用者(email 已存在),**When** 再次以 Google 登入,**Then** 不建立重複帳號,回傳既有帳號的 session。 +3. **Given** Email / Password 帳號已由管理員建立,**When** 使用者首次以正確密碼登入,**Then** 回傳既有帳號的 session。 --- @@ -123,17 +130,17 @@ sequenceDiagram ### 邊界情況 -- OAuth 身份提供者暫時無法使用時?→ 在登入頁顯示友善的錯誤訊息。 -- GitHub 使用者沒有公開 Email 時?→ 使用 GitHub username 建立帳號,email 欄位為 null。 -- 相同 Email 同時連結 Google 與 GitHub 時?→ 靜默合併(silent merge):視為同一帳號(以 email 比對),兩個 provider 均可登入同一使用者記錄,不需使用者確認。 +- Google OAuth 暫時無法使用時?→ 在登入頁顯示友善的錯誤訊息,提示使用 Email / Password 替代登入。 +- Email / Password 帳號忘記密碼時?→ 由 Super Admin 在後台重設密碼(系統不實作自助重設流程,避免 SMTP 依賴)。 +- 相同 Email 同時存在 Google 帳號與 Email/Password 帳號時?→ 靜默合併:視為同一帳號(以 email 比對),兩種登入方式均可進入同一使用者記錄,不需使用者確認。 - JWT 在工作階段中途過期時?→ 導向 `/login`,不進行靜默更新(silent refresh),使用者必須重新驗證。 ## 需求規格 *(必填)* ### 功能需求 -- **FR-001**:系統必須提供含「以 Google 登入」與「以 GitHub 登入」按鈕的 `/login` 頁面。 -- **FR-002**:系統必須對 Google 與 GitHub 實作 OAuth 2.0 授權碼流程。 +- **FR-001**:系統必須提供含「以 Google 登入」按鈕與 Email / Password 表單的 `/login` 頁面。 +- **FR-002**:系統必須對 Google 實作 OAuth 2.0 授權碼流程;並對 Email / Password 實作密碼雜湊驗證(bcrypt)。 - **FR-003**:系統必須在成功驗證後簽發 JWT session token。 - **FR-004**:系統必須在首次登入時使用身份提供者個人資料自動開通使用者記錄。 - **FR-005**:系統必須將已登入使用者從 `/login` 導向 `/dashboard`。 @@ -175,8 +182,8 @@ flowchart LR ### 關鍵實體 -- **User(使用者)**:代表已驗證身份。關鍵屬性:`id`、`email`、`name`、`avatar_url`、`provider`(google | github)、`provider_id`、`role`(annotator | researcher | admin)、`created_at`。 - - 首次登入預設 `role = annotator`。角色升級(researcher / admin)須由既有 admin 透過管理介面執行。 +- **User(使用者)**:代表已驗證身份。關鍵屬性:`id`、`email`、`name`、`avatar_url`、`provider`(google | email)、`provider_id`(Google 帳號 ID,Email/Password 帳號為 null)、`hashed_password`(Email/Password 帳號用,Google 帳號為 null)、`role`(annotator | project_leader | reviewer | super_admin)、`created_at`。 + - 首次 Google 登入預設 `role = annotator`。Email / Password 帳號建立時由管理員指定角色。 - **Session / JWT**:OAuth callback 成功後簽發的短效存取 token。包含 `user_id`、`role`、`exp`。過期後系統導向 `/login`,不進行靜默更新。 ## 成功標準 *(必填)* @@ -189,4 +196,4 @@ flowchart LR - **SC-006**:登出後,已失效的 JWT 被所有受保護 API 端點拒絕(回傳 HTTP 401)。 - **SC-007**:登入頁面正確顯示 zh-TW 與 en 兩種語言;語言切換立即生效,不需重新載入頁面。 - **SC-008**:執行資料庫 migration 後,全新部署環境中存在一個預設 admin 帳號。 -- **SC-009**:使用者以 Google 登入後,再以相同 email 的 GitHub 登入,最終只有一筆使用者記錄並連結兩個 provider。 +- **SC-009**:使用者以 Google 登入後,再以相同 email 的 Email / Password 登入,最終只有一筆使用者記錄並連結兩個 provider。