方法論概述

這裡嘗試以 Ticket 設計和派工機制,解決大型開發任務的協作效率問題,特別是工作日誌臃腫和實作偏差風險。

但是這篇方法論太長了,之後會分拆成多個方法論方便閱讀

適用場景

  • 多人協作開發
  • 大型功能模組開發
  • 需要精細進度追蹤的專案
  • 需要即時 review 機制的團隊

核心目標

  • 建立量化的 Ticket 拆分標準
  • 定義完整的 Ticket 生命週期
  • 建立即時 Review 機制
  • 避免工作日誌臃腫

方法論版本:v1.0.0


第一章:Ticket 機制核心原則

1.1 Ticket vs 工作日誌的定位差異

Ticket 定義

Ticket 是「最小可交付單元」(Minimal Deliverable Unit),代表一個可以獨立完成、驗收和追蹤的最小任務單位。

核心特徵

  • 獨立性:可以獨立執行和驗收
  • 原子性:不可再分割為更小的可交付單元
  • 可驗證性:有明確的完成標準
  • 複雜度限制:基於職責、檔案、測試、行數的量化標準

工作日誌定義

工作日誌是記錄整個開發過程的完整文檔,包含設計決策、實作細節、問題分析和解決方案。

核心特徵

  • 完整性:記錄所有決策和過程
  • 追溯性:提供歷史記錄和演進軌跡
  • 知識傳承:為後續開發者提供上下文

定位差異總結

維度Ticket工作日誌
範圍單一具體任務整個功能模組或版本
粒度最小可交付單元(單一職責或少數相關職責)完整開發週期(數天到數週)
目的任務執行和驗收知識記錄和傳承
更新頻率執行中持續更新階段性更新
文件大小100-200 行500-6000 行
適用場景協作開發、進度追蹤決策記錄、技術傳承

互補關係

Ticket 和工作日誌是互補關係:

  • Ticket 負責「執行層面」:將大任務拆分為可管理的小單元
  • 工作日誌 負責「記錄層面」:記錄決策過程和演進軌跡
  • 主版本日誌 負責「總覽層面」:提供任務總覽和 Ticket 索引

1.2 Ticket 機制的三大目標

目標 1:可追溯性(Traceability)

定義:每個 Ticket 都有明確的來源和目標,可以追溯到需求、設計文件或問題報告。

實現方式

  • Ticket 必須包含「參考文件」欄位,連結到需求規格或設計文件
  • Ticket 必須包含「背景」欄位,說明為什麼需要這個 Ticket
  • 主版本日誌維護完整的 Ticket 索引

範例

1### 參考文件
2- v0.12.7-design-decisions.md #決策1
3- docs/app-requirements-spec.md #UC-01
4
5### 背景
6根據 UC-01 需求,需要建立書籍資訊豐富化服務的介面契約

效益

  • 開發者清楚知道「為什麼」要做這個任務
  • PM 可以追蹤每個 Ticket 的需求來源
  • 後續維護者可以理解設計意圖

目標 2:可驗收性(Verifiability)

定義:每個 Ticket 都有明確、可驗證的完成標準,避免主觀判斷。

實現方式

  • Ticket 必須包含「驗收條件」欄位,列出所有可驗證的條件
  • 驗收條件必須是客觀可檢查的(檔案存在、測試通過、功能運作)
  • Review 時逐項檢查驗收條件

範例

1### 驗收條件
2- [ ] 介面檔案建立在 `lib/domains/import/services/` 目錄
3- [ ] `enrichBook` 方法簽名完整且明確
4- [ ] 輸入輸出類型定義清楚
5- [ ] 包含完整的文檔註解
6- [ ] dart analyze 0 錯誤

效益

  • 避免「看起來完成了」但實際未達標準
  • 提供明確的驗收依據
  • 減少 review 時的主觀爭議

目標 3:可協作性(Collaborability)

定義:多個開發者可以並行執行不同的 Ticket,互不阻塞。

實現方式

  • Ticket 拆分時考慮依賴關係,最小化依賴
  • 明確標註 Ticket 間的依賴關係(必須先完成 / 可並行)
  • 使用 Interface-Driven 開發,內層未完成也可開發外層

範例

1### 依賴 Ticket
2- Ticket #1: 定義 IBookInfoEnrichmentService 介面(必須先完成)
3- Ticket #3: 撰寫 EnrichmentProgress 測試(可並行)

效益

  • 多人可同時開發不同模組
  • 減少等待時間
  • 提升開發效率

1.3 基於 Clean Architecture 的 Ticket 設計哲學

Clean Architecture 核心原則回顧

依賴方向規則

  • 外層依賴內層,內層不依賴外層
  • 所有依賴都指向內層(Domain)

分層定義

  • Entities(Domain):核心業務邏輯
  • Use Cases(Application):應用業務規則
  • Interface Adapters(Presentation/Infrastructure):轉接層
  • Frameworks & Drivers(External):外部實作

Ticket 設計對應 Clean Architecture

原則 1:Interface 定義優先於具體實作

每個功能模組的開發順序:

  1. 先定義 Interface(Ticket 類型:Interface 定義)
  2. 再實作具體邏輯(Ticket 類型:具體實作)

範例

1Ticket #1: 定義 IBookRepository 介面
23Ticket #2: 實作 SQLiteBookRepository(依賴 #1)

好處

  • 外層可依賴 Interface 先行開發(使用 Mock)
  • 內層實作延後,不阻塞外層開發
  • 符合 Dependency Inversion Principle
原則 2:測試驅動 Ticket 拆分

每個實作 Ticket 都應該有對應的測試 Ticket:

  1. Interface 定義 Ticket → 定義契約
  2. 測試撰寫 Ticket → 驗證契約
  3. 具體實作 Ticket → 實現契約
  4. 整合驗證 Ticket → 確認整合

範例

1Ticket #1: 定義 IBookRepository 介面
23Ticket #2: 撰寫 BookRepository 測試
45Ticket #3: 實作 SQLiteBookRepository
67Ticket #4: 整合測試驗證

好處

  • 測試先行,確保需求清晰
  • 實作以測試為目標,不過度設計
  • 整合驗證確保模組間正確協作
原則 3:分層拆分 Ticket

基於 Clean Architecture 分層,將任務拆分為不同層次的 Ticket:

Domain 層 Ticket

  • 定義 Entity
  • 定義 Value Object
  • 定義 Domain Event
  • 定義 Repository Interface

Application 層 Ticket

  • 定義 Use Case Interface
  • 實作 Use Case Interactor
  • 定義 Input/Output Port

Infrastructure 層 Ticket

  • 實作 Repository
  • 實作 External Service
  • 實作 Database Mapper

Presentation 層 Ticket

  • 實作 Controller/Presenter
  • 實作 ViewModel
  • 實作 UI Component

好處

  • 職責清晰,不跨層混合
  • 符合 Clean Architecture 分層原則
  • 易於並行開發

1.4 Ticket 機制與 TDD 階段的關係

TDD 階段回顧

  • Phase 1:功能設計(設計 Interface、規劃架構)
  • Phase 2:測試設計(撰寫測試案例)
  • Phase 3:實作執行(實作功能、通過測試)
  • Phase 4:重構優化(改善品質、消除技術債務)

Ticket 與 TDD 階段對應

Phase 1 產出的 Ticket

Phase 1 設計階段產出「Interface 定義 Ticket」:

  • 定義 Domain Interface
  • 定義 Use Case Interface
  • 定義 Input/Output Port

特徵

  • 無具體實作,只有介面簽名
  • 明確定義輸入輸出
  • 建立契約規範

Phase 2 產出的 Ticket

Phase 2 測試設計階段產出「測試撰寫 Ticket」:

  • 撰寫 Entity 測試
  • 撰寫 Use Case 測試
  • 撰寫 Repository 測試

特徵

  • 測試先行,定義預期行為
  • 覆蓋所有 Interface 方法
  • 包含正常流程和異常處理

Phase 3 產出的 Ticket

Phase 3 實作階段產出「具體實作 Ticket」:

  • 實作 Entity 邏輯
  • 實作 Use Case Interactor
  • 實作 Repository

特徵

  • 以測試通過為目標
  • 最小可行實作
  • 100% 測試通過

Phase 4 產出的 Ticket

Phase 4 重構階段產出「品質改善 Ticket」:

  • 重構複雜邏輯
  • 消除程式異味
  • 改善錯誤處理

特徵

  • 保持測試通過
  • 改善程式品質
  • 不新增功能

Ticket 機制支援 TDD 流程

支援 1:明確的階段產出

每個 TDD Phase 都產出對應的 Ticket 類型,職責清晰。

支援 2:可並行執行

Phase 1 完成後,多個開發者可並行執行 Phase 2-3 的不同 Ticket。

支援 3:即時 Review

每完成一個 Ticket 觸發 review,確保品質。


第二章:Ticket 拆分標準

2.1 量化指標定義

為了確保 Ticket 拆分的一致性和可操作性,定義以下 4 個量化指標

核心原則**:**基於客觀的工作內容評估

  • 職責數量:最客觀,不受個人能力影響- 程式碼行數:可量化,可驗證- 檔案數量:架構層級指標- 測試數量:品質保證指標

指標 1:職責數量(Responsibilities)(最優先)

定義:Ticket 需要完成的獨立職責數量。

標準

  • 簡單 Ticket:1 個明確職責
  • 中等 Ticket:2-3 個相關職責
  • 複雜 Ticket:3-5 個相關職責
  • 超過 5 個職責:必須拆分

識別方式

  • 每個「需要實作的功能點」算一個職責
  • 每個「需要驗證的邊界條件」算一個職責
  • 每個「需要處理的錯誤情境」算一個職責

範例

  • 簡單(1 職責):定義 SelectionManager 介面方法簽名
  • 中等(2-3 職責)
    • 職責 1: 實作 toggleSelection 方法
    • 職責 2: 實作 clearSelection 方法
    • 職責 3: 通知狀態變更(ChangeNotifier)
  • 複雜(3-5 職責)
    • 職責 1: Repository CRUD 實作
    • 職責 2: Data Mapper 轉換
    • 職責 3: 錯誤處理
    • 職責 4: Cache 管理
    • 職責 5: 單元測試

為什麼職責是第一指標

  • 最客觀:不受個人能力影響- 最穩定:不受環境和參考資料影響- 最易溝通:PM 和工程師都能理解

指標 2:程式碼行數(Lines of Code)

定義:Ticket 涉及的程式碼修改行數(新增 + 修改 + 刪除)。

標準

  • 簡單 Ticket:< 30 行
  • 中等 Ticket:30-50 行
  • 複雜 Ticket:50-100 行
  • 超過 100 行:必須拆分

測量方式

  • 使用 git diff --stat 統計
  • 包含新增、修改、刪除的行數總和
  • 不包含空行和註解

範例

  • 簡單:定義 Interface(~20 行)
  • 中等:實作 Value Object(~40 行)
  • 複雜:實作 Repository(~80 行)

指標 3:涉及檔案數(Files)

定義:Ticket 需要修改的檔案數量。

標準

  • 簡單 Ticket:1 個檔案
  • 中等 Ticket:2-3 個檔案
  • 複雜 Ticket:3-5 個檔案
  • 超過 5 個檔案:必須拆分

測量方式

  • 計算 git diff --name-only 的檔案數
  • 包含新建檔案
  • 不包含測試檔案(測試檔案另計)

範例

  • 簡單:新建一個 Interface 檔案(1 個)
  • 中等:修改 Entity 和 Repository Interface(2 個)
  • 複雜:實作 Use Case,修改 Interactor、Input Port、Output Port(3 個)

指標 4:測試用例數(Tests)

定義:Ticket 對應的測試用例數量。

標準

  • 簡單 Ticket:1-3 個測試
  • 中等 Ticket:3-5 個測試
  • 複雜 Ticket:5-10 個測試
  • 超過 10 個測試:必須拆分

測量方式

  • 計算 test 檔案中的測試方法數
  • 包含單元測試和整合測試
  • 每個 test('...', () {...}) 算一個

範例

  • 簡單:測試 Value Object 的建立和驗證(2 個測試)
  • 中等:測試 Repository 的 CRUD 操作(4 個測試)
  • 複雜:測試 Use Case 的正常流程和異常處理(8 個測試)

2.2 任務複雜度評估方法

基於 4 個量化指標,定義任務複雜度評估方法:

複雜度等級定義

等級職責檔案測試行數描述
簡單1 個1 個1-3 個< 30 行單一職責,單一檔案
中等2-3 個2-3 個3-6 個30-70 行少數職責,少數檔案
複雜3-5 個3-5 個6-10 個70-100 行多職責,多檔案
需拆分> 5 個> 5 個> 10 個> 100 行任一指標超標必須拆分

評估方法

步驟 1:初步評估

  • 根據任務描述,估算 4 個指標
  • 取最高的複雜度等級作為初步評估結果
步驟 2:複雜度確認
  • 如果初步評估為「需拆分」,必須拆分
  • 如果初步評估為「複雜」,檢查是否可拆分為「簡單」或「中等」
  • 如果初步評估為「中等」或「簡單」,可直接建立 Ticket
步驟 3:拆分決策
  • 優先拆分為「簡單」Ticket(單一職責、單一檔案)
  • 無法拆分為「簡單」時,拆分為「中等」Ticket(2-3 職責)
  • 避免建立「複雜」Ticket(3-5 職責),除非無法再拆分

2.3 基於 Clean Architecture 分層的拆分策略

基於 Clean Architecture 的分層原則,定義 4 種標準拆分策略:

策略 1:Interface 定義 Ticket

目的:定義一個介面及其輸入輸出契約。

範圍

  • 定義 Interface 簽名
  • 定義輸入參數類型
  • 定義回傳類型
  • 撰寫文檔註解

範例

 1## Ticket #1: 定義 IBookRepository 介面
 2
 3### 目標
 4建立 `IBookRepository` 介面,定義書籍資料存取的契約
 5
 6### 步驟
 71.`lib/domains/library/repositories/` 建立 `i_book_repository.dart`
 82. 定義 `getBookByIsbn` 方法簽名
 93. 定義 `saveBook` 方法簽名
104. 定義 `deleteBook` 方法簽名
115. 撰寫文檔註解
12
13### 驗收條件
14- [ ] Interface 檔案建立在正確位置
15- [ ] 3 個方法簽名完整且明確
16- [ ] 輸入輸出類型定義清楚
17- [ ] 包含完整的文檔註解
18- [ ] dart analyze 0 錯誤

策略 2:具體實作 Ticket

目的:實作一個類別的核心邏輯。

範圍

  • 實作類別邏輯
  • 實現介面方法
  • 處理異常
  • 確保測試通過

範例

 1## Ticket #2: 實作 SQLiteBookRepository
 2
 3### 目標
 4實作 `SQLiteBookRepository`,提供書籍資料的 SQLite 儲存
 5
 6### 步驟
 71. 建立 `SQLiteBookRepository` 類別
 82. 實作 `getBookByIsbn` 方法
 93. 實作 `saveBook` 方法
104. 實作 `deleteBook` 方法
115. 處理 SQLite 異常
126. 確保所有測試通過
13
14### 驗收條件
15- [ ] 實作所有 IBookRepository 方法
16- [ ] 異常處理完整(Database Exception)
17- [ ] 單元測試 100% 通過
18- [ ] dart analyze 0 錯誤
19
20### 依賴 Ticket
21- Ticket #1: 定義 IBookRepository 介面(必須先完成)

策略 3:測試驗證 Ticket

目的:撰寫一組相關的測試用例。

範圍

  • 撰寫單元測試
  • 覆蓋正常流程
  • 覆蓋異常處理
  • 確保測試通過

範例

 1## Ticket #3: 撰寫 BookRepository 測試
 2
 3### 目標
 4撰寫 `BookRepository` 的完整測試用例
 5
 6### 步驟
 71. 建立測試檔案 `book_repository_test.dart`
 82. 撰寫 `getBookByIsbn` 測試(正常流程 + 不存在情況)
 93. 撰寫 `saveBook` 測試(新增 + 更新)
104. 撰寫 `deleteBook` 測試(存在 + 不存在)
115. 確保所有測試通過
12
13### 驗收條件
14- [ ] 測試檔案建立在 `test/unit/domains/library/repositories/`
15- [ ] 至少 6 個測試用例
16- [ ] 覆蓋正常流程和異常處理
17- [ ] 所有測試 100% 通過
18
19### 依賴 Ticket
20- Ticket #1: 定義 IBookRepository 介面(必須先完成)

策略 4:整合連接 Ticket

目的:連接兩個模組並驗證整合。

範圍

  • 連接 Use Case 和 Repository
  • 實作依賴注入
  • 撰寫整合測試
  • 驗證端到端流程

範例

 1## Ticket #4: 整合 BookRepository 到 GetBookUseCase
 2
 3### 目標
 4`BookRepository` 整合到 `GetBookUseCase`,實現完整流程
 5
 6### 步驟
 71. 修改 `GetBookInteractor` 注入 `IBookRepository`
 82.`execute` 方法中呼叫 `repository.getBookByIsbn`
 93. 處理 Repository 異常
104. 撰寫整合測試驗證端到端流程
115. 確保所有測試通過
12
13### 驗收條件
14- [ ] `GetBookInteractor` 正確注入 `IBookRepository`
15- [ ] 端到端流程正常運作
16- [ ] 整合測試 100% 通過
17- [ ] 異常處理完整
18
19### 依賴 Ticket
20- Ticket #2: 實作 SQLiteBookRepository(必須先完成)

2.4 Code Smell 品質閘門檢測

本節整合 v0.12.G.2「Code Smell 檢查清單」到 Ticket 設計流程,實現「設計階段就能發現 Code Smell」的品質管理策略。

整合目標:

  • 在 Ticket 設計階段執行 Code Smell 檢測
  • 降低修正成本(設計階段 vs 實作後修正)
  • 提供明確的 Ticket 設計品質標準
  • 實現預防勝於治療的品質管理

引用方法論:

  • 引用 v0.12.G.1「層級隔離派工方法論」的五層架構和單層修改原則
  • 引用 v0.12.G.2「Code Smell 檢查清單」的 C 類 Code Smell 檢測方法

2.4.1 品質閘門機制概述

品質閘門定義:

品質閘門(Quality Gate)是 Ticket 設計階段的強制檢查點,確保 Ticket 符合 Code Smell 品質標準後才能進入執行階段。

 1Ticket 設計流程整合品質閘門:
 2
 3Phase 1: 功能設計(lavender-interface-designer)
 4 5  1. 撰寫 Ticket 清單
 6  2. 定義驗收條件
 7  3. 規劃步驟和檔案
 8 9【品質閘門檢測】← 新增檢測點
10  ├─ C1. God Ticket 檢測
11  ├─ C2. Incomplete Ticket 檢測
12  └─ C3. Ambiguous Responsibility 檢測
1314  通過 → Phase 2: 測試驗證
15  未通過 → 修正 Ticket → 重新檢測

檢測時機:

檢測時機說明執行者
Ticket 撰寫完成後所有 Ticket 的內容(背景、目標、步驟、驗收條件)都已撰寫完成lavender-interface-designer
分派執行前在將 Ticket 分派給開發者執行前,必須先通過品質閘門lavender-interface-designer
PM 審查前PM 審查時,品質閘門檢測報告是重要參考依據lavender-interface-designer

檢測執行者:

責任歸屬: lavender-interface-designer(TDD Phase 1 功能設計專家)

檢測職責:

  1. 對每個 Ticket 執行 C1/C2/C3 檢測
  2. 記錄檢測結果到工作日誌
  3. 檢測失敗時執行修正
  4. 提供品質閘門報告給 PM

阻斷機制:

 1檢測結果處理:
 2
 3所有 Ticket 都通過 C1/C2/C3?
 4  ├─ Yes → 提交給 PM 審查
 5  │           └─ PM 批准 → 分派給開發者執行
 6 7  └─ No → 阻止進入 Phase 2
 8              ├─ 記錄檢測失敗原因
 9              ├─ 執行修正(拆分/補充/重新定義)
10              └─ 重新檢測(直到通過)

阻斷原則:

  • 強制阻斷: 任何 Ticket 未通過 C1/C2/C3 檢測,禁止進入 Phase 2
  • 修正優先: 發現問題後立即修正,不延後處理
  • 完整記錄: 所有檢測過程和修正過程都記錄到工作日誌

品質閘門價值:

價值維度說明效益
及早發現設計階段就能發現 Code Smell修正成本降低 80%
標準化提供統一的檢測標準避免主觀判斷
可追溯完整的檢測記錄提升品質可見性
預防性預防問題進入實作階段減少返工時間

2.4.2 C1. God Ticket 檢測

定義(引用 v0.12.G.2 第 2.3.1 節 God Ticket 定義):

God Ticket 是指單一 Ticket 修改過多檔案和層級,範圍失控,違反「單層修改原則」(引用 v0.12.G.1 第 3.1 節)。

量化檢測指標:

指標良好設計需要檢查God Ticket(必須拆分)
檔案數量1-3 個(合格)4-6 個(需檢查)> 10 個(超標)
層級跨度1 層(合格)2 層(需檢查)> 2 層(超標)
預估工時2-4 小時(合格)4-8 小時(需檢查)> 16 小時(超標)

組合邏輯(Phase 2 補充說明):

1判斷標準:任一項目超標 = God Ticket(需要拆分)
2
3範例:
4
5- 檔案數 = 8 個(未超標)、層級跨度 = 3 層(超標) → God Ticket
6- 檔案數 = 12 個(超標)、層級跨度 = 1 層(未超標) → God Ticket
7- 檔案數 = 5 個(未超標)、層級跨度 = 2 層(未超標)、工時 = 20 小時(超標) → God Ticket
8
9只要有任何一個指標超標,就判定為 God Ticket,必須拆分。

檢測方法(Ticket 設計階段):

步驟 1: 列出 Ticket 涉及的檔案清單

從 Ticket 的「步驟」章節中提取所有檔案路徑:

 1範例 Ticket 步驟:
 2
 31. 建立 Rating Value Object(`lib/domain/value_objects/rating_value.dart` 42. 建立 Rating Entity(`lib/domain/entities/rating.dart` 53. 更新 Book Entity(`lib/domain/entities/book.dart` 64. 定義 IRatingRepository(`lib/domain/repositories/i_rating_repository.dart` 7...
 8
 9提取檔案清單:
10
11- lib/domain/value_objects/rating_value.dart
12- lib/domain/entities/rating.dart
13- lib/domain/entities/book.dart
14- lib/domain/repositories/i_rating_repository.dart
15...
步驟 2: 計算檔案數量
1統計檔案數量(不包含測試檔案):
2  ├─ 1-3 個 → 良好設計
3  ├─ 4-6 個 → 需要檢查(評估是否可拆分)
4  ├─ 7-10 個 → 建議拆分
5  └─ > 10 個 → God Ticket(強制拆分)
步驟 3: 判斷層級跨度

使用 v0.12.G.1 第 6.2 節「檔案路徑分析法」判斷每個檔案所屬層級:

 1檔案路徑 → 層級對應規則:
 2
 3Layer 1(UI):
 4- lib/presentation/widgets/
 5- lib/presentation/pages/
 6
 7Layer 2(Behavior):
 8- lib/presentation/controllers/
 9- lib/presentation/providers/
10- lib/presentation/view_models/
11
12Layer 3(UseCase):
13- lib/application/use_cases/
14- lib/application/services/
15
16Layer 4(Domain Events/Interfaces):
17- lib/domain/events/
18- lib/domain/repositories/ (介面)
19- lib/domain/services/ (介面)
20
21Layer 5(Domain Implementation):
22- lib/domain/entities/
23- lib/domain/value_objects/
24- lib/infrastructure/repositories/ (實作)
25- lib/infrastructure/services/ (實作)

計算層級跨度:

1範例:
2檔案清單:
3
4- lib/presentation/widgets/rating_widget.dart → Layer 1
5- lib/presentation/controllers/rating_controller.dart → Layer 2
6- lib/application/use_cases/rate_book_use_case.dart → Layer 3
7- lib/domain/entities/rating.dart → Layer 5
8
9層級跨度 = max(5) - min(1) = 4 層(超標)→ God Ticket

判斷標準:

1  ├─ 1 層(單層修改)→ 良好設計
2  ├─ 2 層(Facade 整合)→ 需要檢查(可能可接受)
3  └─ > 2 層(跨多層修改)→ God Ticket(強制拆分)
步驟 4: 評估預估工時

根據 Ticket 的「步驟」章節複雜度評估:

 1評估依據:
 2
 31. 步驟數量:
 4   ├─ < 10 項 → 簡單任務(2-4 小時)
 5   ├─ 10-20 項 → 中等任務(4-8 小時)
 6   └─ > 20 項 → 複雜任務(> 8 小時)
 7
 82. 步驟複雜度:
 9   ├─ 單純檔案建立或方法定義 → 簡單(x1.0 係數)
10   ├─ 包含邏輯實作和測試 → 中等(x1.5 係數)
11   └─ 包含多層整合和異常處理 → 複雜(x2.0 係數)
12
133. 計算公式:
14   預估工時 = 步驟數量 × 平均每步驟時間 × 複雜度係數
15
16範例:
17
18- 15 個步驟 × 30 分鐘 × 1.5 係數 = 11.25 小時(需檢查)
19- 25 個步驟 × 30 分鐘 × 2.0 係數 = 25 小時(超標)→ God Ticket

判斷標準:

1  ├─ 2-4 小時 → 良好設計
2  ├─ 4-8 小時 → 需要檢查
3  ├─ 8-16 小時 → 建議拆分
4  └─ > 16 小時 → God Ticket(強制拆分)

檢測失敗處理:

 1God Ticket 檢測失敗 → 執行拆分策略
 2
 3步驟 1: 選擇拆分策略
 4  優先策略: 按層級拆分(引用 v0.12.G.1 第 3.1 節單層修改原則)
 5  次要策略: 按職責拆分
 6  最終策略: 按功能模組拆分
 7
 8步驟 2: 執行拆分(引用 v0.12.G.1 第 5.4 節 Ticket 拆分指引)
 9  範例:14 個檔案、4 層 → 拆分為 5 個 Ticket(每層級 1 個)
10
11步驟 3: 重新檢測
12  對拆分後的每個 Ticket 重新執行 C1 檢測
13  確保所有 Ticket 都通過標準

拆分策略決策樹:

 1God Ticket 拆分決策:
 2
 3檔案數量 > 10 或 層級跨度 > 2?
 4  └─ Yes → 按層級拆分(優先)
 5            ├─ Layer 5: Domain 層 Ticket
 6            ├─ Layer 4: Domain 介面層 Ticket
 7            ├─ Layer 3: UseCase 層 Ticket
 8            ├─ Layer 2: Behavior 層 Ticket
 9            └─ Layer 1: UI 層 Ticket
10
11預估工時 > 16 小時?
12  └─ Yes → 按職責拆分(次要)
13            ├─ 職責 1: 資料建模 Ticket
14            ├─ 職責 2: 業務邏輯 Ticket
15            ├─ 職責 3: 介面整合 Ticket
16            └─ 職責 4: UI 呈現 Ticket
17
18職責數量 > 5?
19  └─ Yes → 按功能模組拆分(最終)
20            ├─ 模組 A: 核心功能 Ticket
21            ├─ 模組 B: 輔助功能 Ticket
22            └─ 模組 C: 整合驗證 Ticket

檢測範例(完整流程):

原始 Ticket(違反 C1 標準):

 1## Ticket: 新增「書籍評分」完整功能
 2
 3### 背景
 4根據 UC-03 需求,需要新增書籍評分功能。
 5
 6### 目標
 7實作書籍評分的完整功能,包含 UI、邏輯、資料儲存。
 8
 9### 步驟
101. 建立 Rating Value Object(`lib/domain/value_objects/rating_value.dart`112. 建立 Rating Entity(`lib/domain/entities/rating.dart`123. 更新 Book Entity(`lib/domain/entities/book.dart`134. 定義 IRatingRepository(`lib/domain/repositories/i_rating_repository.dart`145. 實作 RatingRepositoryImpl(`lib/infrastructure/repositories/rating_repository_impl.dart`156. 建立 Rating 資料表(`lib/infrastructure/database/rating_table.dart`167. 定義 RateBookUseCase 介面(`lib/application/use_cases/i_rate_book_use_case.dart`178. 實作 RateBookUseCase(`lib/application/use_cases/rate_book_use_case.dart`189. 定義 GetBookRatingUseCase 介面(`lib/application/use_cases/i_get_book_rating_use_case.dart`1910. 實作 GetBookRatingUseCase(`lib/application/use_cases/get_book_rating_use_case.dart`2011. 更新 BookDetailController(`lib/presentation/controllers/book_detail_controller.dart`2112. 建立 RatingController(`lib/presentation/controllers/rating_controller.dart`2213. 建立 RatingWidget(`lib/presentation/widgets/rating_widget.dart`2314. 更新 BookDetailWidget(`lib/presentation/widgets/book_detail_widget.dart`2415. 撰寫測試

C1 檢測執行:

 1步驟 1: 列出檔案清單
 2  檔案數量 = 14 個
 3
 4步驟 2: 計算檔案數量
 5  14 個 > 10 個 → God Ticket
 6
 7步驟 3: 判斷層級跨度
 8  檔案層級分布:
 9  - Layer 5: rating_value.dart, rating.dart, book.dart (3 個)
10  - Layer 5: rating_repository_impl.dart, rating_table.dart (2 個)
11  - Layer 4: i_rating_repository.dart (1 個)
12  - Layer 3: i_rate_book_use_case.dart, rate_book_use_case.dart (2 個)
13  - Layer 3: i_get_book_rating_use_case.dart, get_book_rating_use_case.dart (2 個)
14  - Layer 2: book_detail_controller.dart, rating_controller.dart (2 個)
15  - Layer 1: rating_widget.dart, book_detail_widget.dart (2 個)
16
17  層級跨度 = 5 - 1 = 4 層(超標)→ God Ticket
18
19步驟 4: 評估預估工時
20  步驟數量 = 15 項
21  複雜度 = 包含多層整合(x2.0 係數)
22  預估工時 = 15 × 30 分鐘 × 2.0 = 15 小時(需檢查)
23
24結論: 檔案數量和層級跨度都超標 → God Ticket(必須拆分)

拆分策略執行:

 1選擇策略: 按層級拆分(優先策略)
 2
 3拆分結果(5 個 Ticket):
 4
 5Ticket 1 [Layer 5]: Rating Domain 模型
 6  - rating_value.dart
 7  - rating.dart
 8  - book.dart(新增 rating 欄位)
 9
10Ticket 2 [Layer 5 + 4]: Rating Repository
11  - i_rating_repository.dart(介面)
12  - rating_repository_impl.dart(實作)
13  - rating_table.dart(資料表)
14
15Ticket 3 [Layer 3]: RateBook UseCase
16  - i_rate_book_use_case.dart(介面)
17  - rate_book_use_case.dart(實作)
18
19Ticket 4 [Layer 3]: GetBookRating UseCase
20  - i_get_book_rating_use_case.dart(介面)
21  - get_book_rating_use_case.dart(實作)
22
23Ticket 5 [Layer 2]: Rating Controller 整合
24  - book_detail_controller.dart(更新)
25  - rating_controller.dart(新建)
26
27Ticket 6 [Layer 1]: Rating UI 元件
28  - rating_widget.dart(新建)
29  - book_detail_widget.dart(更新)

拆分後重新檢測:

 1Ticket 1 [Layer 5]: Rating Domain 模型
 2  檔案數量: 3 個(符合)
 3  層級跨度: 1 層(符合)
 4  預估工時: 3 小時(符合)
 5  結論: 通過
 6
 7Ticket 2 [Layer 5 + 4]: Rating Repository
 8  檔案數量: 3 個(符合)
 9  層級跨度: 2 層(需檢查)(Repository 介面和實作可接受)
10  預估工時: 4 小時(符合)
11  結論: 通過
12
13Ticket 3 [Layer 3]: RateBook UseCase
14  檔案數量: 2 個(符合)
15  層級跨度: 1 層(符合)
16  預估工時: 3 小時(符合)
17  結論: 通過
18
19Ticket 4 [Layer 3]: GetBookRating UseCase
20  檔案數量: 2 個(符合)
21  層級跨度: 1 層(符合)
22  預估工時: 2.5 小時(符合)
23  結論: 通過
24
25Ticket 5 [Layer 2]: Rating Controller 整合
26  檔案數量: 2 個(符合)
27  層級跨度: 1 層(符合)
28  預估工時: 3 小時(符合)
29  結論: 通過
30
31Ticket 6 [Layer 1]: Rating UI 元件
32  檔案數量: 2 個(符合)
33  層級跨度: 1 層(符合)
34  預估工時: 4 小時(符合)
35  結論: 通過
36
37最終結論: 所有 Ticket 都通過 C1 檢測

改善效果:

維度原始 Ticket拆分後(6 個 Ticket)改善
檔案數量14 個(超標)2-3 個/Ticket(合格)符合標準
層級跨度4 層(超標)1-2 層/Ticket(合格)符合單層修改原則
預估工時15 小時(需檢查)2.5-4 小時/Ticket(合格)可在半天內完成
可並行執行是(Ticket 1-4 可並行)(合格)加速開發
風險控制高風險低風險(合格)降低失敗影響

2.4.3 C3. Ambiguous Responsibility 檢測

定義(引用 v0.12.G.2 第 2.3.3 節 Ambiguous Responsibility 定義):

Ambiguous Responsibility 是指 Ticket 的職責定義不明確,無法判斷屬於哪一層級,違反「層級明確原則」。

職責明確 Ticket 必要元素:

必要元素檢查項目範例缺失後果
層級標示標題包含 [Layer X] 標籤[Layer 2] 實作書籍詳情事件處理無法判斷責任範圍
職責描述目標章節明確定義單一職責實作 BookDetailController 的 loadBookDetail 方法職責模糊
檔案範圍步驟章節明確列出檔案路徑修改 lib/presentation/controllers/book_detail_controller.dart影響範圍不明
驗收限定驗收條件限定在該層級BookDetailController.loadBookDetail() 正確呼叫 UseCase驗收標準模糊

檢測方法(Ticket 設計階段):

步驟 1: 檢查層級標示
 1標題格式檢查:
 2  合格範例:
 3  - [Layer 1] 建立書籍評分 UI 元件
 4  - [Layer 2] 實作書籍詳情 Controller 事件處理
 5  - [Layer 3] 實作 GetBookDetail UseCase
 6  - [Layer 5] 定義 Book Entity 和 Value Objects
 7
 8  不合格範例:
 9  - 建立書籍評分功能(沒有層級標示)
10  - 實作書籍詳情(層級不明確)
11  - 整合評分功能(跨多層,職責模糊)
步驟 2: 檢查職責描述
 1目標章節檢查:
 2  合格範例:
 3  ### 目標
 4  實作 BookDetailController 的 loadBookDetail 方法,
 5  負責接收使用者事件並呼叫 GetBookDetailUseCase。
 6
 7  職責定義明確:
 8  - 明確說明「做什麼」:實作 loadBookDetail 方法
 9  - 明確說明「責任範圍」:接收事件 + 呼叫 UseCase
10  - 明確說明「不做什麼」:不包含業務邏輯實作
11
12  不合格範例:
13  ### 目標
14  實作書籍詳情功能
15
16  職責定義模糊:
17  - 「書籍詳情功能」範圍太廣(UI? 邏輯? 資料?)
18  - 沒有說明具體職責
19  - 沒有說明責任邊界

步驟 3: 檢查檔案範圍

 1步驟章節檢查:
 2  合格範例:
 3  ### 步驟
 4  1. 修改 `lib/presentation/controllers/book_detail_controller.dart`
 5  2. 新增 `loadBookDetail` 方法
 6  3. 注入 `IGetBookDetailUseCase` 依賴
 7  4. 實作事件處理邏輯
 8
 9  檔案範圍明確:
10  - 明確列出檔案路徑
11  - 避免籠統描述(如「修改相關檔案」)
12  - 檔案數量合理(1-3 個)
13
14  不合格範例:
15  ### 步驟
16  1. 修改書籍詳情相關檔案
17  2. 實作相關邏輯
18  3. 更新 UI
19
20  檔案範圍模糊:
21  - 「相關檔案」沒有具體說明是哪些檔案
22  - 「相關邏輯」沒有說明在哪裡實作
23  - 「更新 UI」沒有說明哪個 UI 檔案

步驟 4: 檢查驗收限定

 1驗收條件章節檢查:
 2  合格範例:
 3  ### 驗收條件
 4  - [ ] BookDetailController.loadBookDetail() 方法建立
 5  - [ ] 正確注入 IGetBookDetailUseCase 依賴
 6  - [ ] loadBookDetail() 正確呼叫 UseCase.execute()
 7  - [ ] 事件處理邏輯正確(不包含業務邏輯)
 8  - [ ] dart analyze 0 錯誤
 9
10  驗收限定在 Layer 2(Behavior):
11  - 只驗證 Controller 層的職責
12  - 不驗證 UI 呈現(Layer 1)
13  - 不驗證業務邏輯(Layer 3)
14
15  不合格範例:
16  ### 驗收條件
17  - [ ] 書籍詳情功能正常運作
18  - [ ] 使用者可以看到書籍資訊
19  - [ ] 資料正確儲存
20
21  驗收未限定在單一層級:
22  - 「功能正常運作」涵蓋所有層級
23  - 「使用者可以看到」是 UI 層(Layer 1)驗收
24  - 「資料正確儲存」是 Repository 層(Layer 5)驗收

檢測失敗處理:

 1C3 檢測失敗 → 執行重新定義步驟
 2
 3步驟 1: 明確層級定位
 4  使用 v0.12.G.1 第 6.2 節檔案路徑分析法判斷層級
 5  在標題加上 [Layer X] 標籤
 6
 7步驟 2: 重新定義職責
 8  基於該層級的職責範圍重寫目標章節
 9  明確說明「做什麼」「責任範圍」「不做什麼」
10
11步驟 3: 明確檔案範圍
12  列出具體的檔案路徑(避免籠統描述)
13  確保檔案都屬於同一層級
14
15步驟 4: 限定驗收條件
16  驗收條件只驗證該層級的職責
17  移除跨層級的驗收項目
18
19步驟 5: 重新檢測
20  確認所有 4 個必要元素都已補充

檢測範例(完整流程):

原始 Ticket(違反 C3 標準):

 1## Ticket: 實作書籍詳情功能
 2
 3### 背景
 4根據 UC-02 需求,需要實作書籍詳情功能。
 5
 6### 目標
 7實作書籍詳情功能,讓使用者可以查看書籍的完整資訊。
 8
 9### 步驟
101. 修改相關檔案
112. 實作查詢邏輯
123. 更新 UI 顯示
13
14### 驗收條件
15- [ ] 使用者可以看到書籍詳情
16- [ ] 資料正確顯示
17- [ ] 功能正常運作

C3 檢測執行:

 1步驟 1: 檢查層級標示
 2  標題: "實作書籍詳情功能"
 3  結果: 沒有 [Layer X] 標籤(不符合)
 4  問題: 無法判斷屬於哪一層級
 5
 6步驟 2: 檢查職責描述
 7  目標: "實作書籍詳情功能,讓使用者可以查看書籍的完整資訊"
 8  結果: 職責定義模糊(不符合)
 9  問題:
10  - "書籍詳情功能"範圍太廣(UI? 邏輯? 資料?)
11  - 沒有明確說明職責範圍
12
13步驟 3: 檢查檔案範圍
14  步驟: "修改相關檔案"
15  結果: 檔案範圍模糊(不符合)
16  問題:
17  - "相關檔案"沒有具體說明
18  - 沒有明確的檔案路徑
19
20步驟 4: 檢查驗收限定
21  驗收條件: "使用者可以看到書籍詳情"、"功能正常運作"
22  結果: 驗收未限定在單一層級(不符合)
23  問題:
24  - "使用者可以看到"是 UI 層驗收
25  - "功能正常運作"涵蓋所有層級
26
27結論: Ambiguous Responsibility(必須重新定義)

重新定義執行:

 1步驟 1: 明確層級定位
 2  分析 Ticket 內容 → 主要涉及 Controller 事件處理
 3  判斷層級 → Layer 2(Behavior)
 4  更新標題 → 加上 [Layer 2] 標籤
 5
 6步驟 2: 重新定義職責
 7  重寫目標章節:
 8  - 明確說明「做什麼」
 9  - 明確說明「責任範圍」
10  - 明確說明「不做什麼」
11
12步驟 3: 明確檔案範圍
13  列出具體檔案路徑
14  確認都屬於 Layer 2
15
16步驟 4: 限定驗收條件
17  只驗證 Layer 2 的職責
18  移除 UI 和業務邏輯驗收

修正後 Ticket(符合 C3 標準):

 1## Ticket: [Layer 2] 實作書籍詳情 Controller 事件處理
 2
 3### 背景
 4根據 UC-02 需求,需要實作 BookDetailController 的事件處理邏輯。
 5
 6### 目標
 7實作 BookDetailController 的 loadBookDetail 方法,
 8負責接收使用者的「查看書籍詳情」事件並呼叫 GetBookDetailUseCase。
 9
10職責範圍:
11
12- 接收使用者事件(如按鈕點擊)
13- 呼叫 GetBookDetailUseCase 獲取書籍資料
14- 將 UseCase 回傳的資料傳遞給 UI
15- 不包含業務邏輯實作(業務邏輯在 UseCase 層)
16
17### 步驟
181. 修改 `lib/presentation/controllers/book_detail_controller.dart`
192. 新增 `loadBookDetail(String isbn)` 方法
203. 注入 `IGetBookDetailUseCase` 依賴
214. 實作事件處理邏輯:
22   - 呼叫 `useCase.execute(isbn)`
23   - 處理回傳的 `OperationResult<Book>`
24   - 更新 Controller 狀態(loading/success/error)
255. 撰寫單元測試
26
27### 驗收條件
28- [ ] BookDetailController.loadBookDetail() 方法建立在正確位置
29- [ ] 正確注入 IGetBookDetailUseCase 依賴
30- [ ] loadBookDetail() 正確呼叫 useCase.execute()
31- [ ] 正確處理 OperationResult(success/failure)
32- [ ] 事件處理邏輯正確(不包含業務邏輯)
33- [ ] 單元測試覆蓋率 > 80%
34- [ ] dart analyze 0 錯誤
35
36### 依賴 Ticket
37- Ticket #3: 定義 IGetBookDetailUseCase 介面(必須先完成)
38
39### 參考文件
40- docs/app-requirements-spec.md #UC-02
41- docs/work-logs/v0.12.8-design-decisions.md #決策2

修正後重新檢測:

 1步驟 1: 檢查層級標示
 2  標題: "[Layer 2] 實作書籍詳情 Controller 事件處理"
 3  結果: 有 [Layer 2] 標籤(符合)
 4
 5步驟 2: 檢查職責描述
 6  目標: 明確定義職責範圍和邊界
 7  結果: 職責定義明確(符合)
 8  - 明確說明「接收事件」「呼叫 UseCase」
 9  - 明確說明「不包含業務邏輯」
10
11步驟 3: 檢查檔案範圍
12  步驟: 明確列出檔案路徑
13  結果: 檔案範圍明確(符合)
14  - `lib/presentation/controllers/book_detail_controller.dart`
15
16步驟 4: 檢查驗收限定
17  驗收條件: 限定在 Layer 2 職責
18  結果: 驗收限定正確(符合)
19  - 只驗證 Controller 層的職責
20  - 不包含 UI 或業務邏輯驗收
21
22結論: 通過 C3 檢測

改善效果:

維度原始 Ticket修正後 Ticket改善
層級標示無(不合格)[Layer 2](合格)明確定位
職責描述模糊(不合格)明確定義範圍和邊界(合格)職責清晰
檔案範圍“相關檔案”(不合格)具體檔案路徑(合格)影響範圍明確
驗收限定跨層級(不合格)限定在 Layer 2(合格)驗收標準清晰
可執行性低(不合格)高(合格)開發者可直接執行

2.4.4 C2. Incomplete Ticket 檢測

定義(引用 v0.12.G.2 第 2.3.3 節 Incomplete Ticket 定義):

Incomplete Ticket 是指 Ticket 內容缺失關鍵元素,導致開發者無法明確理解需求、驗收標準或測試方法。

必要元素檢測清單:

元素檢查內容通過標準重要性
驗收條件是否有「### 驗收條件」章節至少 3 個可驗證的驗收項目必要
測試規劃步驟中是否包含測試明確列出測試檔案和測試項目必要
工作日誌規劃是否規劃工作日誌檔案明確工作日誌檔案名稱和記錄內容必要
參考文件是否連結需求規格或設計文件至少 1 個有效的文件連結必要

檢測方法:

步驟 1: 檢查驗收條件完整性
 1掃描 Ticket 內容
 2 3檢查是否包含「### 驗收條件」章節?
 4  ├─ Yes → 檢查驗收項目數量
 5  │         ├─ ≥ 3 個 → 通過
 6  │         └─ < 3 個 → 失敗(驗收條件不足)
 7 8  └─ No → 失敗(缺少驗收條件章節)
 9
10驗收條件品質檢查:
11  ├─ 是否可量化驗證?(避免模糊描述)
12  ├─ 是否限定在該層級?(不跨層級驗收)
13  └─ 是否涵蓋功能性、品質性、整合性?

範例:

合格驗收條件:

1### 驗收條件
2- [ ] `IBookRepository` 介面檔案建立在 `lib/domains/library/repositories/`
3- [ ] `getBookByIsbn(String isbn)` 方法簽名完整且明確
4- [ ] 方法包含完整的文檔註解(參數、回傳值、異常)
5- [ ] dart analyze 0 錯誤
6- [ ] 測試覆蓋率 > 80%
7- [ ] 不破壞既有功能(回歸測試通過)

不合格驗收條件:

1### 驗收條件
2- [ ] 功能可以正常運作
3- [ ] 程式碼品質良好

問題:驗收條件過於模糊,無法量化驗證

步驟 2: 檢查測試規劃完整性

 1掃描「步驟」章節
 2 3檢查是否包含測試相關步驟?
 4  ├─ Yes → 檢查測試內容
 5  │         ├─ 有測試檔案路徑(符合)
 6  │         ├─ 有測試項目清單(符合)
 7  │         ├─ 有測試覆蓋率要求(符合)
 8  │         └─ 通過
 910  └─ No → 失敗(缺少測試規劃)
11
12測試規劃品質檢查:
13  ├─ 是否包含單元測試?
14  ├─ 是否包含整合測試?(如需要)
15  └─ 是否定義測試覆蓋率標準?

範例:

合格測試規劃:

1### 步驟
24. 撰寫 `test/domain/repositories/book_repository_test.dart` 單元測試
3   - 測試 `getBookByIsbn` 正常流程(書籍存在)
4   - 測試書籍不存在異常處理
5   - 測試 ISBN 格式錯誤異常處理
6   - 測試網路錯誤異常處理
75. 確保測試覆蓋率 > 80%

不合格測試規劃:

1### 步驟
24. 撰寫測試

問題:沒有明確測試檔案路徑和測試項目

步驟 3: 檢查工作日誌規劃

 1掃描 Ticket 內容
 2 3檢查是否包含「### 工作日誌」章節?
 4  ├─ Yes → 檢查檔案名稱
 5  │         ├─ 符合命名規範(符合)
 6  │         │   格式: docs/work-logs/vX.Y.Z-feature-name.md
 7  │         └─ 通過
 8 9  └─ No → 失敗(缺少工作日誌規劃)
10
11命名規範檢查:
12  ├─ 是否包含版本號?
13  ├─ 是否描述性命名?
14  └─ 是否在 docs/work-logs/ 目錄下?

範例:

合格工作日誌規劃:

1### 工作日誌
2檔案名稱: `docs/work-logs/v0.12.8-book-repository-interface.md`
3
4記錄內容:
5- Ticket 執行過程
6- 設計決策和理由
7- 遇到的問題和解決方法
8- 測試結果和覆蓋率報告

不合格工作日誌規劃:

1(沒有工作日誌規劃)

步驟 4: 檢查參考文件連結

 1掃描 Ticket 內容
 2 3檢查是否包含「### 參考文件」章節?
 4  ├─ Yes → 檢查連結有效性
 5  │         ├─ 至少 1 個連結(符合)
 6  │         ├─ 連結格式正確(符合)
 7  │         └─ 連結內容相關(符合)
 8 9  └─ No → 失敗(缺少參考文件)
10
11連結品質檢查:
12  ├─ 是否連結需求規格?(建議)
13  ├─ 是否連結設計文件?(建議)
14  └─ 是否連結相關 Ticket?(如有依賴)

範例:

合格參考文件:

1### 參考文件
2- `docs/app-requirements-spec.md` #UC-01 書籍查詢功能
3- `docs/work-logs/v0.12.7-design-decisions.md` #決策1 Repository 設計模式
4- `.claude/methodologies/layered-ticket-methodology.md` 層級隔離原則

不合格參考文件:

1(沒有參考文件章節)

檢測流程完整範例:

 1Ticket #1: [Layer 5] 定義 IBookRepository 介面
 2 3執行 C2. Incomplete Ticket 檢測
 4 5【步驟 1】檢查驗收條件
 6  ├─ 有「### 驗收條件」章節(符合)
 7  ├─ 驗收項目數量: 6 個(符合)
 8  ├─ 驗收條件可量化(符合)
 9  └─ 通過
1011【步驟 2】檢查測試規劃
12  ├─ 步驟 4 包含測試(符合)
13  ├─ 測試檔案路徑明確(符合)
14  ├─ 測試項目完整(符合)
15  └─ 通過
1617【步驟 3】檢查工作日誌規劃
18  ├─ 有「### 工作日誌」章節(符合)
19  ├─ 檔案名稱符合規範(符合)
20  └─ 通過
2122【步驟 4】檢查參考文件
23  ├─ 有「### 參考文件」章節(符合)
24  ├─ 連結數量: 3 個(符合)
25  ├─ 連結格式正確(符合)
26  └─ 通過
2728C2 檢測結論: 通過

修正方法:

缺失項目 1: 沒有驗收條件

修正步驟:

11. 新增「### 驗收條件」章節
22. 撰寫 3-6 個可量化驗收項目
33. 涵蓋三個維度:
4   - 功能性驗收(檔案位置、方法簽名、程式邏輯)
5   - 品質性驗收(dart analyze、測試覆蓋率、文檔)
6   - 整合性驗收(整合測試、不破壞既有功能)
缺失項目 2: 沒有測試規劃

修正步驟:

11. 在「### 步驟」章節新增測試步驟
22. 明確列出測試檔案路徑
33. 列出測試項目清單(正常流程 + 異常處理)
44. 定義測試覆蓋率要求(建議 > 80%)
缺失項目 3: 沒有工作日誌規劃

修正步驟:

11. 新增「### 工作日誌」章節
22. 定義工作日誌檔案名稱
3   格式: docs/work-logs/vX.Y.Z-feature-name.md
43. 說明記錄內容範圍
缺失項目 4: 沒有參考文件

修正步驟:

11. 新增「### 參考文件」章節
22. 連結需求規格(必要)
33. 連結設計文件(建議)
44. 連結相關 Ticket(如有依賴)

完整修正範例:

修正前(Incomplete Ticket):

1## Ticket: 定義 IBookRepository 介面
2
3### 目標
4定義書籍 Repository 的介面契約
5
6### 步驟
71. 建立介面檔案
82. 定義方法簽名
93. 撰寫文檔註解

修正後(Complete Ticket):

 1## Ticket: [Layer 5] 定義 IBookRepository 介面
 2
 3### 目標
 4定義書籍 Repository 的介面契約,規範 Domain 層與 Infrastructure 層的互動方式
 5
 6### 步驟
 71. 建立 `lib/domains/library/repositories/i_book_repository.dart`
 82. 定義 `getBookByIsbn(String isbn)` 方法簽名
 93. 定義 `getAllBooks()` 方法簽名
104. 撰寫完整的文檔註解(參數、回傳值、異常)
115. 撰寫 `test/domain/repositories/book_repository_test.dart` 單元測試
12   - 測試 getBookByIsbn 正常流程
13   - 測試書籍不存在異常處理
14   - 測試 ISBN 格式錯誤異常處理
156. 確保測試覆蓋率 > 80%
16
17### 驗收條件
18- [ ] `IBookRepository` 介面檔案建立在 `lib/domains/library/repositories/`
19- [ ] `getBookByIsbn(String isbn)` 方法簽名完整且明確
20- [ ] 方法包含完整的文檔註解
21- [ ] dart analyze 0 錯誤
22- [ ] 測試覆蓋率 > 80%
23- [ ] 不破壞既有功能
24
25### 工作日誌
26檔案名稱: `docs/work-logs/v0.12.8-book-repository-interface.md`
27
28### 參考文件
29- `docs/app-requirements-spec.md` #UC-01 書籍查詢功能
30- `.claude/methodologies/layered-ticket-methodology.md` 層級隔離原則

2.4.5 品質閘門執行流程

完整執行流程:

 1Phase 1: 功能設計(lavender-interface-designer)
 2 3Ticket 清單撰寫完成
 4 5┌─────────────────────────────────────┐
 6│   品質閘門檢測開始                    │
 7│   (lavender-interface-designer)    │
 8└─────────────────────────────────────┘
 910對每個 Ticket 執行檢測(按順序)
1112┌─────────────────────────────────────┐
13│ 【檢測 1】C1. God Ticket 檢測        │
14│                                     │
15│ 檢查指標:                            │
16│  - 檔案數量 ≤ 10?                   │
17│  - 層級跨度 ≤ 2?                    │
18│  - 預估工時 ≤ 16h?                  │
19│                                     │
20│ 組合邏輯: 任一項目超標 = God Ticket   │
21└─────────────────────────────────────┘
2223  ├─ 通過 → 繼續檢測 C3
24  └─ 失敗 → 執行拆分 → 重新檢測 C1
2526┌─────────────────────────────────────┐
27│ 【檢測 2】C3. Ambiguous              │
28│           Responsibility 檢測         │
29│                                     │
30│ 檢查要素:                            │
31│  - 有層級標示 [Layer X]?            │
32│  - 職責描述明確?                    │
33│  - 檔案範圍明確?                    │
34│  - 驗收條件限定在該層?              │
35└─────────────────────────────────────┘
3637  ├─ 通過 → 繼續檢測 C2
38  └─ 失敗 → 重新定義職責 → 重新檢測 C3
3940┌─────────────────────────────────────┐
41│ 【檢測 3】C2. Incomplete Ticket 檢測 │
42│                                     │
43│ 檢查要素:                            │
44│  - 有驗收條件章節?                  │
45│  - 有測試規劃?                      │
46│  - 有工作日誌規劃?                  │
47│  - 有參考文件連結?                  │
48└─────────────────────────────────────┘
4950  ├─ 通過 → Ticket 通過品質閘門
51  └─ 失敗 → 補充遺漏項目 → 重新檢測 C2
5253所有 Ticket 都通過 C1/C2/C3?
5455  ├─ Yes → 提交品質閘門報告給 PM
56  │           ↓
57  │         PM 審查
58  │           ↓
59  │         PM 批准 → 進入 Phase 2: 測試驗證
6061  └─ No → 繼續修正未通過的 Ticket

檢測順序說明:

順序檢測項目檢測原因失敗影響
1 C1God Ticket檔案數和層級是最基礎的結構問題必須拆分,否則後續檢測無意義
2 C3Ambiguous Responsibility職責定義是 Ticket 品質的核心必須重新定義,避免跨層級實作
3 C2Incomplete Ticket完整性是 Ticket 可執行性的保證補充遺漏項目,確保開發者理解需求

檢測順序設計理由:

  • C1 優先: 檔案數和層級問題會影響職責定義,必須先解決結構問題
  • C3 次之: 職責明確後才能評估驗收條件和測試規劃是否完整
  • C2 最後: 完整性檢測依賴明確的職責定義

檢測失敗處理流程:

 1檢測失敗
 2 3記錄失敗原因到工作日誌
 4 5根據失敗類型選擇修正方法
 6  ├─ C1 失敗 → 執行 Ticket 拆分
 7  │             ├─ 按層級拆分(優先)
 8  │             ├─ 按職責拆分(次要)
 9  │             └─ 按 TDD 階段拆分(特殊)
1011  ├─ C3 失敗 → 重新定義職責
12  │             ├─ 確認主要職責層級
13  │             ├─ 加入層級標示 [Layer X]
14  │             ├─ 限定職責範圍
15  │             └─ 明確列出檔案
1617  └─ C2 失敗 → 補充遺漏項目
18                ├─ 補充驗收條件
19                ├─ 補充測試規劃
20                ├─ 補充工作日誌規劃
21                └─ 補充參考文件連結
2223修正完成
2425重新執行失敗的檢測項目
2627  ├─ 通過 → 繼續下一個檢測
28  └─ 失敗 → 再次修正(直到通過)

PM 審查標準:

審查清單:

審查項目檢查內容通過標準
品質閘門報告每個 Ticket 是否都執行了 C1/C2/C3 檢測所有 Ticket 都有檢測記錄(合格)
檢測結果所有 Ticket 是否都通過檢測所有 Ticket 標記為「通過」
修正記錄檢測失敗的 Ticket 是否記錄修正過程修正過程完整記錄(問題 + 修正方法 + 結果)
Ticket 數量拆分後的 Ticket 數量是否合理不過度拆分(< 10 個)、不過度合併(> 1 個)
依賴關係Ticket 間的依賴關係是否明確依賴順序符合架構層級(L5→L3→L2→L1)

PM 審查決策流程:

 1PM 收到品質閘門報告
 2 3【檢查 1】品質閘門報告完整性
 4  ├─ 所有 Ticket 都有 C1/C2/C3 檢測記錄?
 5  │   ├─ Yes → 繼續檢查 2
 6  │   └─ No → 要求 lavender 補充檢測
 7 8【檢查 2】檢測結果正確性
 9  ├─ 所有 Ticket 都標記為「通過」?
10  │   ├─ Yes → 繼續檢查 3
11  │   └─ No → 檢查未通過原因
12  │                ├─ 未修正 → 要求 lavender 修正
13  │                └─ 修正後仍不符合 → 要求重新設計
1415【檢查 3】修正記錄完整性
16  ├─ 檢測失敗的 Ticket 是否記錄修正過程?
17  │   ├─ Yes → 繼續檢查 4
18  │   └─ No → 要求補充修正記錄
1920【檢查 4】Ticket 數量合理性
21  ├─ 拆分後數量是否合理(1-10 個)?
22  │   ├─ Yes → 繼續檢查 5
23  │   └─ No → 要求調整拆分策略
2425【檢查 5】依賴關係正確性
26  ├─ Ticket 依賴順序是否符合架構層級?
27  │   ├─ Yes → PM 批准 Ticket 清單
28  │   └─ No → 要求調整依賴順序
2930PM 批准
3132分派給開發者執行(進入 Phase 2)

工作日誌記錄範例:

  1## Code Smell 品質閘門檢測
  2
  3### Ticket #1: [Layer 5] 定義 Book Entity
  4
  5#### 檢測記錄(2025-10-11)
  6
  7**C1. God Ticket 檢測**:
  8- 檔案數量: 2 個(符合)(book.dart + isbn.dart)
  9- 層級跨度: 1 層(Layer 5)(符合)
 10- 預估工時: 4 小時(符合)
 11- 結論: 通過
 12
 13**C3. Ambiguous Responsibility 檢測**:
 14- 層級標示: [Layer 5](符合)
 15- 職責描述: 明確(定義 Book Entity 和 ISBN Value Object)(符合)
 16- 檔案範圍: 明確列出 2 個檔案路徑(符合)
 17- 驗收限定: 限定在 Domain 層(符合)
 18- 結論: 通過
 19
 20**C2. Incomplete Ticket 檢測**:
 21- 驗收條件: 6 個驗收項目(符合)
 22- 測試規劃: 包含測試步驟和覆蓋率要求(符合)
 23- 工作日誌: 規劃檔案名稱(符合)
 24- 參考文件: 連結需求規格和設計文件(符合)
 25- 結論: 通過
 26
 27**最終結論**: Ticket #1 通過品質閘門
 28
 29---
 30
 31### Ticket #2: [Layer 3/5] 實作書籍查詢功能(原始設計)
 32
 33#### 檢測記錄(2025-10-11)
 34
 35**C1. God Ticket 檢測**:
 36- 檔案數量: 15 個(不符合)(超標,標準 ≤ 10)
 37- 層級跨度: 3 層(Layer 1/2/3/5)(不符合)(超標,標準 ≤ 2)
 38- 預估工時: 24 小時(不符合)(超標,標準 ≤ 16h)
 39- 結論: 失敗(3 個指標都超標)
 40
 41**修正方法**: 按層級拆分為 4 個 Ticket
 42- Ticket #2a: [Layer 5] 定義 Book Entity
 43- Ticket #2b: [Layer 3] 實作 GetBookUseCase
 44- Ticket #2c: [Layer 2] 實作 BookController
 45- Ticket #2d: [Layer 1] 實作 BookListWidget
 46
 47**拆分後重新檢測**:
 48
 49**Ticket #2a 檢測**:
 50- C1: 通過(2 個檔案、1 層、4h)
 51- C3: 通過(職責明確)
 52- C2: 通過(4 項必要元素齊全)
 53
 54**Ticket #2b 檢測**:
 55- C1: 通過(3 個檔案、1 層、6h)
 56- C3: 通過(職責明確)
 57- C2: 通過(4 項必要元素齊全)
 58
 59**Ticket #2c 檢測**:
 60- C1: 通過(2 個檔案、1 層、4h)
 61- C3: 通過(職責明確)
 62- C2: 通過(4 項必要元素齊全)
 63
 64**Ticket #2d 檢測**:
 65- C1: 通過(3 個檔案、1 層、5h)
 66- C3: 通過(職責明確)
 67- C2: 通過(4 項必要元素齊全)
 68
 69**最終結論**: 原 Ticket #2 拆分為 4 個 Ticket,全部通過品質閘門
 70
 71---
 72
 73### PM 審查報告
 74
 75**審查日期**: 2025-10-11
 76**審查 Ticket 清單**: v0.12.8 書籍查詢功能(5 個 Ticket)
 77
 78**品質閘門檢測確認**:
 79- Ticket #1: 通過 C1/C2/C3 檢測- Ticket #2a: 通過 C1/C2/C3 檢測(拆分後)- Ticket #2b: 通過 C1/C2/C3 檢測(拆分後)- Ticket #2c: 通過 C1/C2/C3 檢測(拆分後)- Ticket #2d: 通過 C1/C2/C3 檢測(拆分後)
 80**拆分合理性**:
 81- 原 Ticket 數量: 2 個(1 個正常 + 1 個 God Ticket)
 82- 拆分後數量: 5 個
 83- 評估: 合理(符合)
 84- 理由: God Ticket 按層級拆分為 4 個,符合單層修改原則
 85
 86**依賴關係檢查**:
 87- 依賴順序: Ticket #1#2a#2b#2c#2d
 88- 評估: 正確(符合)
 89- 理由: 遵循架構層級順序(Layer 5 → Layer 3 → Layer 2 → Layer 1)
 90
 91**審查結論**:
 92- 批准 Ticket 清單- 可分派給開發者執行(進入 Phase 2)```
 93
 94---
 95
 96#### 2.4.6 自動化檢測準備(v0.12.G.4)
 97
 98本節為 v0.12.G.4「代理人和 Hook 機制調整」準備自動化檢測規則設計。
 99
100**自動化檢測目標**:
101
102- 減少人工檢測工作量
103- 提升檢測一致性
104- 即時反饋 Ticket 品質問題
105- 支援 lavender-interface-designer 執行檢測
106
107**可自動化項目**:
108
109**C1. God Ticket 自動化檢測(可自動化程度: 80%)**:
110
111| 檢測指標     | 自動化程度 | 自動化方法                             | 需要人工判斷     |
112| ------------ | ---------- | -------------------------------------- | ---------------- |
113| **檔案數量** | 100%(合格)    | 掃描步驟章節,提取檔案路徑,計算數量   | 無               |
114| **層級跨度** | 100%(合格)    | 使用 v0.12.G.1 第 6.2 節決策樹判斷層級 | 無               |
115| **預估工時** | 60%(需檢查)      | 根據步驟數量估算(< 10 = 2-4h)     | 複雜度需人工確認 |
116
117**自動化規則設計**:
118
119```python
120def check_god_ticket_automated(ticket_content: str) -> dict:
121    """
122    自動化檢測 God Ticket
123
124    回傳格式:
125    {
126        "file_count": int,
127        "layer_span": int,
128        "estimated_hours": int,
129        "is_god_ticket": bool,
130        "confidence": float  # 0.0-1.0
131    }
132    """
133    # 1. 提取檔案路徑
134    file_paths = extract_file_paths(ticket_content)
135    file_count = len(file_paths)
136
137    # 2. 判斷層級跨度
138    layers = [determine_layer(path) for path in file_paths]
139    layer_span = max(layers) - min(layers) + 1
140
141    # 3. 預估工時(簡化估算)
142    step_count = count_steps(ticket_content)
143    estimated_hours = estimate_hours_by_steps(step_count)
144
145    # 4. 判斷是否為 God Ticket(任一項目超標)
146    is_god_ticket = (
147        file_count > 10 or
148        layer_span > 2 or
149        estimated_hours > 16
150    )
151
152    # 5. 計算信心度
153    confidence = calculate_confidence(step_count, file_paths)
154
155    return {
156        "file_count": file_count,
157        "layer_span": layer_span,
158        "estimated_hours": estimated_hours,
159        "is_god_ticket": is_god_ticket,
160        "confidence": confidence
161    }

C2. Incomplete Ticket 自動化檢測(可自動化程度: 90%):

檢測指標自動化程度自動化方法需要人工判斷
驗收條件100%(合格)檢查章節存在性、驗收項目數量
測試規劃80%(需檢查)檢查測試檔案和關鍵字測試完整性需人工確認
工作日誌100%(合格)檢查章節存在性、檔案名稱格式
參考文件100%(合格)檢查章節存在性、連結數量

自動化規則設計:

 1def check_incomplete_ticket_automated(ticket_content: str) -> dict:
 2    """
 3    自動化檢測 Incomplete Ticket
 4
 5    回傳格式:
 6    {
 7        "has_acceptance_criteria": bool,
 8        "acceptance_count": int,
 9        "has_test_plan": bool,
10        "test_files": list,
11        "has_work_log": bool,
12        "work_log_file": str,
13        "has_references": bool,
14        "reference_count": int,
15        "is_incomplete": bool
16    }
17    """
18    # 1. 檢查驗收條件
19    has_acceptance = has_section(ticket_content, "### 驗收條件")
20    acceptance_count = count_acceptance_items(ticket_content)
21
22    # 2. 檢查測試規劃
23    has_test_plan = has_test_keywords(ticket_content)
24    test_files = extract_test_files(ticket_content)
25
26    # 3. 檢查工作日誌
27    has_work_log = has_section(ticket_content, "### 工作日誌")
28    work_log_file = extract_work_log_file(ticket_content)
29
30    # 4. 檢查參考文件
31    has_references = has_section(ticket_content, "### 參考文件")
32    reference_count = count_references(ticket_content)
33
34    # 5. 判斷是否為 Incomplete Ticket
35    is_incomplete = not (
36        has_acceptance and acceptance_count >= 3 and
37        has_test_plan and len(test_files) > 0 and
38        has_work_log and work_log_file and
39        has_references and reference_count >= 1
40    )
41
42    return {
43        "has_acceptance_criteria": has_acceptance,
44        "acceptance_count": acceptance_count,
45        "has_test_plan": has_test_plan,
46        "test_files": test_files,
47        "has_work_log": has_work_log,
48        "work_log_file": work_log_file,
49        "has_references": has_references,
50        "reference_count": reference_count,
51        "is_incomplete": is_incomplete
52    }

C3. Ambiguous Responsibility 自動化檢測(可自動化程度: 70%):

檢測指標自動化程度自動化方法需要人工判斷
層級標示100%(合格)正則匹配 \[Layer \d+\]
職責描述50%(需檢查)檢查字數、關鍵字明確性需人工確認
檔案範圍100%(合格)檢查具體檔案路徑
驗收限定70%(需檢查)提取驗收條件的類別名稱層級一致性需人工確認

自動化規則設計:

 1def check_ambiguous_responsibility_automated(ticket_content: str) -> dict:
 2    """
 3    自動化檢測 Ambiguous Responsibility
 4
 5    回傳格式:
 6    {
 7        "has_layer_tag": bool,
 8        "layer_number": int,
 9        "has_clear_responsibility": bool,
10        "responsibility_length": int,
11        "has_file_paths": bool,
12        "file_count": int,
13        "acceptance_limited_to_layer": bool,
14        "is_ambiguous": bool,
15        "confidence": float
16    }
17    """
18    # 1. 檢查層級標示
19    has_layer_tag, layer_number = extract_layer_tag(ticket_content)
20
21    # 2. 檢查職責描述(簡化檢查)
22    responsibility = extract_responsibility(ticket_content)
23    has_clear_responsibility = len(responsibility) > 20
24
25    # 3. 檢查檔案範圍
26    file_paths = extract_file_paths(ticket_content)
27    has_file_paths = len(file_paths) > 0
28
29    # 4. 檢查驗收限定(需要層級判斷)
30    acceptance_items = extract_acceptance_items(ticket_content)
31    acceptance_layers = [
32        determine_layer_from_acceptance(item)
33        for item in acceptance_items
34    ]
35    acceptance_limited = all(
36        layer == layer_number for layer in acceptance_layers
37    )
38
39    # 5. 判斷是否為 Ambiguous Responsibility
40    is_ambiguous = not (
41        has_layer_tag and
42        has_clear_responsibility and
43        has_file_paths and
44        acceptance_limited
45    )
46
47    # 6. 計算信心度(職責描述需人工確認)
48    confidence = 0.7 if has_clear_responsibility else 0.5
49
50    return {
51        "has_layer_tag": has_layer_tag,
52        "layer_number": layer_number,
53        "has_clear_responsibility": has_clear_responsibility,
54        "responsibility_length": len(responsibility),
55        "has_file_paths": has_file_paths,
56        "file_count": len(file_paths),
57        "acceptance_limited_to_layer": acceptance_limited,
58        "is_ambiguous": is_ambiguous,
59        "confidence": confidence
60    }

需要人工判斷的項目:

項目原因人工判斷者自動化支援
Ticket 拆分合理性需要業務知識和架構經驗PM 或架構師提供拆分建議
職責定義明確性需要理解業務語意lavender-interface-designer檢測關鍵字
預估工時準確性需要評估任務複雜度PM 或開發者根據步驟數量估算
依賴關係正確性需要理解架構層級關係lavender-interface-designer檢查依賴順序

Hook 系統檢測規則(v0.12.G.4 規劃):

 1# Hook 觸發時機: Ticket 檔案修改時(PostEdit Hook)
 2
 3def ticket_quality_gate_hook(ticket_file_path: str) -> dict:
 4    """
 5    Ticket 品質閘門 Hook
 6
 7    執行時機:
 8    - Ticket 檔案儲存時
 9    - lavender-interface-designer 提交工作日誌時
10
11    回傳格式:
12    {
13        "passed": bool,
14        "c1_result": dict,
15        "c2_result": dict,
16        "c3_result": dict,
17        "suggestions": list,
18        "blocking_issues": list
19    }
20    """
21    # 讀取 Ticket 內容
22    ticket_content = read_ticket_file(ticket_file_path)
23
24    # 執行自動化檢測
25    c1_result = check_god_ticket_automated(ticket_content)
26    c2_result = check_incomplete_ticket_automated(ticket_content)
27    c3_result = check_ambiguous_responsibility_automated(ticket_content)
28
29    # 判斷是否通過
30    passed = not (
31        c1_result["is_god_ticket"] or
32        c2_result["is_incomplete"] or
33        c3_result["is_ambiguous"]
34    )
35
36    # 生成建議
37    suggestions = generate_suggestions(c1_result, c2_result, c3_result)
38
39    # 生成阻斷問題(需要立即修正)
40    blocking_issues = []
41    if c1_result["is_god_ticket"]:
42        blocking_issues.append(
43            f"God Ticket 檢測失敗: "
44            f"檔案數={c1_result['file_count']}, "
45            f"層級跨度={c1_result['layer_span']}, "
46            f"工時={c1_result['estimated_hours']}h"
47        )
48    if c2_result["is_incomplete"]:
49        blocking_issues.append(
50            f"Incomplete Ticket 檢測失敗: 缺少必要元素"
51        )
52    if c3_result["is_ambiguous"]:
53        blocking_issues.append(
54            f"Ambiguous Responsibility 檢測失敗: 職責不明確"
55        )
56
57    return {
58        "passed": passed,
59        "c1_result": c1_result,
60        "c2_result": c2_result,
61        "c3_result": c3_result,
62        "suggestions": suggestions,
63        "blocking_issues": blocking_issues
64    }
65
66# Hook 輸出範例:
67# - 品質閘門通過 → 記錄日誌,允許繼續
68# - 品質閘門失敗 → 阻止提交,提供修正建議

v0.12.G.4 實作準備清單:

  • 實作檔案路徑提取函式
  • 實作層級判斷函式(基於 v0.12.G.1 第 6.2 節)
  • 實作步驟數量計算和工時估算函式
  • 實作章節檢測函式
  • 實作驗收條件提取和驗證函式
  • 實作測試檔案檢測函式
  • 實作 Hook 整合(PostEdit Hook)
  • 撰寫 Hook 測試(模擬 Ticket 檔案)
  • 建立檢測結果日誌機制
  • 提供修正建議生成器

2.5 Ticket 大小標準和範例

Ticket 大小標準總結

類型職責檔案測試行數適用場景
Interface 定義1 個1 個0 個< 30 行定義契約
Value Object 實作1 個1 個2-3 個30-40 行簡單邏輯
Repository 實作2-3 個1 個4-6 個50-80 行CRUD 操作
Use Case 實作2-3 個2-3 個5-8 個40-70 行業務邏輯
整合驗證2-3 個2-3 個3-5 個30-50 行端到端測試

2.6 拆分決策樹

當面對一個大任務時,使用以下決策樹判斷如何拆分:

 1任務評估
 2 3├─ 是否為單一職責且檔案數 ≤ 1?
 4│  └─ Yes → 建立單一 Ticket(簡單)
 5│  └─ No  → 繼續評估
 6 7├─ 可按 Clean Architecture 分層拆分?
 8│  └─ Yes → 拆分為 4 種 Ticket
 9│  │        1. Interface 定義 Ticket
10│  │        2. 測試驗證 Ticket
11│  │        3. 具體實作 Ticket
12│  │        4. 整合連接 Ticket
13│  └─ No  → 繼續評估
1415├─ 可按功能模組拆分?
16│  └─ Yes → 拆分為多個功能 Ticket
17│  │        範例:User 模組、Book 模組、Order 模組
18│  └─ No  → 繼續評估
1920├─ 可按步驟順序拆分?
21│  └─ Yes → 拆分為多個步驟 Ticket
22│  │        範例:步驟1 資料準備、步驟2 邏輯處理、步驟3 結果輸出
23│  └─ No  → 繼續評估
2425└─ 可按 CRUD 操作拆分?
26   └─ Yes → 拆分為 Create、Read、Update、Delete Ticket
27   └─ No  → 重新分析任務結構或尋求 PM 協助

2.7 Ticket 拆分檢查清單

拆分前檢查(5 項):

  • 任務描述是否清晰明確?
  • 是否有明確的需求來源?
  • 是否理解任務的技術實作方式?
  • 是否識別所有依賴關係?
  • 是否評估職責數量、檔案數、測試數、程式碼行數?

拆分策略檢查(5 項):

  • 是否嘗試按 Clean Architecture 分層拆分?
  • 是否嘗試按功能模組拆分?
  • 是否嘗試按步驟順序拆分?
  • 拆分後的 Ticket 是否都可獨立驗收?
  • 拆分後的 Ticket 是否符合複雜度標準(職責、檔案、測試、行數)?

拆分後檢查(4 項):

  • 每個 Ticket 是否都有明確的驗收條件?
  • Ticket 間的依賴關係是否明確標註?
  • 是否有並行執行的機會?
  • 所有 Ticket 加總是否完整覆蓋原任務?

第三章:Ticket 生命週期管理

3.1 Ticket 狀態定義

Ticket 從建立到關閉經歷 4 個狀態:

狀態 1:待執行(Pending)

定義:Ticket 已建立並通過準備度檢查,等待開發者執行。

進入條件

  • Ticket 建立完成
  • 驗收條件明確
  • 依賴 Ticket 已完成(如適用)

可執行動作

  • 指派開發者
  • 調整優先級
  • 開始執行(轉為「進行中」)

流程特性:快速流轉至 In Progress

狀態 2:進行中(In Progress)

定義:開發者正在執行 Ticket。

進入條件

  • 開發者開始執行
  • 標記 Ticket 為「進行中」

可執行動作

  • 持續更新進度
  • 遇到問題記錄到 Ticket 日誌
  • 完成後提交 review(轉為「Review 中」)
  • 發現問題暫停(轉回「待執行」)

流程特性:快速完成並進入 Review

狀態 3:Review 中(In Review)

定義:Ticket 已完成執行,等待 review 驗收。

進入條件

  • 開發者認為已完成
  • 提交 review 請求

可執行動作

  • Review 檢查驗收條件
  • 通過驗收(轉為「已完成」)
  • 發現問題(轉回「進行中」,建立修正 Ticket)

流程特性:快速 Review 並決定結果

狀態 4:已完成(Completed)

定義:Ticket 通過 review 驗收,已關閉。

進入條件

  • 所有驗收條件滿足
  • Review 通過
  • 相關測試 100% 通過

可執行動作

  • 更新主版本日誌 Ticket 索引
  • 更新 todolist 任務狀態
  • 記錄完成時間和實際工時

停留時間:永久(已歸檔)

生命週期流程圖

 1建立 Ticket
 2 3待執行(Pending)
 4 5進行中(In Progress) ←─┐
 6    ↓                   │
 7Review 中(In Review)   │
 8    ↓                   │
 9  通過?                │
10    ├─ Yes → 已完成(Completed)
11    └─ No  ──────────────┘
12       (建立修正 Ticket,重新執行)

3.2 Ticket 建立標準

Ticket 標題格式

格式Ticket #N: [動詞] [目標]

動詞選擇

  • 定義:定義 Interface、定義 Entity
  • 撰寫:撰寫測試、撰寫文檔
  • 實作:實作 Repository、實作 Use Case
  • 整合:整合 Service、整合 Module
  • 修復:修復 Bug、修復測試
  • 重構:重構邏輯、重構架構

範例

  • Ticket #1: 定義 IBookRepository 介面- Ticket #2: 撰寫 BookRepository 測試- Ticket #3: 實作 SQLiteBookRepository- Ticket #1: BookRepository(缺少動詞)- 反例:做一下 Repository(不明確)

Ticket 描述內容

完整的 Ticket 必須包含以下 5 個核心欄位:

Ticket 建立模板

 1## Ticket #N: [動詞] [目標]
 2
 3### 背景
 4[為什麼需要這個 Ticket?來自哪個需求或問題?]
 5
 6### 目標
 7[這個 Ticket 要達成什麼?明確且可驗證]
 8
 9### 步驟
101. [具體步驟 1]
112. [具體步驟 2]
123. [具體步驟 3]
13
14### 驗收條件
15- [ ] [可驗證的條件 1]
16- [ ] [可驗證的條件 2]
17- [ ] [可驗證的條件 3]
18
19### 參考文件
20- [設計文件連結]
21- [需求文件連結]
22
23### 依賴 Ticket
24- Ticket #X (必須先完成)
25- Ticket #Y (可並行)

欄位說明

1. 背景

  • 說明為什麼需要這個 Ticket
  • 連結到需求或設計決策
  • 提供上下文資訊

2. 目標

  • 一句話說明要達成什麼
  • 必須明確且可驗證
  • 避免模糊用語

3. 步驟

  • 列出具體執行步驟(3-5 步)
  • 步驟必須可操作
  • 幫助開發者快速理解如何執行

4. 驗收條件

  • 列出所有可驗證的條件(3-5 項)
  • 條件必須客觀可檢查
  • 使用 checkbox 格式

5. 參考文件

  • 連結到設計文件
  • 連結到需求規格
  • 連結到相關 Ticket

6. 依賴 Ticket

  • 列出必須先完成的 Ticket
  • 列出可並行的 Ticket
  • 明確依賴關係

3.3 Ticket 執行流程

步驟 1:領取 Ticket

  • 開發者從「待執行」清單選擇 Ticket
  • 確認依賴 Ticket 已完成
  • 標記 Ticket 為「進行中」
步驟 2:閱讀 Ticket
  • 閱讀背景和目標
  • 檢查參考文件
  • 理解驗收條件
步驟 3:執行步驟
  • 按照步驟執行
  • 遇到問題記錄到 Ticket 日誌
  • 持續更新進度
步驟 4:自我檢查
  • 逐項檢查驗收條件
  • 確保所有條件滿足
  • 執行相關測試
步驟 5:提交 Review
  • 標記所有驗收條件為完成
  • 標記 Ticket 為「Review 中」
  • 通知 Reviewer
步驟 6:處理 Review 結果
  • 如果通過:Ticket 標記為「已完成」
  • 如果未通過:根據 Review 意見修正,重新執行

3.4 Ticket 驗收標準

驗收條件必須符合 SMART 原則:

S - Specific(具體)

  • 反例:「功能運作正常」(太模糊)- 正例:「呼叫 getBookByIsbn(‘123’) 回傳正確的 Book 物件」

M - Measurable(可測量)

  • 反例:「程式碼品質良好」(無法測量)- 正例:「dart analyze 0 錯誤,測試覆蓋率 > 80%」

A - Achievable(可達成)

  • 反例:「整合所有第三方 API」(範圍太大)- 正例:「整合 Google Books API 的書籍搜尋功能」

R - Relevant(相關)

  • 反例:「優化 UI 顏色」(與 Repository Ticket 無關)- 正例:「Repository 實作完成,測試通過」

T - Time-bound(有明確完成標準)

  • 反例:「未來會完成」(無明確標準)- 正例:「符合所有驗收條件即完成」

3.5 Ticket 關閉條件

Ticket 必須滿足以下所有條件才能關閉:

強制條件(5 項):

  • 所有驗收條件打勾完成
  • Review 通過
  • 相關測試 100% 通過
  • dart analyze 0 錯誤
  • 工作日誌已更新

建議條件(3 項):

  • 程式碼符合專案規範
  • 無技術債務產生
  • 文檔同步更新

3.6 生命週期管理檢查清單

Ticket 建立檢查(3 項):

  • 標題格式正確(動詞 + 目標)
  • 5 個核心欄位完整
  • 驗收條件符合 SMART 原則

Ticket 執行檢查(4 項):

  • 依賴 Ticket 已完成
  • 開發者理解目標和步驟
  • 進度持續更新
  • 遇到問題即時記錄

Ticket Review 檢查(4 項):

  • 所有驗收條件滿足
  • 測試 100% 通過
  • 程式碼品質符合標準
  • 文檔同步更新

Ticket 關閉檢查(3 項):

  • Review 通過
  • 工作日誌已更新
  • 主版本日誌索引已更新

第四章:即時 Review 機制

4.1 一邊實作一邊 review 的原則

傳統 Review 問題

傳統的「實作完成後才 review」存在以下問題:

  1. 發現問題太晚:實作偏差已形成,修正成本高
  2. 返工時間長:需要大幅修改已完成的程式碼
  3. 士氣影響大:開發者認為「白做了」,影響積極性
  4. 無法並行:必須等所有任務完成才能 review

即時 Review 原則

「一邊實作一邊 review」的核心原則:

  1. 每完成一個 Ticket 觸發 review
  2. review 快速完成,聚焦核心問題
  3. 只 review 當前 Ticket,不累積
  4. 發現問題立即建立修正 Ticket

效益

維度傳統 Review即時 Review
問題發現時機實作完成後(數天後)每個 Ticket 完成後(即時)
修正成本高(需大幅修改)低(只需修正單一 Ticket)
開發者體驗挫折感(白做了)即時回饋(快速修正)
可並行性低(必須等全部完成)高(可持續並行開發)

4.2 Review 觸發時機

觸發條件

Review 在以下時機觸發:

  1. 每完成一個 Ticket:開發者標記 Ticket 為「Review 中」
  2. 每完成 3-5 個 Ticket:觸發階段性 review(可選)
  3. 每完成一個模組:觸發模組整合 review(可選)

主要觸發機制

每完成一個 Ticket 觸發

  • 開發者完成 Ticket,自我檢查驗收條件
  • 標記 Ticket 為「Review 中」
  • Reviewer 收到通知,開始 review
  • Review 快速完成,聚焦核心問題

不等待

  • 不等待整個任務完成才 review
  • 不累積多個 Ticket 一起 review
  • 不延後 review 時機

4.3 Review 檢查項目

Review 分為 4 大類,共 16 項檢查項:

類別 1:功能正確性檢查(4 項)

檢查項 1:Ticket 描述的功能是否實現?
  • 檢查方法:對照 Ticket 目標和實際程式碼
  • 通過標準:功能完全符合 Ticket 描述
檢查項 2:驗收條件是否全部滿足?
  • 檢查方法:逐項檢查驗收條件 checkbox
  • 通過標準:所有條件都打勾且確實滿足
檢查項 3:是否有未處理的邊界情況?
  • 檢查方法:檢查 null、empty、異常輸入處理
  • 通過標準:所有邊界情況都有處理
檢查項 4:錯誤處理是否完整?
  • 檢查方法:檢查 try-catch、異常拋出
  • 通過標準:所有異常都有妥善處理

類別 2:架構合規性檢查(4 項)

檢查項 5:是否符合 Clean Architecture 分層原則?
  • 檢查方法:檢查檔案位置、模組分層
  • 通過標準:符合 Domain/Application/Infrastructure/Presentation 分層
檢查項 6:依賴方向是否正確(內層不依賴外層)?
  • 檢查方法:檢查 import 語句
  • 通過標準:所有依賴都指向內層或 Interface
檢查項 7:是否使用 Interface-Driven 開發?
  • 檢查方法:檢查是否依賴 Interface 而非具體實作
  • 通過標準:外層依賴 Interface,不直接依賴實作類別
檢查項 8:是否有架構債務產生?
  • 檢查方法:檢查是否有違反 SOLID 原則的程式碼
  • 通過標準:無明顯架構債務

類別 3:測試通過率檢查(4 項)

檢查項 9:相關單元測試是否 100% 通過?
  • 檢查方法:執行 dart testflutter test
  • 通過標準:所有測試通過,0 失敗
檢查項 10:相關整合測試是否 100% 通過?
  • 檢查方法:執行整合測試
  • 通過標準:所有整合測試通過
檢查項 11:測試覆蓋率是否達標?
  • 檢查方法:檢查測試覆蓋率報告
  • 通過標準:覆蓋率 > 80%(建議)
檢查項 12:是否有測試被 skip?
  • 檢查方法:搜尋 skip:.skip
  • 通過標準:無 skip 的測試

類別 4:文檔同步性檢查(4 項)

檢查項 13:Ticket 工作日誌是否更新?
  • 檢查方法:檢查對應的 Ticket 日誌檔案
  • 通過標準:記錄執行過程和決策
檢查項 14:設計決策是否記錄?
  • 檢查方法:檢查設計決策日誌
  • 通過標準:重要決策都有記錄
檢查項 15:API 文檔是否同步?
  • 檢查方法:檢查程式碼註解和 dartdoc
  • 通過標準:公開 API 都有完整文檔註解
檢查項 16:README 是否需要更新?
  • 檢查方法:檢查是否有新增功能或變更使用方式
  • 通過標準:如需更新則已更新

4.4 偏差糾正流程

當 Review 發現問題時,執行以下偏差糾正流程:

 1Review 發現偏差
 2 3暫停當前 Ticket
 4 5記錄偏差問題(描述、影響、根因)
 6 7分析根因
 8    ├─ 理解錯誤? → 釐清需求,重新執行
 9    ├─ 技術問題? → 尋求技術支援
10    └─ 架構問題? → 修正架構設計
1112建立修正 Ticket
1314修正 Ticket 執行
1516再次 Review
17    ├─ 通過 → 標記原 Ticket 為「已完成」
18    └─ 未通過 → 重複偏差糾正流程
1920總結經驗教訓(更新檢查清單)

偏差記錄格式

 1### Review 偏差記錄 #N
 2
 3**發現時間**:2025-10-10 14:30
 4
 5**偏差描述** 6實作的 Repository 方法簽名與 Interface 不一致
 7
 8**影響範圍** 9
10- SQLiteBookRepository.getBookByIsbn 方法
11- 相關測試需要調整
12
13**根因分析**14開發者未參考最新的 Interface 定義
15
16**糾正措施**17
18- 建立修正 Ticket:修正 Repository 方法簽名
19- 更新相關測試
20- 加入檢查清單:實作前必須確認 Interface 最新版本
21
22**責任歸屬**23開發者(未確認 Interface)+ Reviewer(未及時發現)
24
25**經驗教訓**26實作前必須先閱讀最新的 Interface 定義

4.5 Review 記錄格式

每次 Review 都必須記錄,格式如下:

 1### Review 記錄 - Ticket #N
 2
 3**Review 時間**:2025-10-10 15:00
 4
 5**Reviewer**:張三
 6
 7**Ticket 標題**:實作 SQLiteBookRepository
 8
 9**Review 結果**:通過 / 未通過
10
11**檢查項目**12
13- [x] 功能正確性(4/4 通過)
14- [x] 架構合規性(4/4 通過)
15- [x] 測試通過率(4/4 通過)
16- [x] 文檔同步性(4/4 通過)
17
18**發現問題**19
20- 無(如果有,列出問題清單)
21
22**建議改善**23
24- 建議補充更多邊界情況測試(可選)
25
26**Review 時間**:8 分鐘
27
28**下一步行動**29
30- 標記 Ticket 為「已完成」
31- 更新主版本日誌索引

4.6 即時 Review 檢查清單

Review 前準備(3 項):

  • Reviewer 收到 review 通知
  • Ticket 標記為「Review 中」
  • 所有驗收條件已打勾

Review 執行(4 項):

  • 逐項檢查 16 個檢查項目
  • 記錄 Review 結果
  • 發現問題建立偏差記錄
  • Review 快速完成,聚焦核心問題

Review 後處理(2 項):

  • 通過:標記 Ticket 為「已完成」
  • 未通過:建立修正 Ticket

持續改善(5 項):

  • 總結經驗教訓
  • 更新檢查清單(如需要)
  • 優化 Review 流程
  • 提升 Review 效率
  • 降低偏差發生率

第五章:文件管理策略

5.1 避免工作日誌臃腫的三層文件結構

問題分析:v0.12.7 工作日誌臃腫案例

v0.12.7 工作日誌問題

  • 檔案大小:6000 行
  • 問題根因
    • 所有 Ticket 日誌都寫在主版本日誌
    • 設計迭代過程全部記錄在同一檔案
    • 缺乏分層管理機制

影響

  • 開發者難以快速找到關鍵資訊
  • 檔案過大導致編輯器效能下降
  • 歷史記錄難以追溯

三層文件結構設計

為了解決工作日誌臃腫問題,採用三層文件結構:

第 1 層:主版本日誌(Main Version Log)

檔案命名vX.Y.Z-main.md 目標大小:500-800 行 內容範圍

  • 版本目標和規劃
  • Ticket 索引(只記錄 Ticket 編號和標題)
  • 設計決策索引(連結到決策日誌)
  • 版本總結

範例

 1# v0.12.7 主版本日誌
 2
 3## 版本目標
 4實現書籍資訊豐富化功能
 5
 6## Ticket 索引
 7- Ticket #1: 定義 IBookInfoEnrichmentService 介面 → [詳細日誌](/record/ticket_v2/v0.12.7-ticket-001.md)
 8- Ticket #2: 撰寫 BookInfoEnrichmentService 測試 → [詳細日誌](/record/ticket_v2/v0.12.7-ticket-002.md)
 9- Ticket #3: 實作 GoogleBooksEnrichmentService → [詳細日誌](/record/ticket_v2/v0.12.7-ticket-003.md)
10
11## 設計決策索引
12- 決策 #1: 選擇 Strategy Pattern 處理多資料源 → [詳細日誌](/record/ticket_v2/v0.12.7-design-decisions.md#決策1)
13- 決策 #2: 使用 Riverpod 管理服務註冊 → [詳細日誌](/record/ticket_v2/v0.12.7-design-decisions.md#決策2)
14
15## 版本總結
16- 完成 12 個 Ticket
17- 總開發時間:4.5 小時
18- 測試覆蓋率:92%

第 2 層:Ticket 工作日誌(Ticket Work Log)

檔案命名vX.Y.Z-ticket-NNN.md 目標大小:100-200 行 內容範圍

  • Ticket 描述(背景、目標、步驟、驗收條件)
  • 執行過程記錄
  • 遇到的問題和解決方案
  • Review 結果

範例

 1# Ticket #1 工作日誌
 2
 3## Ticket 描述
 4定義 IBookInfoEnrichmentService 介面
 5
 6### 背景
 7根據 UC-05 需求,需要建立書籍資訊豐富化服務的介面契約
 8
 9### 目標
10建立 `IBookInfoEnrichmentService` 介面,定義書籍資訊豐富化的契約
11
12### 步驟
131. 建立介面檔案
142. 定義 `enrichBook` 方法
153. 定義 `enrichProgress` 方法
164. 撰寫文檔註解
17
18### 驗收條件
19- [x] 介面檔案建立在正確位置
20- [x] 方法簽名完整且明確
21- [x] 包含完整的文檔註解
22- [x] dart analyze 0 錯誤
23
24## 執行過程
251. 建立 `lib/domains/import/services/i_book_info_enrichment_service.dart`
262. 定義 `enrichBook` 方法:接收 ISBN,回傳豐富化後的 Book
273. 定義 `enrichProgress` 方法:回傳豐富化進度 Stream
284. 補充文檔註解說明每個方法的用途
29
30## Review 結果
31通過(8 分鐘)
32- 功能正確性:4/4 通過
33- 架構合規性:4/4 通過

第 3 層:設計決策日誌(Design Decision Log)

檔案命名vX.Y.Z-design-decisions.md 目標大小:300-500 行 內容範圍

  • 重要設計決策記錄
  • 技術選型理由
  • 架構調整說明
  • 決策的影響分析

範例

 1# v0.12.7 設計決策日誌
 2
 3## 決策 #1: 選擇 Strategy Pattern 處理多資料源
 4
 5### 決策時間
 62025-10-09 14:30
 7
 8### 決策背景
 9書籍資訊豐富化需要支援多個資料來源(Google Books、Open Library、豆瓣讀書)
10
11### 可選方案
121. **方案 A**:使用 if-else 判斷資料來源
132. **方案 B**:使用 Strategy Pattern 封裝每個資料來源
143. **方案 C**:使用 Chain of Responsibility Pattern
15
16### 選擇理由
17選擇方案 B(Strategy Pattern):
18
19- 每個資料來源獨立封裝,符合 Open-Closed Principle
20- 新增資料來源只需新增 Strategy,不修改現有程式碼
21- 可以動態切換資料來源策略
22
23### 影響範圍
24- 建立 `IEnrichmentStrategy` 介面
25- 實作 `GoogleBooksStrategy``OpenLibraryStrategy`
26- `BookInfoEnrichmentService` 依賴 `IEnrichmentStrategy`
27
28### 實作 Ticket
29- Ticket #4: 定義 IEnrichmentStrategy 介面
30- Ticket #5: 實作 GoogleBooksStrategy
31- Ticket #6: 實作 OpenLibraryStrategy

三層結構效益

效益總結

維度v0.12.7 單一檔案(6000 行)三層結構(800+200*N+400 行)
可讀性低(難以快速找到資訊)高(分層清晰)
維護性低(修改影響範圍大)高(獨立修改)
查找效率低(需搜尋整個檔案)高(索引快速定位)
協作友善低(衝突機率高)高(不同檔案並行編輯)

改善數據

  • 主版本日誌:6000 行 → 800 行(減少 87%)
  • Ticket 日誌:分散到 12 個檔案,每個 150 行
  • 設計決策日誌:獨立 400 行

5.2 設計迭代文件管理

設計迭代的挑戰

問題: 設計過程中會產生多個版本的設計文件:

  • 初版設計(可能有缺陷)
  • 修正版設計(發現問題後調整)
  • 最終設計(經過 review 確認)

如果不管理

  • 開發者不知道哪個是最終版本
  • 過時的設計誤導後續開發
  • 設計演進過程難以追溯

版本管理策略

策略 1:設計檔案版本標記

在設計決策日誌中明確標記版本狀態:

 1## 決策 #1: 選擇 Strategy Pattern 處理多資料來源
 2
 3**決策狀態**:最終決策(已實作)
 4
 5**版本歷史** 6
 7- v1 (2025-10-09 14:30): 初版設計 - 使用 if-else 判斷(已廢棄)
 8- v2 (2025-10-09 15:00): 修正版 - 改用 Strategy Pattern(最終版本)
 9
10**當前版本**: v2

策略 2:最終設計明確標記

在主版本日誌中明確標記最終設計:

1## 設計決策索引
2- 決策 #1: 選擇 Strategy Pattern(最終決策)→ [詳細日誌](/record/ticket_v2/v0.12.7-design-decisions.md#決策1)
3- 決策 #2: 使用 Riverpod 管理服務(最終決策)→ [詳細日誌](/record/ticket_v2/v0.12.7-design-decisions.md#決策2)
4- ~~決策 #3: 使用 GetIt 管理服務~~(已廢棄,改用決策 #2

策略 3:廢棄設計保留但標記

不刪除過時設計,而是標記為廢棄並說明原因:

 1## ~~決策 #3: 使用 GetIt 管理服務~~(已廢棄)
 2
 3**廢棄原因** 4發現 Riverpod 更適合 Flutter 3.x,提供更好的型別安全
 5
 6**廢棄時間**:2025-10-09 16:00
 7
 8**替代決策**:決策 #2(使用 Riverpod)
 9
10**保留原因**11記錄設計演進過程,避免重複評估相同方案

5.3 開發者查找設計的指引

設計查找流程

步驟 1:從主版本日誌開始

開發者接到任務時,先查看主版本日誌:

1# v0.12.7 主版本日誌
2
3## 快速導航
4- [版本目標](#版本目標)
5- [Ticket 索引](#Ticket索引)
6- [設計決策索引](#設計決策索引)(開發者從這裡開始)

步驟 2:查看設計決策索引

根據任務相關的領域,找到對應的設計決策:

1## 設計決策索引
2
3### 服務層設計
4- 決策 #1: 選擇 Strategy Pattern(最終決策)→ [詳細](/record/ticket_v2/v0.12.7-design-decisions.md#決策1)
5- 決策 #2: 使用 Riverpod 管理服務(最終決策)→ [詳細](/record/ticket_v2/v0.12.7-design-decisions.md#決策2)
6
7### 資料層設計
8- 決策 #4: 選擇 SQLite 儲存(最終決策)→ [詳細](/record/ticket_v2/v0.12.7-design-decisions.md#決策4)

步驟 3:閱讀設計決策詳細內容

點擊連結進入設計決策日誌,閱讀詳細內容:

 1## 決策 #1: 選擇 Strategy Pattern 處理多資料來源
 2
 3**決策狀態**:最終決策(已實作)
 4
 5### 決策背景
 6...
 7
 8### 選擇理由
 9...
10
11### 影響範圍
12...
13
14### 實作 Ticket
15- Ticket #4: 定義 IEnrichmentStrategy 介面
16- Ticket #5: 實作 GoogleBooksStrategy

步驟 4:查看相關 Ticket

根據設計決策中的「實作 Ticket」,查看具體實作細節:

1# Ticket #4 工作日誌
2
3## Ticket 描述
4定義 IEnrichmentStrategy 介面
5...

設計文件索引規範

主版本日誌索引格式

 1## 設計決策索引
 2
 3### [領域名稱]
 4- 決策 #N: [決策摘要](最終決策 / 已廢棄)→ [詳細日誌連結]
 5
 6**索引規則** 7
 81. 按領域分組(服務層、資料層、UI 層)
 92. 標記決策狀態(最終決策、已廢棄)
103. 提供直接連結到詳細日誌

設計決策日誌格式

 1## 決策 #N: [決策標題]
 2
 3**決策狀態**:最終決策 / 已廢棄
 4
 5**相關 Ticket** 6
 7- Ticket #X: [Ticket 標題]
 8- Ticket #Y: [Ticket 標題]
 9
10**決策背景**:...
11**選擇理由**:...
12**影響範圍**:...

5.4 文件管理檢查清單

主版本日誌檢查(4 項):

  • 版本目標明確且可驗證
  • Ticket 索引完整(所有 Ticket 都有連結)
  • 設計決策索引清晰(按領域分組)
  • 檔案大小控制在 500-800 行

Ticket 工作日誌檢查(4 項):

  • 檔案命名符合規範(vX.Y.Z-ticket-NNN.md)
  • Ticket 描述完整(6 個核心欄位)
  • 執行過程記錄清楚
  • 檔案大小控制在 100-200 行

設計決策日誌檢查(4 項):

  • 每個決策都有明確的狀態標記
  • 廢棄決策保留但標記廢棄原因
  • 版本歷史記錄完整
  • 檔案大小控制在 300-500 行

設計文件索引檢查(4 項):

  • 主版本日誌有「快速導航」區塊
  • 設計決策索引按領域分組
  • 所有連結都正確指向目標
  • 最終決策明確標記

第六章:與敏捷重構和 TDD 的整合

6.1 Ticket 機制與三重文件原則的關係

三重文件原則回顧

本專案採用三重文件原則(CHANGELOG + todolist + work-log)進行全方位進度管理:

1. CHANGELOG.md

  • 面向用戶的版本功能描述
  • 只記錄「做了什麼」,不記錄「怎麼做」

2. todolist.md

  • 記錄整個開發過程所有待處理任務
  • 任務狀態追蹤(待執行/進行中/已完成)

3. work-log/

  • 完整的技術實作細節和決策過程
  • TDD 四階段進度追蹤

Ticket 機制如何融入三重文件

Ticket 機制定位

Ticket 機制是「work-log 層」的細化管理工具:

  • work-log 主版本日誌 = Ticket 索引 + 版本總覽
  • work-log Ticket 日誌 = 單一 Ticket 的執行記錄
  • work-log 設計決策日誌 = 設計迭代過程記錄

整合關係

1CHANGELOG.md(版本功能描述)
2    ↑ 提取功能變動
3work-log/vX.Y.Z-main.md(主版本日誌)
4    ↓ Ticket 索引
5work-log/vX.Y.Z-ticket-NNN.md(Ticket 日誌)
6    ↑ 完成狀態
7todolist.md(任務狀態追蹤)

協作流程

  1. PM 規劃階段

    • todolist.md 建立任務項目
    • vX.Y.Z-main.md 規劃 Ticket 索引
  2. 開發執行階段

    • 建立 vX.Y.Z-ticket-NNN.md Ticket 日誌
    • 執行 Ticket,記錄過程
    • 完成後更新 todolist.md 狀態
  3. 版本發布階段

    • vX.Y.Z-main.md 提取功能變動
    • 更新 CHANGELOG.md 版本說明

6.2 Ticket 與 TDD 階段的對應關係

TDD 階段與 Ticket 類型對應

Phase 1(功能設計)→ Interface 定義 Ticket

Phase 1 產出的設計決策 → 轉化為 Interface 定義 Ticket:

1Phase 1 產出:
2
3- IBookRepository 介面設計
4- IBookInfoEnrichmentService 介面設計
5
6↓ 轉化為 Ticket
7
8Ticket #1: 定義 IBookRepository 介面
9Ticket #2: 定義 IBookInfoEnrichmentService 介面

Phase 2(測試設計)→ 測試撰寫 Ticket

Phase 2 產出的測試設計 → 轉化為測試撰寫 Ticket:

1Phase 2 產出:
2
3- BookRepository 測試用例設計
4- BookInfoEnrichmentService 測試用例設計
5
6↓ 轉化為 Ticket
7
8Ticket #3: 撰寫 BookRepository 測試
9Ticket #4: 撰寫 BookInfoEnrichmentService 測試

Phase 3(實作執行)→ 具體實作 Ticket + 整合 Ticket

Phase 3 產出的實作 → 拆分為具體實作和整合 Ticket:

 1Phase 3 產出:
 2
 3- SQLiteBookRepository 實作
 4- GoogleBooksEnrichmentService 實作
 5- 整合到 Use Case
 6
 7↓ 轉化為 Ticket
 8
 9Ticket #5: 實作 SQLiteBookRepository
10Ticket #6: 實作 GoogleBooksEnrichmentService
11Ticket #7: 整合到 GetBookUseCase

Phase 4(重構優化)→ 重構 Ticket

Phase 4 發現的重構需求 → 建立重構 Ticket:

1Phase 4 發現:
2
3- BookRepository 邏輯複雜,需要拆分
4- EnrichmentService 錯誤處理不完整
5
6↓ 轉化為 Ticket
7
8Ticket #8: 重構 BookRepository,拆分 CRUD 邏輯
9Ticket #9: 補充 EnrichmentService 錯誤處理

TDD 階段完成標準與 Ticket 關係

Phase 1 完成標準

  • 所有 Interface 定義 Ticket 建立並標記為「待執行」
  • 設計決策日誌記錄完整

Phase 2 完成標準

  • 所有測試撰寫 Ticket 建立並標記為「待執行」
  • 測試覆蓋所有 Interface 方法

Phase 3 完成標準

  • 所有具體實作 Ticket 完成並通過 review
  • 所有整合 Ticket 完成並通過測試
  • 測試 100% 通過

Phase 4 完成標準

  • 所有重構 Ticket 完成並通過 review
  • 程式碼品質達標,無技術債務

6.3 Ticket 派工前的準備度檢查

準備度檢查清單

在建立和派工 Ticket 前,必須檢查以下準備度:

設計準備度(4 項):

  • 相關設計決策已完成且標記為「最終決策」
  • Interface 定義已完成(如適用)
  • 設計決策日誌已更新
  • 沒有未解決的設計問題

依賴準備度(3 項):

  • 依賴的 Ticket 已完成
  • 依賴的 Interface 已定義
  • 依賴的測試已撰寫(如適用)

資源準備度(3 項):

  • 開發者已理解 Ticket 目標
  • 開發環境已準備就緒
  • 相關文檔已閱讀

品質準備度(2 項):

  • 驗收條件明確且可驗證
  • Review 機制已建立

準備度不足的處理

發現準備度不足時

 1Ticket 派工前檢查
 2 3準備度檢查
 4    ├─ 通過 → 派工執行
 5    └─ 不通過 → 暫停派工
 6 7    分析缺失項目
 8        ├─ 設計不完整 → 補充設計決策
 9        ├─ 依賴未完成 → 等待依賴 Ticket
10        └─ 資源不足 → 準備環境和文檔
1112    重新檢查準備度

6.4 Ticket 完成後的文件更新

更新流程

每完成一個 Ticket,必須更新以下文件:

步驟 1:更新 Ticket 工作日誌

vX.Y.Z-ticket-NNN.md 記錄:

  • 執行過程
  • Review 結果
  • 遇到的問題和解決方案
步驟 2:更新主版本日誌

vX.Y.Z-main.md 更新:

  • Ticket 索引(標記為已完成)
  • 如有新的設計決策,更新設計決策索引
步驟 3:更新 todolist

todolist.md 更新:

  • 標記對應任務為「已完成」
  • 如發現新任務,新增到待辦清單
步驟 4:更新設計決策日誌(如適用)

vX.Y.Z-design-decisions.md 更新:

  • 如有設計調整,記錄新的決策版本
  • 如廢棄舊決策,標記廢棄原因

6.5 整合檢查清單

Ticket 建立檢查(4 項):

  • Ticket 來自 TDD Phase 1-4 的產出
  • Ticket 類型符合 Clean Architecture 分層
  • Ticket 已連結到設計決策日誌
  • Ticket 準備度檢查通過

Ticket 執行檢查(4 項):

  • 執行過程記錄到 Ticket 日誌
  • 完成後更新主版本日誌索引
  • 完成後更新 todolist 狀態
  • 如有設計調整,更新設計決策日誌

文件同步檢查(4 項):

  • Ticket 日誌大小控制在 100-200 行
  • 主版本日誌索引保持最新
  • 設計決策狀態正確標記
  • todolist 任務狀態與實際一致

第七章:實務案例和模板

7.1 v0.12.7 工作日誌臃腫問題分析

原始問題描述

v0.12.7 版本資訊

  • 功能範圍:書籍資訊豐富化功能
  • 工作日誌大小:6000 行
  • 開發時間:5 天
  • Ticket 數量:未明確拆分

臃腫問題根因

根因 1:缺乏 Ticket 拆分機制
  • 所有實作細節都寫在主版本日誌
  • 沒有建立獨立的 Ticket 日誌
  • 設計迭代過程全部記錄在同一檔案
根因 2:設計迭代未分層管理
  • 初版設計、修正版設計、最終設計混在一起
  • 廢棄的設計沒有明確標記
  • 開發者難以找到最終設計
根因 3:缺乏文件索引機制
  • 沒有 Ticket 索引
  • 沒有設計決策索引
  • 開發者需搜尋整個檔案才能找到資訊

問題影響分析

影響 1:開發效率降低
  • 開發者花費 30% 時間搜尋設計資訊
  • 編輯器效能下降(檔案過大)
  • 協作衝突頻繁(多人編輯同一檔案)
影響 2:品質風險增加
  • 使用過時的設計實作(找錯版本)
  • Review 困難(難以理解上下文)
  • 技術債務累積(沒時間重構)
影響 3:知識傳承困難
  • 新成員難以快速理解設計演進
  • 歷史決策難以追溯
  • 重複犯錯(不知道為什麼廢棄某設計)

7.2 基於 Ticket 機制的改善方案

改善方案設計

方案目標: 將 6000 行主版本日誌改善為三層文件結構,控制在約 2000 行總量(800+200*6+400)。

改善步驟

步驟 1:Ticket 拆分(回溯分析)

分析 v0.12.7 的開發過程,回溯拆分為 12 個 Ticket:

Domain 層 Ticket(3 個):

  • Ticket #1: 定義 IBookInfoEnrichmentService 介面
  • Ticket #2: 定義 IEnrichmentStrategy 介面
  • Ticket #3: 定義 EnrichmentProgress Value Object

Application 層 Ticket(2 個):

  • Ticket #4: 定義 EnrichBookUseCase 介面
  • Ticket #5: 實作 EnrichBookInteractor

Infrastructure 層 Ticket(4 個):

  • Ticket #6: 實作 GoogleBooksStrategy
  • Ticket #7: 實作 OpenLibraryStrategy
  • Ticket #8: 實作 BookInfoEnrichmentService
  • Ticket #9: 實作 Riverpod Provider 註冊

測試 Ticket(3 個):

  • Ticket #10: 撰寫 BookInfoEnrichmentService 測試
  • Ticket #11: 撰寫 EnrichBookInteractor 測試
  • Ticket #12: 撰寫整合測試
步驟 2:建立三層文件結構

主版本日誌(800 行):

 1# v0.12.7 主版本日誌
 2
 3## 快速導航
 4- [版本目標](#版本目標)
 5- [Ticket 索引](#Ticket索引)(12 個 Ticket)
 6- [設計決策索引](#設計決策索引)(5 個決策)
 7- [版本總結](#版本總結)
 8
 9## Ticket 索引
10
11### Domain 層
12- Ticket #1: 定義 IBookInfoEnrichmentService 介面 → [詳細](/record/ticket_v2/v0.12.7-ticket-001.md)
13- Ticket #2: 定義 IEnrichmentStrategy 介面 → [詳細](/record/ticket_v2/v0.12.7-ticket-002.md)
14- Ticket #3: 定義 EnrichmentProgress Value Object → [詳細](/record/ticket_v2/v0.12.7-ticket-003.md)
15
16### Application 層
17- Ticket #4: 定義 EnrichBookUseCase 介面 → [詳細](/record/ticket_v2/v0.12.7-ticket-004.md)
18- Ticket #5: 實作 EnrichBookInteractor → [詳細](/record/ticket_v2/v0.12.7-ticket-005.md)
19...

Ticket 工作日誌(200 行 × 12 = 2400 行,分散到 12 個檔案):

 1# Ticket #1 工作日誌
 2
 3## Ticket 描述
 4定義 IBookInfoEnrichmentService 介面
 5
 6### 背景
 7根據 UC-05 需求,需要建立書籍資訊豐富化服務的介面契約
 8...
 9
10## 執行過程
111. 建立介面檔案
122. 定義方法簽名
13...
14
15## Review 結果
16通過(8 分鐘)

設計決策日誌(400 行):

 1# v0.12.7 設計決策日誌
 2
 3## 決策 #1: 選擇 Strategy Pattern 處理多資料源
 4
 5**決策狀態**:最終決策(已實作)
 6
 7**版本歷史** 8
 9- v1 (2025-10-09 14:30): 初版設計 - 使用 if-else 判斷(已廢棄)
10- v2 (2025-10-09 15:00): 修正版 - 改用 Strategy Pattern(最終版本)
11...

步驟 3:建立設計文件索引

在主版本日誌建立清晰的索引:

1## 設計決策索引
2
3### 服務層設計
4- 決策 #1: 選擇 Strategy Pattern(最終決策)→ [詳細](/record/ticket_v2/v0.12.7-design-decisions.md#決策1)
5- 決策 #2: 使用 Riverpod 管理服務(最終決策)→ [詳細](/record/ticket_v2/v0.12.7-design-decisions.md#決策2)
6
7### 資料來源設計
8- 決策 #3: Google Books 為主要資料源(最終決策)→ [詳細](/record/ticket_v2/v0.12.7-design-decisions.md#決策3)
9- ~~決策 #4: 豆瓣讀書為備用資料源~~(已廢棄,API 限制)

改善效果評估

檔案大小改善

維度改善前改善後改善幅度
主版本日誌6000 行800 行-87%
Ticket 日誌0(混在主日誌)200 行 × 12 = 2400 行分散管理
設計決策日誌0(混在主日誌)400 行獨立管理
總計6000 行(單一檔案)3600 行(14 個檔案)-40% 且分散

查找效率改善

任務改善前改善後效率提升
找到特定 Ticket搜尋 6000 行查索引 → 直接開啟90% ↑
找到最終設計搜尋全文查設計決策索引85% ↑
理解設計演進難以追溯查版本歷史80% ↑

7.3 Ticket 模板集合

模板 1:Interface 定義 Ticket

 1## Ticket #N: 定義 [Interface 名稱] 介面
 2
 3### 背景
 4根據 [需求編號] 需求,需要建立 [功能描述] 的介面契約
 5
 6### 目標
 7建立 `[Interface 名稱]` 介面,定義 [功能描述] 的契約
 8
 9### 步驟
101.`lib/domains/[domain]/[layer]/` 建立 `[interface_file].dart`
112. 定義 `[method1]` 方法簽名
123. 定義 `[method2]` 方法簽名
134. 撰寫文檔註解
14
15### 驗收條件
16- [ ] Interface 檔案建立在正確位置
17- [ ] 所有方法簽名完整且明確
18- [ ] 輸入輸出類型定義清楚
19- [ ] 包含完整的文檔註解
20- [ ] dart analyze 0 錯誤
21
22### 參考文件
23- [設計文件連結]
24- [需求文件連結]
25
26### 依賴 Ticket
27- 無(Interface 定義通常是第一個 Ticket)

模板 2:具體實作 Ticket

 1## Ticket #N: 實作 [類別名稱]
 2
 3### 背景
 4根據 [Interface 名稱] 介面契約,實作 [功能描述]
 5
 6### 目標
 7實作 `[類別名稱]`,提供 [功能描述]
 8
 9### 步驟
101. 建立 `[類別名稱]` 類別
112. 實作 `[method1]` 方法
123. 實作 `[method2]` 方法
134. 處理異常情況
145. 確保所有測試通過
15
16### 驗收條件
17- [ ] 實作所有 [Interface 名稱] 方法
18- [ ] 異常處理完整(列出可能的異常)
19- [ ] 單元測試 100% 通過
20- [ ] dart analyze 0 錯誤
21
22### 參考文件
23- [Interface 定義 Ticket]
24- [設計決策日誌]
25
26### 依賴 Ticket
27- Ticket #X: 定義 [Interface 名稱] 介面(必須先完成)

模板 3:測試撰寫 Ticket

 1## Ticket #N: 撰寫 [類別名稱] 測試
 2
 3### 背景
 4`[類別名稱]` 撰寫完整的測試用例,確保功能正確性
 5
 6### 目標
 7撰寫 `[類別名稱]` 的完整測試用例
 8
 9### 步驟
101. 建立測試檔案 `[test_file]_test.dart`
112. 撰寫 `[method1]` 測試(正常流程 + 異常處理)
123. 撰寫 `[method2]` 測試(正常流程 + 異常處理)
134. 確保所有測試通過
14
15### 驗收條件
16- [ ] 測試檔案建立在 `test/unit/[path]/`
17- [ ] 至少 [N] 個測試用例
18- [ ] 覆蓋所有方法的正常流程
19- [ ] 覆蓋所有方法的異常處理
20- [ ] 所有測試 100% 通過
21
22### 參考文件
23- [Interface 定義 Ticket]
24- [測試設計文件]
25
26### 依賴 Ticket
27- Ticket #X: 定義 [Interface 名稱] 介面(必須先完成)

模板 4:整合連接 Ticket

 1## Ticket #N: 整合 [Module A] 到 [Module B]
 2
 3### 背景
 4`[Module A]` 整合到 `[Module B]`,實現完整流程
 5
 6### 目標
 7連接 [Module A] 和 [Module B],實現端到端功能
 8
 9### 步驟
101. 修改 `[Module B]` 注入 `[Module A Interface]`
112.`[method]` 方法中呼叫 `[Module A].[method]`
123. 處理 [Module A] 的異常
134. 撰寫整合測試驗證端到端流程
145. 確保所有測試通過
15
16### 驗收條件
17- [ ] `[Module B]` 正確注入 `[Module A Interface]`
18- [ ] 端到端流程正常運作
19- [ ] 整合測試 100% 通過
20- [ ] 異常處理完整
21
22### 參考文件
23- [Module A 實作 Ticket]
24- [Module B 實作 Ticket]
25- [整合設計文件]
26
27### 依賴 Ticket
28- Ticket #X: 實作 [Module A](必須先完成)
29- Ticket #Y: 實作 [Module B](必須先完成)

模板 5:重構 Ticket

 1## Ticket #N: 重構 [功能描述]
 2
 3### 背景
 4Phase 4 發現 [問題描述],需要重構改善
 5
 6### 目標
 7重構 `[類別名稱]`,[改善目標]
 8
 9### 步驟
101. 分析當前程式碼問題
112. 設計重構方案
123. 執行重構(保持測試通過)
134. 驗證功能未受影響
145. 確保所有測試通過
15
16### 驗收條件
17- [ ] 重構完成,程式碼品質改善
18- [ ] 所有測試 100% 通過(功能未受影響)
19- [ ] dart analyze 0 錯誤
20- [ ] 無新的技術債務產生
21
22### 參考文件
23- [Phase 4 重構報告]
24- [程式碼品質標準]
25
26### 依賴 Ticket
27- 無(重構可獨立進行)

7.4 常見錯誤和解決方案

錯誤 1:Ticket 拆分過細或過粗

問題描述

  • 過細:Ticket 的職責過於單一,失去獨立交付價值
  • 過粗:Ticket 包含過多職責(>5 個)或檔案(>5 個),失去即時 review 的效益

解決方案

  • 標準複雜度:控制在單一職責或少數相關職責
  • 過細時:合併相關的小 Ticket 形成完整職責
  • 過粗時:按 Clean Architecture 分層或步驟拆分

範例

1反例 - 過細拆分:
2
3- Ticket #1: 建立檔案(職責不完整)
4- Ticket #2: 定義 class(職責不完整)
5- Ticket #3: 撰寫註解(職責不完整)
6
7正例 - 合理拆分:
8
9- Ticket #1: 定義 Interface(包含建立檔案、定義 class、撰寫註解 - 完整職責)

錯誤 2:驗收條件模糊

問題描述: 驗收條件使用主觀描述,無法客觀驗證。

錯誤範例

1反例 - 模糊的驗收條件:
2
3- [ ] 功能運作正常
4- [ ] 程式碼品質良好
5- [ ] 效能可接受

正確範例

1正例 - 明確的驗收條件:
2
3- [ ] 呼叫 getBookByIsbn('123') 回傳正確的 Book 物件
4- [ ] dart analyze 0 錯誤,測試覆蓋率 > 80%
5- [ ] API 回應時間 < 500ms 100 筆資料下

解決方案: 使用 SMART 原則撰寫驗收條件(Specific, Measurable, Achievable, Relevant, Time-bound)。

錯誤 3:忽略 Ticket 依賴關係

問題描述: 沒有明確標註 Ticket 間的依賴關係,導致執行順序錯誤。

錯誤範例

1反例 - 缺少依賴標註:
2
3- Ticket #1: 實作 Repository
4- Ticket #2: 定義 Repository Interface

正確範例

1正例 - 明確依賴關係:
2
3- Ticket #1: 定義 IBookRepository 介面
4- Ticket #2: 實作 SQLiteBookRepository
5  依賴:Ticket #1(必須先完成)

解決方案

  • Interface 定義 Ticket 優先於實作 Ticket
  • 測試撰寫 Ticket 可與實作 Ticket 並行
  • 整合 Ticket 必須等待所有依賴 Ticket 完成

錯誤 4:Review 累積延後

問題描述: 等待多個 Ticket 完成後才一起 review,失去即時 review 的效益。

錯誤做法

1完成 Ticket #1 → 繼續 Ticket #2 → 繼續 Ticket #3 → 一起 Review
2(問題:Ticket #1 的錯誤到 Review 時才發現,已完成 #2、#3,需大量返工)

正確做法

1完成 Ticket #1 → Review #1 → 完成 Ticket #2 → Review #2 → 完成 Ticket #3 → Review #3
2(好處:每個 Ticket 完成後立即發現問題,修正成本低)

解決方案

  • 每完成一個 Ticket 立即觸發 review
  • Review 快速完成,聚焦核心問題
  • 發現問題立即建立修正 Ticket

錯誤 5:工作日誌未同步更新

問題描述: Ticket 完成後未更新工作日誌,導致文件與實際進度不一致。

解決方案: 每完成一個 Ticket 必須執行以下更新:

  1. 更新 Ticket 工作日誌(記錄執行過程和 Review 結果)
  2. 更新主版本日誌 Ticket 索引(標記為已完成)
  3. 更新 todolist 任務狀態
  4. 如有設計調整,更新設計決策日誌

7.5 完整 Ticket 設計檢查清單

Ticket 建立階段檢查清單(10 項)

基本資訊(3 項):

  • Ticket 標題格式正確(動詞 + 目標)
  • Ticket 編號唯一且連續
  • Ticket 分類明確(Interface/實作/測試/整合/重構)

內容完整性(6 項):

  • 背景欄位說明來源(需求或設計決策)
  • 目標欄位明確且可驗證
  • 步驟欄位具體且可操作(3-5 步)
  • 驗收條件符合 SMART 原則(3-5 項)
  • 參考文件連結正確
  • 依賴 Ticket 明確標註

Ticket 執行階段檢查清單(8 項)

執行前檢查(3 項):

  • 依賴 Ticket 已完成
  • 相關設計決策已確認為「最終決策」
  • 開發者已理解目標和步驟

執行中檢查(3 項):

  • Ticket 標記為「進行中」
  • 執行過程記錄到 Ticket 日誌
  • 遇到問題即時記錄

執行後檢查(2 項):

  • 所有驗收條件已滿足
  • Ticket 標記為「Review 中」

Ticket Review 階段檢查清單(16 項)

功能正確性(4 項):

  • Ticket 描述的功能是否實現?
  • 驗收條件是否全部滿足?
  • 是否有未處理的邊界情況?
  • 錯誤處理是否完整?

架構合規性(4 項):

  • 是否符合 Clean Architecture 分層原則?
  • 依賴方向是否正確(內層不依賴外層)?
  • 是否使用 Interface-Driven 開發?
  • 是否有架構債務產生?

測試通過率(4 項):

  • 相關單元測試是否 100% 通過?
  • 相關整合測試是否 100% 通過?
  • 測試覆蓋率是否達標(> 80%)?
  • 是否有測試被 skip?

文檔同步性(4 項):

  • Ticket 工作日誌是否更新?
  • 設計決策是否記錄?
  • API 文檔是否同步?
  • README 是否需要更新?

Ticket 關閉階段檢查清單(8 項)

強制條件(5 項):

  • 所有驗收條件打勾完成
  • Review 通過
  • 相關測試 100% 通過
  • dart analyze 0 錯誤
  • 工作日誌已更新

建議條件(3 項):

  • 程式碼符合專案規範
  • 無技術債務產生
  • 文檔同步更新

文件版本: v1.0.0(完整版) 最後更新: 2025-10-10