<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Ticket on Tarragon</title><link>https://tarrragon.github.io/blog/tags/ticket/</link><description>Recent content in Ticket on Tarragon</description><generator>Hugo -- gohugo.io</generator><language>zh-TW</language><copyright>Tarragon (CC BY 4.0)</copyright><lastBuildDate>Wed, 04 Mar 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://tarrragon.github.io/blog/tags/ticket/index.xml" rel="self" type="application/rss+xml"/><item><title>Code Smell 品質閘門檢測方法論</title><link>https://tarrragon.github.io/blog/record/code-smell-%E5%93%81%E8%B3%AA%E9%96%98%E9%96%80%E6%AA%A2%E6%B8%AC%E6%96%B9%E6%B3%95%E8%AB%96/</link><pubDate>Wed, 04 Mar 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/record/code-smell-%E5%93%81%E8%B3%AA%E9%96%98%E9%96%80%E6%AA%A2%E6%B8%AC%E6%96%B9%E6%B3%95%E8%AB%96/</guid><description>&lt;p>Ticket 設計完成後才發現職責不清、範圍過大——這時程式碼都已經寫了，修正成本才是真正的問題所在。&lt;/p>
&lt;p>我們在專案中建立了一套設計階段品質閘門：&lt;strong>在 Ticket 進入 Phase 2 之前強制執行 C1/C2/C3 三項檢測。&lt;/strong> 問題在文字階段就抓出來，修正只需幾分鐘；等到程式碼都寫好了，才是幾個小時起跳的代價。&lt;/p></description><content:encoded><![CDATA[<p>Ticket 設計完成後才發現職責不清、範圍過大——這時程式碼都已經寫了，修正成本才是真正的問題所在。</p>
<p>我們在專案中建立了一套設計階段品質閘門：<strong>在 Ticket 進入 Phase 2 之前強制執行 C1/C2/C3 三項檢測。</strong> 問題在文字階段就抓出來，修正只需幾分鐘；等到程式碼都寫好了，才是幾個小時起跳的代價。</p>
<h2 id="三層檢測標準">三層檢測標準</h2>
<p><strong>C1 God Ticket</strong>：超過 10 個檔案、跨越超過 2 個架構層、或預估超過 16 小時，判定過大，必須拆分。</p>
<p><strong>C2 Incomplete Ticket</strong>：驗收條件少於 3 個可量化項目、缺少測試規劃、未定義工作日誌名稱、無參考文件連結——任一缺失，Ticket 不完整。</p>
<p><strong>C3 Ambiguous Responsibility</strong>：標題缺少層級標示（如 <code>[Layer 5]</code>）、目標含複合職責（出現「和」或「或」）、步驟用「相關檔案」而非具體路徑、驗收條件跨層——任一模糊，需重新定義。</p>
<h2 id="檢測順序的設計邏輯">檢測順序的設計邏輯</h2>
<p>固定執行順序：<strong>C1 → C3 → C2</strong>。</p>
<p>C1 最先，因為一旦判定 God Ticket，拆分後產生多個新 Ticket，C2/C3 的分析全部作廢要重來。C3 排第二，職責不清的 Ticket，補充驗收條件也會是模糊的。C2 最後，在範圍合理、職責明確的基礎上，確認必要元素齊全。</p>
<h2 id="執行流程">執行流程</h2>
<h3 id="step-1c1-god-ticket-檢測">Step 1：C1 God Ticket 檢測</h3>
<p>從 Ticket 的步驟章節提取所有檔案路徑，計算檔案數量。接著使用檔案路徑分析法判斷每個檔案所屬的架構層：</p>
<ul>
<li><code>lib/presentation/widgets/</code>、<code>lib/presentation/pages/</code> 屬於 Layer 1（UI 層）</li>
<li><code>lib/presentation/controllers/</code>、<code>lib/presentation/view_models/</code> 屬於 Layer 2（行為層）</li>
<li><code>lib/application/use_cases/</code>、<code>lib/application/services/</code> 屬於 Layer 3（UseCase 層）</li>
<li><code>lib/domain/repositories/</code>（介面）、<code>lib/domain/events/</code> 屬於 Layer 4（Domain 介面層）</li>
<li><code>lib/domain/entities/</code>、<code>lib/domain/value_objects/</code>、<code>lib/infrastructure/</code> 屬於 Layer 5（Domain 實作層）</li>
</ul>
<p>層級跨度 = 最高層 - 最低層。如果有檔案分佈在 Layer 1 到 Layer 5，層級跨度就是 4，遠超過 2 的上限。</p>
<p>預估工時根據步驟數量與複雜度係數評估：步驟數 × 平均每步時間 × 複雜度係數（1.0 到 2.0）。</p>
<p>檢測失敗時，依序嘗試三種拆分策略：</p>
<ol>
<li>按層級拆分（優先）：將跨層的 Ticket 按架構層拆成多個</li>
<li>按職責拆分（次要）：將工時過長的 Ticket 按職責邊界拆分</li>
<li>按功能模組拆分（最終）：將職責過多的 Ticket 按功能模組拆分</li>
</ol>
<p>拆分後的每個子 Ticket 都需要重新執行 C1 檢測。</p>
<h3 id="step-2c3-ambiguous-responsibility-檢測">Step 2：C3 Ambiguous Responsibility 檢測</h3>
<p>確認四個要素：</p>
<ul>
<li><strong>層級標示</strong>：標題包含 <code>[Layer X]</code> 標籤</li>
<li><strong>職責描述</strong>：目標章節無「和」或「或」的複合描述</li>
<li><strong>檔案範圍</strong>：步驟列出具體路徑，而非「相關檔案」</li>
<li><strong>驗收限定</strong>：驗收條件不出現跨層項目</li>
</ul>
<p>任一不符，依序修正：明確層級 → 重寫職責 → 列出具體檔案 → 限定驗收範圍。</p>
<h3 id="step-3c2-incomplete-ticket-檢測">Step 3：C2 Incomplete Ticket 檢測</h3>
<p>確認四個必要元素都存在：</p>
<ul>
<li><strong>驗收條件</strong>：3 個以上可量化、可驗證的項目（「程式碼品質提升」這種描述不算）</li>
<li><strong>測試規劃</strong>：明確的測試檔案路徑和對應的測試項目</li>
<li><strong>工作日誌</strong>：定義好工作日誌的檔案名稱（而非「待填寫」）</li>
<li><strong>參考文件</strong>：至少 1 個有效的文件連結</li>
</ul>
<p>缺少哪個就補哪個，沒有例外。</p>
<h3 id="step-4提交審查">Step 4：提交審查</h3>
<p>所有 Ticket 通過 C1/C2/C3 之後，生成品質閘門檢測報告，提交 PM 審查。PM 批准後才能進入 Phase 2。</p>
<h2 id="阻斷機制與執行時機">阻斷機制與執行時機</h2>
<p>任何 Ticket 未通過 C1/C2/C3，<strong>禁止進入 Phase 2</strong>。不是建議，是硬性規定。問題立即修正，所有過程寫入工作日誌。</p>
<p>執行時機有三個：設計完成後立即檢測、PM 分派前確認報告、PM 審查時以報告作依據。三個時機缺一不可——缺了任何一個，閘門就會有漏網之魚。</p>
<h2 id="實際效益">實際效益</h2>
<p>最直接的改變是：開發者接到 Ticket 時就已經有明確範圍、清楚職責、具體驗收標準，不需要反覆確認。</p>
<p>更重要的是，因為修正成本真的很低，團隊才會認真對待每一次品質閘門，而不是當作走形式。一旦修正成本高，就會開始討價還價、局部修正、累積技術債——品質閘門也就形同虛設。</p>]]></content:encoded></item><item><title>Ticket 生命週期管理方法論</title><link>https://tarrragon.github.io/blog/record/ticket-%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F%E7%AE%A1%E7%90%86%E6%96%B9%E6%B3%95%E8%AB%96/</link><pubDate>Wed, 04 Mar 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/record/ticket-%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F%E7%AE%A1%E7%90%86%E6%96%B9%E6%B3%95%E8%AB%96/</guid><description>&lt;p>某個深夜追查 Bug，打開 Ticket 系統看到的是：「修復書籍搜尋問題」、「要加那個功能」、「上次說的那個」。沒有驗收條件，沒有步驟，只有模糊標題。Reviewer 不知道該查什麼，開發者不確定自己算不算完成，PM 無法判斷能不能關掉。&lt;/p>
&lt;p>這讓我們認真思考：Ticket 不只是一張便利貼，它是任務的完整生命週期。&lt;/p></description><content:encoded><![CDATA[<p>某個深夜追查 Bug，打開 Ticket 系統看到的是：「修復書籍搜尋問題」、「要加那個功能」、「上次說的那個」。沒有驗收條件，沒有步驟，只有模糊標題。Reviewer 不知道該查什麼，開發者不確定自己算不算完成，PM 無法判斷能不能關掉。</p>
<p>這讓我們認真思考：Ticket 不只是一張便利貼，它是任務的完整生命週期。</p>
<h2 id="四個狀態一條主線">四個狀態，一條主線</h2>
<p><strong>待執行（Pending）</strong>：Ticket 準備好但還沒人開始。進入條件是標題格式正確、五個核心欄位填寫完整、前置依賴都已完成。</p>
<p><strong>進行中（In Progress）</strong>：核心紀律是即時記錄，遇到問題就寫進日誌，不要等到最後才回憶。我們設的建議上限是 8 小時——超過通常代表 Ticket 太大，需要拆分。</p>
<p><strong>Review 中（In Review）</strong>：第三方驗證。重點聚焦在驗收條件：逐項打勾，要麼通過要麼不通過。建議 1-2 小時內完成，避免卡住流程。</p>
<p><strong>已完成（Completed）</strong>：不可逆的終態。進入條件：所有驗收條件打勾、Review 通過、測試 100% 通過、靜態分析 0 錯誤、工作日誌更新。缺一不可。</p>
<h2 id="ticket-標題動詞加目標">Ticket 標題：動詞加目標</h2>
<p>標準格式是「動詞 + 目標」。動詞選擇反映任務類型：「定義」用於介面或規範，「撰寫」用於測試文件，「實作」用於具體功能，「修復」用於 Bug，「重構」用於改善結構。</p>
<p>對比：「做 Repository」和「實作 SQLiteBookRepository」——後者讓人在領取前就知道工作規模。</p>
<h2 id="五個核心欄位">五個核心欄位</h2>
<p>每張 Ticket 必須有這五個欄位：</p>
<p><strong>背景</strong>說明為什麼需要這個任務，讓三個月後的自己也能理解來龍去脈，不用去問當初的人。</p>
<p><strong>目標</strong>一句話說清楚要達成什麼，建議不超過 30 字。可驗證的目標：「實作 SQLiteBookRepository，符合 IBookRepository 介面，通過所有單元測試」。不可驗證的：「優化資料儲存」。</p>
<p><strong>步驟</strong>列 3-5 個具體動作，每個指明操作對象和預期結果。目的是讓人一領取就知道從哪裡開始。</p>
<p><strong>驗收條件</strong>是任務的契約，必須客觀可勾選。不是「程式碼品質良好」，而是「dart analyze 0 錯誤」；不是「測試通過」，而是「覆蓋率 100%，通過率 100%」。</p>
<p><strong>參考文件</strong>連結設計文件、需求規格、相關 Ticket，讓執行者有完整上下文。</p>
<h2 id="執行的七個步驟">執行的七個步驟</h2>
<p><strong>領取</strong>前先確認依賴都完成，工作量合理再標記進行中。</p>
<p><strong>閱讀</strong>背景和目標，把參考文件看完再動手。</p>
<p><strong>執行</strong>時遇到問題即時記進日誌。</p>
<p><strong>自檢</strong>時逐項勾選驗收條件，全過才進下一步。</p>
<p><strong>提交</strong>時標記為 Review，附上自我檢查結果。</p>
<p><strong>處理 Review 結果</strong>，通過則關閉，未通過根據反饋修正再提交。</p>
<p><strong>記錄經驗</strong>——這一步最容易省略，也最有長期價值。Ticket 完成時回答：學到了什麼？有什麼可改進的地方？是否需要建立 error-pattern 防止重複？知識沉澱進系統，才不會只留在某個人腦子裡。</p>
<h2 id="阻塞狀態的積極處理">阻塞狀態的積極處理</h2>
<p>Blocked 最容易被誤用：標記了就等著。我們的原則是阻塞不超過 24 小時，必須採取行動。</p>
<p>行動方式取決於原因：缺前置條件就派發前置任務；技術問題不清楚就建調查任務；需要決策就建評估任務。把「被動等待」轉成「積極解除」，每個阻塞都變成一個有人負責的子任務。</p>
<h2 id="結語">結語</h2>
<p>從「修復那個問題」到「修復書籍搜尋在 ISBN 格式不一致時回傳空結果的問題」，這個距離比看起來近。只需要一點紀律，和對「完成」這件事更認真的態度。</p>]]></content:encoded></item><item><title>Ticket 設計派工方法論</title><link>https://tarrragon.github.io/blog/record/ticket-%E8%A8%AD%E8%A8%88%E6%B4%BE%E5%B7%A5%E6%96%B9%E6%B3%95%E8%AB%96/</link><pubDate>Wed, 04 Mar 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/record/ticket-%E8%A8%AD%E8%A8%88%E6%B4%BE%E5%B7%A5%E6%96%B9%E6%B3%95%E8%AB%96/</guid><description>&lt;p>開發 book_overview_app 某個版本時，工作日誌膨脹到 6000 行，查一個設計決策要上下滾半天，不同人同時修改同一份文件也頻繁衝突。這不是個別案例，大型功能開發幾乎必然會遇到。&lt;/p>
&lt;p>我們的解法是建立一套 Ticket 設計派工方法論。這篇文章記錄實踐方式和核心概念，以及後來加入的積極派發原則。&lt;/p></description><content:encoded><![CDATA[<p>開發 book_overview_app 某個版本時，工作日誌膨脹到 6000 行，查一個設計決策要上下滾半天，不同人同時修改同一份文件也頻繁衝突。這不是個別案例，大型功能開發幾乎必然會遇到。</p>
<p>我們的解法是建立一套 Ticket 設計派工方法論。這篇文章記錄實踐方式和核心概念，以及後來加入的積極派發原則。</p>
<h2 id="為什麼需要-ticket">為什麼需要 Ticket？</h2>
<p>工作日誌已經記錄了一切，為什麼還需要 Ticket？</p>
<p>兩者定位不同。工作日誌是「記錄層」，給未來的開發者看，記錄決策脈絡。Ticket 是「執行層」，給正在做事的人看，代表一個可以獨立完成、驗收、追蹤的最小任務單位。</p>
<p>一個 Ticket 有幾個核心特徵：獨立性（可以獨立執行和驗收）、原子性（不可再分割）、可驗證性（有明確的完成標準），以及單一職責（一個動詞加上一個目標）。</p>
<h2 id="單一職責是拆分-ticket-的唯一標準">單一職責是拆分 Ticket 的唯一標準</h2>
<p>方法論早期我們用量化指標判斷是否需要拆分：職責數量、檔案數量、測試案例數、行數。直觀，但實際用起來有問題：一個 100 行的 Ticket 可能職責非常清楚，完全不需要拆；一個 30 行的如果混了兩個不相關的目標，就應該拆。數字不能反映語義。</p>
<p>後來改為四個語義檢查：</p>
<p><strong>語義檢查</strong>：能用「動詞加單一目標」描述嗎？描述時出現「並且」或「以及」，通常需要拆。</p>
<p><strong>修改原因檢查</strong>：只有一個原因會觸發修改嗎？兩個不同的業務規則各自可能觸發修改，就是兩個 Ticket。</p>
<p><strong>驗收一致性</strong>：所有驗收條件都指向同一個目標嗎？</p>
<p><strong>依賴獨立性</strong>：拆分後不會產生循環依賴嗎？</p>
<p>這四個問題比任何量化指標都更接近本質。</p>
<p>驗收條件的標準也要說清楚：「功能正常」不夠，「所有單元測試通過且 dart analyze 輸出 0 個問題」才算。</p>
<h2 id="ticket-與-clean-architecture-的對應">Ticket 與 Clean Architecture 的對應</h2>
<p>我們的專案用 Clean Architecture，Ticket 設計也遵循同樣的分層邏輯。</p>
<p>Interface 定義優先於具體實作。每個功能模組先建 Interface 定義的 Ticket，再建具體實作的 Ticket。這樣外層可以依賴 Interface 先行開發，不被內層實作進度卡住。</p>
<p>分層拆分讓每個 Ticket 待在自己的架構層，Domain、Application、Infrastructure、Presentation 層的 Ticket 不互相混合，也更容易並行執行。</p>
<h2 id="即時-review在問題發生當下就解決">即時 Review：在問題發生當下就解決</h2>
<p>傳統 code review 在整個版本完成後進行，此時修正成本很高，問題可能已經影響了許多後續實作。</p>
<p>我們改為每個 Ticket 完成時立即觸發 Review。因為範圍只有單一 Ticket 的相關程式碼，Review 者不需要理解整個版本的脈絡，反饋在數小時內完成，修正成本極低。</p>
<p>Review 涵蓋四個面向：功能正確性（功能實現、驗收條件、邊界情況、錯誤處理）、架構合規性（Clean Architecture、依賴方向、Interface-Driven、架構債務）、測試通過率（單元測試、整合測試、覆蓋率、跳過測試）、文件同步性（Ticket 日誌、設計決策、API 文件、README），共 16 項。</p>
<h2 id="三層文件結構讓-6000-行問題消失">三層文件結構：讓 6000 行問題消失</h2>
<p>解決臃腫工作日誌的方式是拆層：</p>
<ul>
<li><strong>主版本日誌</strong>：500–1000 行，說明版本目標，提供所有 Ticket 的索引</li>
<li><strong>Ticket 工作日誌</strong>：每個 Ticket 一份，100–200 行，記錄執行過程、Review 結果和完成標記</li>
<li><strong>設計決策日誌</strong>：300–500 行，記錄設計決策演進，包含廢棄決策的原因</li>
</ul>
<p>原本 6000 行的文件拆分後變成一份 800 行主日誌加上 12 個 Ticket 日誌加上一份 400 行設計決策日誌，總量降到約 2000 行，資訊查找時間減少大約 80%。</p>
<h2 id="積極派發發現問題就建-ticket">積極派發：發現問題就建 Ticket</h2>
<p>這是後來加入的原則，也是這套方法論最核心的轉變。</p>
<p>執行一個 Ticket 時，經常會發現超出原本範圍的情況。以前的做法是「繼續在這個 Ticket 裡處理」或「先記著等有空再說」。前者讓 Ticket 失去單一職責，後者讓問題消失在記憶裡。</p>
<p>積極派發的做法：只要發現超出範圍的新情況，立刻評估性質，建立對應的新 Ticket。阻塞了當前 Ticket 就建子 Ticket 標記依賴；獨立於當前 Ticket 就建新 Ticket 讓兩者並行；是未來的改進就建技術債務 Ticket 記錄起來。</p>
<p>好處是：每個決策都有獨立記錄，保持可追溯性；任務粒度更細，更容易估算；學習點不會淹沒在大 Ticket 裡；一次只專注一件事。</p>
<p>要注意的反模式是「為派發而派發」。積極派發不是讓每件事都變成獨立 Ticket，判斷標準始終是單一職責：情況是否真的超出原 Ticket 範圍？</p>
<hr>
<p>這套方法論從單一大文件演進到精簡主文加引用網絡，量化指標被單一職責取代，是因為語義比數字更能反映 Ticket 是否設計得好。積極派發的加入，是因為 Ticket 可以成為持續改善的工具，不只是任務追蹤。</p>
<p>如果你的工作日誌越來越長、協作衝突越來越多，從三個問題開始：Ticket 能用「動詞加單一目標」描述嗎？驗收條件是客觀可檢查的嗎？跟其他 Ticket 的依賴關係清楚嗎？</p>]]></content:encoded></item><item><title>即時 Review 機制：Ticket 完成就 Review，不累積</title><link>https://tarrragon.github.io/blog/record/%E5%8D%B3%E6%99%82-review-%E6%A9%9F%E5%88%B6ticket-%E5%AE%8C%E6%88%90%E5%B0%B1-review%E4%B8%8D%E7%B4%AF%E7%A9%8D/</link><pubDate>Wed, 04 Mar 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/record/%E5%8D%B3%E6%99%82-review-%E6%A9%9F%E5%88%B6ticket-%E5%AE%8C%E6%88%90%E5%B0%B1-review%E4%B8%8D%E7%B4%AF%E7%A9%8D/</guid><description>&lt;p>以前我們也是等一批 Ticket 做完，才坐下來一起 review。&lt;/p>
&lt;p>結果就是：Review 的時候發現第一個 Ticket 的架構方向有問題，接下來五個都是建在那個錯誤上面。這時候修正成本已經是即時發現的六到十倍，開發者剛花了三天卻要整個打掉，士氣很難不崩。&lt;/p>
&lt;p>後來我們設計了「即時 Review 機制」，核心就一句話：&lt;strong>Ticket 完成就 Review，不累積。&lt;/strong>&lt;/p></description><content:encoded><![CDATA[<p>以前我們也是等一批 Ticket 做完，才坐下來一起 review。</p>
<p>結果就是：Review 的時候發現第一個 Ticket 的架構方向有問題，接下來五個都是建在那個錯誤上面。這時候修正成本已經是即時發現的六到十倍，開發者剛花了三天卻要整個打掉，士氣很難不崩。</p>
<p>後來我們設計了「即時 Review 機制」，核心就一句話：<strong>Ticket 完成就 Review，不累積。</strong></p>
<h2 id="三個原則">三個原則</h2>
<p><strong>即時觸發</strong>。Ticket 完成的當下就觸發，不是等 Wave 結束，不是等今天收工。錯誤的架構決策會在下一個 Ticket 開始前就污染後續設計，等不起。</p>
<p><strong>30 分鐘完成</strong>。這個時間限制是設計訊號：如果一個 Ticket 的 Review 超過一小時，代表那個 Ticket 太大，應該在規劃時就拆。</p>
<p><strong>標準清單</strong>。16 項固定檢查項，分功能正確性、架構合規性、測試通過率、文件同步性四類。不管誰 Review、什麼時間點，標準都一樣。</p>
<h2 id="怎麼跑">怎麼跑</h2>
<p><strong>觸發</strong>：完成實作、驗收條件全滿足、測試 100% 通過、靜態分析零錯誤，狀態標為「Review 中」。</p>
<p><strong>執行</strong>：30 分鐘內跑完 16 項。功能正確性（10 分鐘）、架構合規性（8 分鐘）、測試通過率（5 分鐘）、文件同步性（2 分鐘），最後 5 分鐘記錄結果。</p>
<p><strong>偏差糾正</strong>：發現問題就照固定流程走——暫停、記錄根因、建修正 Ticket、執行、再 Review。流程結構化是關鍵，「發現問題不知怎麼辦」是問題被忽略的主因。</p>
<h2 id="問題分三級">問題分三級</h2>
<p><strong>P0（阻塞）</strong>：功能錯誤、架構偏差、測試失敗。必須在 Review 通過前修正。</p>
<p><strong>P1（重要）</strong>：邊界處理缺失、文件不完整。建 Ticket 追蹤，當前 Ticket 可先通過。</p>
<p><strong>P2（建議）</strong>：命名改善、程式風格。記錄即可。</p>
<p>分級的目的：Review 保持快速，重要問題不被跳過。</p>
<h2 id="超時是訊號">超時是訊號</h2>
<p>Ticket 完成後 2 小時內開始 Review，目標 30 分鐘，最長 1 小時。超時代表 Ticket 範圍太大，不是 Reviewer 的問題。這個標準幫助我們持續校正 Ticket 的粒度。</p>
<h2 id="最明顯的變化">最明顯的變化</h2>
<p>導入前，「Review」這件事是模糊的——知道應該做，但時機不固定、標準不一、出了問題也不清楚怎麼處理。</p>
<p>導入後，偏差被控制在單一 Ticket 的範圍內，沒機會擴散。另一個意外收穫是，16 項清單讓我們對「品質」有了共同語言，Review 結果可以比較、可以追蹤，不再靠個人感覺。</p>
<hr>
<p>即時 Review 的目的是把修正成本壓到最低。問題在最小範圍被抓到，代價才會真的小。</p>]]></content:encoded></item><item><title>層級隔離：讓每張 Ticket 只做一件層級的事</title><link>https://tarrragon.github.io/blog/record/%E5%B1%A4%E7%B4%9A%E9%9A%94%E9%9B%A2%E8%AE%93%E6%AF%8F%E5%BC%B5-ticket-%E5%8F%AA%E5%81%9A%E4%B8%80%E4%BB%B6%E5%B1%A4%E7%B4%9A%E7%9A%84%E4%BA%8B/</link><pubDate>Wed, 04 Mar 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/record/%E5%B1%A4%E7%B4%9A%E9%9A%94%E9%9B%A2%E8%AE%93%E6%AF%8F%E5%BC%B5-ticket-%E5%8F%AA%E5%81%9A%E4%B8%80%E4%BB%B6%E5%B1%A4%E7%B4%9A%E7%9A%84%E4%BA%8B/</guid><description>&lt;p>架構圖貼出來，層級畫得漂漂亮亮，但 PR 送進來還是一次動了 UI、Controller、UseCase 和 Entity 四層。&lt;/p></description><content:encoded><![CDATA[<p>架構圖貼出來，層級畫得漂漂亮亮，但 PR 送進來還是一次動了 UI、Controller、UseCase 和 Entity 四層。</p>
<h2 id="問題不在架構在派工">問題不在架構，在派工</h2>
<p>Clean Architecture 告訴你「怎麼組織程式碼」，但沒告訴你「怎麼拆 Ticket」。每次 Code Review 都像翻地層，從 Widget 翻到 Entity，不知道從哪開始看；Domain 沒穩定，UI 那層就沒辦法測，整個流程互相等待。</p>
<p>這個銜接點，需要一套專門處理 Ticket 拆法的方法論。</p>
<h2 id="核心原則一張-ticket一個層級">核心原則：一張 Ticket，一個層級</h2>
<blockquote>
<p>一個 Ticket 只應該修改單一架構層級的程式碼，變更的原因單一且明確。</p></blockquote>
<p>SRP 說一個類別只有一個改變的原因，我們把它升一層：一張 Ticket 也只有一個改變的原因。</p>
<p>聽起來嚴苛，但實際跑起來好處很直接：Code Review 只需要理解一層的邏輯、測試不需要拉起整個系統、PR 影響範圍可預測，壞掉的時候更容易定位。</p>
<h2 id="我們怎麼定義五層">我們怎麼定義「五層」</h2>
<p>傳統 Clean Architecture 四層中，Interface Adapters 同時處理「事件邏輯」和「資料轉換」，職責太雜，我們把它細分成五層：</p>
<p><strong>Layer 1 — UI/Presentation</strong>：純視覺呈現，Widget 長什麼樣。變更原因只有一個：設計稿改了。</p>
<p><strong>Layer 2 — Application/Behavior</strong>：事件處理和 UI 邏輯。按鈕點擊怎麼處理、Loading 狀態怎麼切換、Domain Entity 怎麼轉成 ViewModel。Flutter 對應 Controller 和 ViewModel。</p>
<p><strong>Layer 3 — UseCase</strong>：業務流程編排。協調多個 Repository 和 Domain Service，把業務步驟串起來。不管 UI 怎麼顯示，也不管資料庫怎麼存。</p>
<p><strong>Layer 4 — Domain Events/Interfaces</strong>：定義契約。Repository 抽象介面、Domain Event 結構、跨層 DTO。只定義，不實作。</p>
<p><strong>Layer 5 — Domain Implementation</strong>：核心業務邏輯。Entity、Value Object、Domain Service、業務規則驗證。整個系統最穩定的部分。</p>
<p>Infrastructure 層（資料庫、外部 API、EventBus）不納入層級隔離，它的變更驅動是技術決策，不是業務需求，Ticket 設計上本來就獨立對待。</p>
<h2 id="從外而內而不是從內而外">從外而內，而不是從內而外</h2>
<p>許多教材說「先設計 Domain 再往外做」，但實際開發時，我們發現從外而內更能控制風險。</p>
<p>原因很簡單：Layer 1 UI 壞掉只影響視覺，Layer 5 Domain 邏輯壞掉影響整個系統的業務規則。從影響最小的地方開始，需求偏差時調整成本低；一開始就動 Domain，到了 UI 才發現需求理解有誤，代價就大得多。</p>
<p>實作順序是 Layer 1 → Layer 2 → Layer 3 → Layer 4 → Layer 5，每層完成後立即驗證。</p>
<p>有幾個例外：架構遷移要先定義 Layer 4 介面契約（Interface-First），讓外層修改有穩定依據；安全性修復從 Layer 5 往外；Bug Fix 從問題根源那層開始。</p>
<h2 id="ticket-拆分的量化標準">Ticket 拆分的量化標準</h2>
<p>幾個判斷指標：修改檔案數 1 到 3 個（最多 5 個）、預估開發時間 2 到 8 小時（超過一天就拆）、修改層級嚴格限制 1 層、新增程式碼測試覆蓋率 100%。</p>
<p>數字可以商議，但有標準就不用靠直覺判斷「感覺差不多」。</p>
<p>反面教材：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Ticket：實作書籍收藏功能
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">變更範圍：
</span></span><span class="line"><span class="ln">4</span><span class="cl">- lib/ui/pages/book_detail_page.dart       (Layer 1)
</span></span><span class="line"><span class="ln">5</span><span class="cl">- lib/application/controllers/book_detail_controller.dart  (Layer 2)
</span></span><span class="line"><span class="ln">6</span><span class="cl">- lib/usecases/add_book_to_favorite_usecase.dart  (Layer 3)
</span></span><span class="line"><span class="ln">7</span><span class="cl">- lib/domain/entities/favorite.dart        (Layer 5)</span></span></code></pre></div><p>這張 Ticket 跨了四層，PR 送出來沒人知道從哪開始審，測試也很難設計。正確做法是拆成四張各自獨立的 Ticket，按依賴順序執行。</p>
<h2 id="如何判斷一段程式碼屬於哪一層">如何判斷一段程式碼屬於哪一層</h2>
<p>最常模糊的是 Layer 2 和 Layer 3 之間的邊界。判斷流程：</p>
<ol>
<li>在渲染 UI 元素？→ Layer 1</li>
<li>在處理 UI 事件、控制 UI 狀態、或把 Domain 資料轉成 UI 格式？→ Layer 2（把 Domain Exception 轉成 ErrorViewModel 也是這層的事）</li>
<li>在協調多個 Domain Service 或 Repository、編排業務步驟？→ Layer 3</li>
<li>在定義介面契約或事件結構？→ Layer 4</li>
<li>在實作業務規則或定義 Entity？→ Layer 5</li>
<li>以上都不是 → Infrastructure 層</li>
</ol>
<h2 id="這套方法論的定位">這套方法論的定位</h2>
<p>這是 Clean Architecture 的「派工指南」。Clean Architecture 告訴你程式碼怎麼組織，層級隔離告訴你 Ticket 怎麼拆、按什麼順序做。</p>
<p>它和 Atomic Ticket 方法論也不衝突：Atomic Ticket 強調職責維度（一個 Action 加一個 Target），層級隔離強調層級維度（一個 Ticket 只動一層），兩個維度同時符合才是最完整的 Ticket 設計。</p>
<p>緊急 Hotfix、原型開發、一次性腳本不需要強行套用。但在正常功能開發和重構中，跑起來之後的感覺是：每次把一個大需求拆成按層排好的 Ticket 序列，就等於把架構邊界重新確認了一遍。</p>]]></content:encoded></item><item><title>Ticket 生命週期流程 - AI 協作開發的任務管理系統</title><link>https://tarrragon.github.io/blog/record/ticket-%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F%E6%B5%81%E7%A8%8B-ai-%E5%8D%94%E4%BD%9C%E9%96%8B%E7%99%BC%E7%9A%84%E4%BB%BB%E5%8B%99%E7%AE%A1%E7%90%86%E7%B3%BB%E7%B5%B1/</link><pubDate>Mon, 02 Feb 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/record/ticket-%E7%94%9F%E5%91%BD%E9%80%B1%E6%9C%9F%E6%B5%81%E7%A8%8B-ai-%E5%8D%94%E4%BD%9C%E9%96%8B%E7%99%BC%E7%9A%84%E4%BB%BB%E5%8B%99%E7%AE%A1%E7%90%86%E7%B3%BB%E7%B5%B1/</guid><description>&lt;p>本文件定義 Ticket 從建立到完成的完整生命週期。這套系統是我在 AI 協作開發（Claude Code）過程中逐步建立的任務追蹤機制。&lt;/p>
&lt;h2 id="生命週期總覽">生命週期總覽&lt;/h2>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">需求/問題產生
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl"> v
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">建立 Ticket (/ticket create)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl"> v
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">Ticket 狀態: pending
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl"> v
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">認領 Ticket (/ticket track claim)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl"> v
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">Ticket 狀態: in_progress
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">15&lt;/span>&lt;span class="cl"> +-- 正常完成 --&amp;gt; /ticket track complete --&amp;gt; 狀態: completed
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">16&lt;/span>&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">17&lt;/span>&lt;span class="cl"> +-- 無法繼續 --&amp;gt; /ticket track release --&amp;gt; 狀態: blocked
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">18&lt;/span>&lt;span class="cl"> | |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">19&lt;/span>&lt;span class="cl"> | v
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">20&lt;/span>&lt;span class="cl"> | 升級到 PM 處理
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">21&lt;/span>&lt;span class="cl"> |
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">22&lt;/span>&lt;span class="cl"> v
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">23&lt;/span>&lt;span class="cl">完成&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>這套系統的核心目標是將任務需求有邏輯地拆分拆細。任務進來後先分析，拆分成平行的子任務；子任務若仍太大，可繼續往下切分。執行時從最底層開始，完成後檢查平行任務，再往上驗收父任務，直到整個任務鏈完成。&lt;/p>
&lt;p>任務拆小的好處：降低執行時的認知負擔，也讓驗收檢查更容易發現疏失。&lt;/p>
&lt;h2 id="ticket-狀態定義">Ticket 狀態定義&lt;/h2>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>狀態&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;th>允許操作&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>pending&lt;/td>
 &lt;td>等待處理&lt;/td>
 &lt;td>claim&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>in_progress&lt;/td>
 &lt;td>處理中&lt;/td>
 &lt;td>complete, release&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>completed&lt;/td>
 &lt;td>已完成&lt;/td>
 &lt;td>-&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>blocked&lt;/td>
 &lt;td>被阻塞&lt;/td>
 &lt;td>claim（重新認領）&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="階段-標準流程對照表">階段-標準流程對照表&lt;/h2>
&lt;p>每個生命週期階段都有對應的標準流程和提示，防止關鍵步驟被遺漏。&lt;/p>
&lt;h3 id="建立階段">建立階段&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>標準流程&lt;/th>
 &lt;th>提示強度&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>SA 前置審查評估&lt;/td>
 &lt;td>建議&lt;/td>
 &lt;td>新功能/架構變更時需要 SA 審查&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>任務拆分評估&lt;/td>
 &lt;td>建議&lt;/td>
 &lt;td>認知負擔 &amp;gt; 10 時需要拆分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>驗收條件 4V 檢查&lt;/td>
 &lt;td>建議&lt;/td>
 &lt;td>確保驗收條件可驗證、可量化、可追溯、可記錄&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>blockedBy 設定&lt;/td>
 &lt;td>提示&lt;/td>
 &lt;td>提醒設定依賴關係&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>decision_tree_path 填寫&lt;/td>
 &lt;td>建議&lt;/td>
 &lt;td>派發驗證必需&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="認領階段">認領階段&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>標準流程&lt;/th>
 &lt;th>提示強度&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>阻塞依賴檢查&lt;/td>
 &lt;td>警告&lt;/td>
 &lt;td>如有阻塞依賴，顯示警告&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>設計文件閱讀&lt;/td>
 &lt;td>建議&lt;/td>
 &lt;td>提醒閱讀相關規格和設計&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>驗收條件理解&lt;/td>
 &lt;td>建議&lt;/td>
 &lt;td>確保理解驗收標準&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>error-patterns 查詢&lt;/td>
 &lt;td>建議&lt;/td>
 &lt;td>IMP/ADJ 類型時建議查詢&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="執行階段">執行階段&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>標準流程&lt;/th>
 &lt;th>提示強度&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>問題派發 incident-responder&lt;/td>
 &lt;td>強制&lt;/td>
 &lt;td>遇到錯誤時強制派發&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>工作日誌更新&lt;/td>
 &lt;td>建議&lt;/td>
 &lt;td>執行過程記錄&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="完成階段">完成階段&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>標準流程&lt;/th>
 &lt;th>提示強度&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>驗收條件勾選確認&lt;/td>
 &lt;td>建議&lt;/td>
 &lt;td>所有條件必須勾選&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>建議處理確認&lt;/td>
 &lt;td>建議&lt;/td>
 &lt;td>無 pending 建議&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>派發 acceptance-auditor&lt;/td>
 &lt;td>強制&lt;/td>
 &lt;td>IMP/ADJ 類型必須執行驗收&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>任務鏈後續步驟建議&lt;/td>
 &lt;td>提示&lt;/td>
 &lt;td>分析並建議下一個 Ticket&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="驗收後階段">驗收後階段&lt;/h3>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>標準流程&lt;/th>
 &lt;th>目的&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>技術債務記錄&lt;/td>
 &lt;td>將執行過程中發現的技術債務正式記錄，避免遺忘&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>CHANGELOG 更新&lt;/td>
 &lt;td>在版本發布時更新變更日誌，維護版本歷史的完整性&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>學習經驗記錄&lt;/td>
 &lt;td>萃取任務中的學習經驗，建構團隊知識網絡&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>任務鏈進度更新&lt;/td>
 &lt;td>追蹤整體任務鏈完成度，便於掌握專案整體進度&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="任務鏈後續步驟建議">任務鏈後續步驟建議&lt;/h2>
&lt;p>當 Ticket 完成時，系統會自動分析任務鏈狀態並建議下一步。&lt;/p></description><content:encoded><![CDATA[<p>本文件定義 Ticket 從建立到完成的完整生命週期。這套系統是我在 AI 協作開發（Claude Code）過程中逐步建立的任務追蹤機制。</p>
<h2 id="生命週期總覽">生命週期總覽</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">需求/問題產生
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    |
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    v
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">建立 Ticket (/ticket create)
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    |
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    v
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">Ticket 狀態: pending
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    |
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    v
</span></span><span class="line"><span class="ln">10</span><span class="cl">認領 Ticket (/ticket track claim)
</span></span><span class="line"><span class="ln">11</span><span class="cl">    |
</span></span><span class="line"><span class="ln">12</span><span class="cl">    v
</span></span><span class="line"><span class="ln">13</span><span class="cl">Ticket 狀態: in_progress
</span></span><span class="line"><span class="ln">14</span><span class="cl">    |
</span></span><span class="line"><span class="ln">15</span><span class="cl">    +-- 正常完成 --&gt; /ticket track complete --&gt; 狀態: completed
</span></span><span class="line"><span class="ln">16</span><span class="cl">    |
</span></span><span class="line"><span class="ln">17</span><span class="cl">    +-- 無法繼續 --&gt; /ticket track release --&gt; 狀態: blocked
</span></span><span class="line"><span class="ln">18</span><span class="cl">    |                                              |
</span></span><span class="line"><span class="ln">19</span><span class="cl">    |                                              v
</span></span><span class="line"><span class="ln">20</span><span class="cl">    |                                         升級到 PM 處理
</span></span><span class="line"><span class="ln">21</span><span class="cl">    |
</span></span><span class="line"><span class="ln">22</span><span class="cl">    v
</span></span><span class="line"><span class="ln">23</span><span class="cl">完成</span></span></code></pre></div><p>這套系統的核心目標是將任務需求有邏輯地拆分拆細。任務進來後先分析，拆分成平行的子任務；子任務若仍太大，可繼續往下切分。執行時從最底層開始，完成後檢查平行任務，再往上驗收父任務，直到整個任務鏈完成。</p>
<p>任務拆小的好處：降低執行時的認知負擔，也讓驗收檢查更容易發現疏失。</p>
<h2 id="ticket-狀態定義">Ticket 狀態定義</h2>
<table>
  <thead>
      <tr>
          <th>狀態</th>
          <th>說明</th>
          <th>允許操作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>pending</td>
          <td>等待處理</td>
          <td>claim</td>
      </tr>
      <tr>
          <td>in_progress</td>
          <td>處理中</td>
          <td>complete, release</td>
      </tr>
      <tr>
          <td>completed</td>
          <td>已完成</td>
          <td>-</td>
      </tr>
      <tr>
          <td>blocked</td>
          <td>被阻塞</td>
          <td>claim（重新認領）</td>
      </tr>
  </tbody>
</table>
<h2 id="階段-標準流程對照表">階段-標準流程對照表</h2>
<p>每個生命週期階段都有對應的標準流程和提示，防止關鍵步驟被遺漏。</p>
<h3 id="建立階段">建立階段</h3>
<table>
  <thead>
      <tr>
          <th>標準流程</th>
          <th>提示強度</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>SA 前置審查評估</td>
          <td>建議</td>
          <td>新功能/架構變更時需要 SA 審查</td>
      </tr>
      <tr>
          <td>任務拆分評估</td>
          <td>建議</td>
          <td>認知負擔 &gt; 10 時需要拆分</td>
      </tr>
      <tr>
          <td>驗收條件 4V 檢查</td>
          <td>建議</td>
          <td>確保驗收條件可驗證、可量化、可追溯、可記錄</td>
      </tr>
      <tr>
          <td>blockedBy 設定</td>
          <td>提示</td>
          <td>提醒設定依賴關係</td>
      </tr>
      <tr>
          <td>decision_tree_path 填寫</td>
          <td>建議</td>
          <td>派發驗證必需</td>
      </tr>
  </tbody>
</table>
<h3 id="認領階段">認領階段</h3>
<table>
  <thead>
      <tr>
          <th>標準流程</th>
          <th>提示強度</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>阻塞依賴檢查</td>
          <td>警告</td>
          <td>如有阻塞依賴，顯示警告</td>
      </tr>
      <tr>
          <td>設計文件閱讀</td>
          <td>建議</td>
          <td>提醒閱讀相關規格和設計</td>
      </tr>
      <tr>
          <td>驗收條件理解</td>
          <td>建議</td>
          <td>確保理解驗收標準</td>
      </tr>
      <tr>
          <td>error-patterns 查詢</td>
          <td>建議</td>
          <td>IMP/ADJ 類型時建議查詢</td>
      </tr>
  </tbody>
</table>
<h3 id="執行階段">執行階段</h3>
<table>
  <thead>
      <tr>
          <th>標準流程</th>
          <th>提示強度</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>問題派發 incident-responder</td>
          <td>強制</td>
          <td>遇到錯誤時強制派發</td>
      </tr>
      <tr>
          <td>工作日誌更新</td>
          <td>建議</td>
          <td>執行過程記錄</td>
      </tr>
  </tbody>
</table>
<h3 id="完成階段">完成階段</h3>
<table>
  <thead>
      <tr>
          <th>標準流程</th>
          <th>提示強度</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>驗收條件勾選確認</td>
          <td>建議</td>
          <td>所有條件必須勾選</td>
      </tr>
      <tr>
          <td>建議處理確認</td>
          <td>建議</td>
          <td>無 pending 建議</td>
      </tr>
      <tr>
          <td>派發 acceptance-auditor</td>
          <td>強制</td>
          <td>IMP/ADJ 類型必須執行驗收</td>
      </tr>
      <tr>
          <td>任務鏈後續步驟建議</td>
          <td>提示</td>
          <td>分析並建議下一個 Ticket</td>
      </tr>
  </tbody>
</table>
<h3 id="驗收後階段">驗收後階段</h3>
<table>
  <thead>
      <tr>
          <th>標準流程</th>
          <th>目的</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>技術債務記錄</td>
          <td>將執行過程中發現的技術債務正式記錄，避免遺忘</td>
      </tr>
      <tr>
          <td>CHANGELOG 更新</td>
          <td>在版本發布時更新變更日誌，維護版本歷史的完整性</td>
      </tr>
      <tr>
          <td>學習經驗記錄</td>
          <td>萃取任務中的學習經驗，建構團隊知識網絡</td>
      </tr>
      <tr>
          <td>任務鏈進度更新</td>
          <td>追蹤整體任務鏈完成度，便於掌握專案整體進度</td>
      </tr>
  </tbody>
</table>
<h2 id="任務鏈後續步驟建議">任務鏈後續步驟建議</h2>
<p>當 Ticket 完成時，系統會自動分析任務鏈狀態並建議下一步。</p>
<h3 id="分析優先級">分析優先級</h3>
<table>
  <thead>
      <tr>
          <th>優先級</th>
          <th>情境</th>
          <th>建議內容</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>1</td>
          <td>有子 Ticket 可開始</td>
          <td>「子 Ticket {id} 現在可以開始」</td>
      </tr>
      <tr>
          <td>2</td>
          <td>有被解除阻塞的 Ticket</td>
          <td>「{id} 的阻塞已解除」</td>
      </tr>
      <tr>
          <td>3</td>
          <td>有同層兄弟 Ticket</td>
          <td>「同層還有 {id} 待處理」</td>
      </tr>
      <tr>
          <td>4</td>
          <td>同 Wave 有其他 pending</td>
          <td>「同 Wave 還有 N 個待處理」</td>
      </tr>
      <tr>
          <td>5</td>
          <td>任務鏈全部完成</td>
          <td>「任務鏈 {root} 全部完成」</td>
      </tr>
  </tbody>
</table>
<h3 id="輸出範例">輸出範例</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">============================================================
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">[任務鏈後續步驟建議]
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">============================================================
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">已完成: 0.31.0-W4-007.1
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">        [實作 track P0 功能]
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">任務鏈進度: 1/3 completed
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   Root: 0.31.0-W4-007
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">建議下一步:
</span></span><span class="line"><span class="ln">12</span><span class="cl">   1. 0.31.0-W4-007.2
</span></span><span class="line"><span class="ln">13</span><span class="cl">      [實作 track P1 功能]
</span></span><span class="line"><span class="ln">14</span><span class="cl">      原因: 阻塞已解除（blockedBy 0.31.0-W4-007.1 已完成）
</span></span><span class="line"><span class="ln">15</span><span class="cl">      狀態: pending → 可認領</span></span></code></pre></div><h2 id="任務鏈-id-格式">任務鏈 ID 格式</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">0.31.0-W3-002              # ticket-handoff 功能（根）
</span></span><span class="line"><span class="ln">2</span><span class="cl">├── 0.31.0-W3-002.1        # chain_analyzer 模組
</span></span><span class="line"><span class="ln">3</span><span class="cl">│   ├── 0.31.0-W3-002.1.1  # 問題修復
</span></span><span class="line"><span class="ln">4</span><span class="cl">│   └── 0.31.0-W3-002.1.2  # 測試補充
</span></span><span class="line"><span class="ln">5</span><span class="cl">├── 0.31.0-W3-002.2        # handoff_executor 模組
</span></span><span class="line"><span class="ln">6</span><span class="cl">└── 0.31.0-W3-002.3        # 文件更新</span></span></code></pre></div><table>
  <thead>
      <tr>
          <th>類型</th>
          <th>格式</th>
          <th>範例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>根任務</td>
          <td><code>{版本}-W{波次}-{序號}</code></td>
          <td><code>0.31.0-W3-002</code></td>
      </tr>
      <tr>
          <td>子任務</td>
          <td><code>{根ID}.{n}[.{n}...]</code></td>
          <td><code>0.31.0-W3-002.1.1</code></td>
      </tr>
  </tbody>
</table>
<h3 id="chain-欄位">chain 欄位</h3>
<table>
  <thead>
      <tr>
          <th>欄位</th>
          <th>類型</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>root</td>
          <td>string</td>
          <td>任務鏈根 ID</td>
      </tr>
      <tr>
          <td>parent</td>
          <td>string/null</td>
          <td>直接父任務 ID</td>
      </tr>
      <tr>
          <td>depth</td>
          <td>number</td>
          <td>深度（根=0）</td>
      </tr>
      <tr>
          <td>sequence</td>
          <td>array</td>
          <td>序號路徑陣列</td>
      </tr>
  </tbody>
</table>
<p>根任務 <code>0.31.0-W3-002</code> 的 chain：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">chain</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span><span class="nt">root</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;0.31.0-W3-002&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span><span class="nt">parent</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span><span class="nt">depth</span><span class="p">:</span><span class="w"> </span><span class="m">0</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">  </span><span class="nt">sequence</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="m">2</span><span class="p">]</span></span></span></code></pre></div><p>子任務 <code>0.31.0-W3-002.1.1</code> 的 chain：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">chain</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span><span class="nt">root</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;0.31.0-W3-002&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span><span class="nt">parent</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;0.31.0-W3-002.1&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">  </span><span class="nt">depth</span><span class="p">:</span><span class="w"> </span><span class="m">2</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">  </span><span class="nt">sequence</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="m">2</span><span class="p">,</span><span class="w"> </span><span class="m">1</span><span class="p">,</span><span class="w"> </span><span class="m">1</span><span class="p">]</span></span></span></code></pre></div><p>ID 正則表達式：<code>^(\d+\.\d+\.\d+)-W(\d+)-(\d+(?:\.\d+)*)$</code></p>
<h2 id="ticket-建立流程">Ticket 建立流程</h2>
<h3 id="任務層級判斷">任務層級判斷</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">任務層級判斷
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    |
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    v
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">這個任務是否因為執行現有 Ticket 而產生？
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    |
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    +-- 是 → 來源 Ticket 是什麼？
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    |       |
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    |       └── 確定來源 Ticket ID → 建立該 Ticket 的子任務
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    |           ├── 來源: 010.4 → 子任務 ID: 010.4.x
</span></span><span class="line"><span class="ln">10</span><span class="cl">    |           ├── 來源: 010.4.1 → 子任務 ID: 010.4.1.x
</span></span><span class="line"><span class="ln">11</span><span class="cl">    |           └── 來源: 010 → 子任務 ID: 010.x
</span></span><span class="line"><span class="ln">12</span><span class="cl">    |
</span></span><span class="line"><span class="ln">13</span><span class="cl">    └-- 否 → 建立新任務鏈（新的 Wx-00n）</span></span></code></pre></div><table>
  <thead>
      <tr>
          <th>應建立子任務</th>
          <th>應建立新任務鏈</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>問題在執行特定 Ticket 時發現</td>
          <td>問題與任何執行中的 Ticket 無關</td>
      </tr>
      <tr>
          <td>問題直接影響該 Ticket 的完成</td>
          <td>問題是系統性的獨立問題</td>
      </tr>
      <tr>
          <td>「執行 X 時發現 Y 問題」</td>
          <td>「發現系統有 Z 問題」</td>
      </tr>
  </tbody>
</table>
<p>核心判斷問題：「這個任務是在執行哪個 Ticket 時產生的？」若有明確來源，建立子任務；若無關聯，建立新任務鏈。</p>
<h3 id="建立格式">建立格式</h3>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">---
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">id: {版本}-W{波次}-{序號}
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">title: {動詞} {目標}
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">type: IMP/RES/ANA/INV/DOC
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">status: pending
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">priority: P0/P1/P2
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">assignee: pending
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">created: {日期}
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">---
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gh"># {Ticket ID}: {標題}
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gh"></span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">## 目標
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">{目標描述}
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="gu">## 驗收條件
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">- [ ]</span> {條件1}
</span></span><span class="line"><span class="ln">20</span><span class="cl">- [ ] {條件2}</span></span></code></pre></div><h3 id="atomic-ticket-檢查">Atomic Ticket 檢查</h3>
<table>
  <thead>
      <tr>
          <th>檢查項目</th>
          <th>標準</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>語義檢查</td>
          <td>能用「動詞 + 單一目標」表達</td>
      </tr>
      <tr>
          <td>修改原因</td>
          <td>只有一個修改原因</td>
      </tr>
      <tr>
          <td>驗收一致</td>
          <td>所有驗收條件指向同一目標</td>
      </tr>
      <tr>
          <td>依賴獨立</td>
          <td>無循環依賴</td>
      </tr>
  </tbody>
</table>
<h3 id="驗收條件格式要求">驗收條件格式要求</h3>
<p>驗收條件必須符合 4V 原則：<strong>可驗證、可量化、可追溯、可記錄</strong>。</p>
<table>
  <thead>
      <tr>
          <th>要求</th>
          <th>說明</th>
          <th>範例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>必須有編號</td>
          <td>每個驗收項目都有編號</td>
          <td><code>1.</code>, <code>2.</code>, &hellip;</td>
      </tr>
      <tr>
          <td>必須有來源</td>
          <td>引用設計文件或需求</td>
          <td><code>SKILL.md L97</code></td>
      </tr>
      <tr>
          <td>必須有確認方法</td>
          <td>定義如何驗證完成</td>
          <td><code>執行命令驗證輸出</code></td>
      </tr>
      <tr>
          <td>禁止模糊詞彙</td>
          <td>不可用「完成」「正常」「適當」</td>
          <td>用具體描述取代</td>
      </tr>
  </tbody>
</table>
<p><strong>標準格式（表格式）</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="gu">## Acceptance Criteria
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">3</span><span class="cl">| #   | 項目       | 來源       | 確認方法   | 狀態 |
</span></span><span class="line"><span class="ln">4</span><span class="cl">| --- | ---------- | ---------- | ---------- | ---- |
</span></span><span class="line"><span class="ln">5</span><span class="cl">| 1   | {項目描述} | {來源引用} | {確認方法} | [ ]  |
</span></span><span class="line"><span class="ln">6</span><span class="cl">| 2   | {項目描述} | {來源引用} | {確認方法} | [ ]  |</span></span></code></pre></div><h2 id="ticket-有效性驗證">Ticket 有效性驗證</h2>
<h3 id="有效-ticket-定義">有效 Ticket 定義</h3>
<p>有效的 Ticket 必須滿足以下條件：</p>
<table>
  <thead>
      <tr>
          <th>條件</th>
          <th>說明</th>
          <th>驗證方式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>決策樹欄位</td>
          <td>包含 <code>decision_tree_path</code> 欄位</td>
          <td>YAML frontmatter 檢查</td>
      </tr>
      <tr>
          <td>或決策樹區段</td>
          <td>包含「## 決策樹路徑」Markdown 區段</td>
          <td>內容檢查</td>
      </tr>
  </tbody>
</table>
<h3 id="驗證時機">驗證時機</h3>
<table>
  <thead>
      <tr>
          <th>時機</th>
          <th>驗證者</th>
          <th>動作</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>建立 Ticket</td>
          <td>/ticket create</td>
          <td>自動要求填寫決策樹欄位</td>
      </tr>
      <tr>
          <td>派發任務</td>
          <td>agent-ticket-validation-hook</td>
          <td>阻止使用無效 Ticket</td>
      </tr>
      <tr>
          <td>認領 Ticket</td>
          <td>/ticket track claim</td>
          <td>確認 Ticket 有效性</td>
      </tr>
  </tbody>
</table>
<h3 id="無效-ticket-處理">無效 Ticket 處理</h3>
<p>無效 Ticket（缺少決策樹欄位）：</p>
<ul>
<li>無法用於 Task 派發（被 Hook 阻止）</li>
<li>需要補充決策樹欄位才能使用</li>
<li>建議使用 /ticket create 重新建立</li>
</ul>
<h3 id="補充決策樹欄位">補充決策樹欄位</h3>
<p>如果 Ticket 缺少決策樹欄位，可手動補充：</p>
<ol>
<li>
<p><strong>YAML 格式</strong>（在 frontmatter 中）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="ln">1</span><span class="cl"><span class="nt">decision_tree_path</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="w">  </span><span class="nt">entry_point</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;第X層&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="w">  </span><span class="nt">decision_nodes</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="w">    </span>- <span class="nt">layer</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;X&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="w">      </span><span class="nt">question</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;決策問題&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="w">      </span><span class="nt">answer</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;答案&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="w">      </span><span class="nt">next_action</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;下一步&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">8</span><span class="cl"><span class="w">  </span><span class="nt">final_decision</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;最終決策&#34;</span><span class="w">
</span></span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="w">  </span><span class="nt">rationale</span><span class="p">:</span><span class="w"> </span><span class="s2">&#34;決策理由&#34;</span></span></span></code></pre></div></li>
<li>
<p><strong>Markdown 格式</strong>（在內容中）：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="gu">## 決策樹路徑
</span></span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="gu">### 進入點
</span></span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">-</span> **層級**: 第X層
</span></span><span class="line"><span class="ln">6</span><span class="cl">- <span class="gs">**觸發條件**</span>: ...</span></span></code></pre></div></li>
</ol>
<h2 id="ticket-認領流程">Ticket 認領流程</h2>
<h3 id="認領規則">認領規則</h3>
<table>
  <thead>
      <tr>
          <th>規則</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>單一認領</td>
          <td>同一時間只能有一個代理人處理</td>
      </tr>
      <tr>
          <td>階段匹配</td>
          <td>只能認領對應階段的 Ticket</td>
      </tr>
      <tr>
          <td>依賴檢查</td>
          <td>前置 Ticket 必須完成</td>
      </tr>
  </tbody>
</table>
<h2 id="ticket-執行流程">Ticket 執行流程</h2>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">認領 Ticket
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    |
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    v
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">執行對應階段工作
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    |
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    v
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">更新工作日誌
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    |
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    v
</span></span><span class="line"><span class="ln">10</span><span class="cl">驗證驗收條件
</span></span><span class="line"><span class="ln">11</span><span class="cl">    |
</span></span><span class="line"><span class="ln">12</span><span class="cl">    +-- 全部通過 --&gt; 完成 Ticket
</span></span><span class="line"><span class="ln">13</span><span class="cl">    +-- 部分通過 --&gt; 繼續處理或升級
</span></span><span class="line"><span class="ln">14</span><span class="cl">    +-- 無法完成 --&gt; 釋放 Ticket</span></span></code></pre></div><h3 id="完成檢查">完成檢查</h3>
<table>
  <thead>
      <tr>
          <th>檢查項目</th>
          <th>標準</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>驗收條件</td>
          <td>所有條件都已勾選</td>
      </tr>
      <tr>
          <td>測試通過</td>
          <td>相關測試全部通過</td>
      </tr>
      <tr>
          <td>文件更新</td>
          <td>相關文件已更新</td>
      </tr>
      <tr>
          <td>工作日誌</td>
          <td>執行記錄完整</td>
      </tr>
  </tbody>
</table>
<h2 id="ticket-釋放流程">Ticket 釋放流程</h2>
<h3 id="釋放時機">釋放時機</h3>
<table>
  <thead>
      <tr>
          <th>時機</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>被阻塞</td>
          <td>依賴其他 Ticket 完成</td>
      </tr>
      <tr>
          <td>超出範圍</td>
          <td>發現需要額外工作</td>
      </tr>
      <tr>
          <td>技術限制</td>
          <td>當前無法解決</td>
      </tr>
      <tr>
          <td>資訊不足</td>
          <td>需要更多資訊</td>
      </tr>
  </tbody>
</table>
<h2 id="ticket-類型說明">Ticket 類型說明</h2>
<table>
  <thead>
      <tr>
          <th>類型</th>
          <th>代碼</th>
          <th>用途</th>
          <th>典型時長</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Research</td>
          <td>RES</td>
          <td>探索未知領域</td>
          <td>1-2 小時</td>
      </tr>
      <tr>
          <td>Analysis</td>
          <td>ANA</td>
          <td>理解現狀和問題</td>
          <td>30 分鐘 - 1 小時</td>
      </tr>
      <tr>
          <td>Implementation</td>
          <td>IMP</td>
          <td>執行具體任務</td>
          <td>1-4 小時</td>
      </tr>
      <tr>
          <td>Investigation</td>
          <td>INV</td>
          <td>深入追蹤問題根因</td>
          <td>1-2 小時</td>
      </tr>
      <tr>
          <td>Documentation</td>
          <td>DOC</td>
          <td>記錄和傳承經驗</td>
          <td>30 分鐘 - 1 小時</td>
      </tr>
  </tbody>
</table>
<h2 id="版本歷史">版本歷史</h2>
<ul>
<li>v2.8.0 (2026-02-01): 取消驗收豁免機制，改為契約式驗收</li>
<li>v2.7.0 (2026-02-01): 強化驗收代理人派發要求</li>
<li>v2.6.0 (2026-01-31): 新增任務層級判斷規則</li>
<li>v2.5.0 (2026-01-30): 新增階段-標準流程對照表和任務鏈後續步驟建議</li>
<li>v2.4.0 (2026-01-30): 新增建議追蹤流程整合章節</li>
<li>v2.3.0 (2026-01-30): 新增驗收條件格式要求章節</li>
<li>v2.2.0 (2026-01-29): 新增任務鏈 ID 格式章節</li>
<li>v2.1.0 (2026-01-27): 新增 Ticket 有效性驗證章節</li>
<li>v2.0.0 (2026-01-23): 重構為 TDD 含 SA 前置審查流程版本</li>
</ul>
]]></content:encoded></item><item><title>五層文件系統 - 專案文檔管理架構</title><link>https://tarrragon.github.io/blog/record/%E4%BA%94%E5%B1%A4%E6%96%87%E4%BB%B6%E7%B3%BB%E7%B5%B1-%E5%B0%88%E6%A1%88%E6%96%87%E6%AA%94%E7%AE%A1%E7%90%86%E6%9E%B6%E6%A7%8B/</link><pubDate>Tue, 20 Jan 2026 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/record/%E4%BA%94%E5%B1%A4%E6%96%87%E4%BB%B6%E7%B3%BB%E7%B5%B1-%E5%B0%88%E6%A1%88%E6%96%87%E6%AA%94%E7%AE%A1%E7%90%86%E6%9E%B6%E6%A7%8B/</guid><description>&lt;p>我們需要專門的 SKILL 處理我們的文件運作，我們之前可能有其他腳本或者 SKILL 處理相關工作，但是現在這是一個完整的整合描述跟處理模式&lt;/p>
&lt;p>我們原本設計的是三重文件系統，但是現在會經過擴充把分工再度做拆分，重新調整不同的工作職責&lt;/p>
&lt;p>changelog 是純粹的提供給其他工程師了解版本推進的變化&lt;/p>
&lt;p>todo.md 是當前版本已知的待處理的問題，但是還沒加入執行的排程中，可能會在下一個版本或者更之後的版本處理這些問題，如果已經解決的任務應該要從 todo.md 移除&lt;/p>
&lt;p>worklog 是記錄這個版本的大方向，這個版本任務的前情提要，整個版本的執行企劃，不包括執行細節，因為執行細節我們會交付給 ticket ，我們要確保的是 worklog 想要達到的目標都有達成，比如我們剛剛規劃的 step by step
,我們為什麼會這樣設計，為什麼我們需要這些設計相關的解釋，理論上，每一個工程師，不需要其他的 context 解釋，他應該能從當前版本的 worklog 理解所有人的工作目標跟工作要求&lt;/p>
&lt;p>ticket 是所有任務的細節，會記錄任務從何而來，目標是什麼，執行的途中也會更新 ticket 的處理狀況跟進度 ，直到 ticket 被更新為完成為止&lt;/p>
&lt;p>最後是我們剛剛新增的錯誤模式文件系統，當我們在執行 ticket 之前跟之後，都需要查詢或者更新相關的問題，蒐集問題，並且提供之後改善我們工作模式的參考素材&lt;/p>
&lt;p>所以我們需要 SKILL 說明每個文件的職責，設計相關的 command 做更新或者查詢，用 hook 確保文件進度的同步，這是我們現在的工作模式的核心運作系統&lt;/p></description><content:encoded><![CDATA[<p>我們需要專門的 SKILL 處理我們的文件運作，我們之前可能有其他腳本或者 SKILL 處理相關工作，但是現在這是一個完整的整合描述跟處理模式</p>
<p>我們原本設計的是三重文件系統，但是現在會經過擴充把分工再度做拆分，重新調整不同的工作職責</p>
<p>changelog 是純粹的提供給其他工程師了解版本推進的變化</p>
<p>todo.md 是當前版本已知的待處理的問題，但是還沒加入執行的排程中，可能會在下一個版本或者更之後的版本處理這些問題，如果已經解決的任務應該要從 todo.md 移除</p>
<p>worklog 是記錄這個版本的大方向，這個版本任務的前情提要，整個版本的執行企劃，不包括執行細節，因為執行細節我們會交付給 ticket ，我們要確保的是 worklog 想要達到的目標都有達成，比如我們剛剛規劃的 step by step
,我們為什麼會這樣設計，為什麼我們需要這些設計相關的解釋，理論上，每一個工程師，不需要其他的 context 解釋，他應該能從當前版本的 worklog 理解所有人的工作目標跟工作要求</p>
<p>ticket 是所有任務的細節，會記錄任務從何而來，目標是什麼，執行的途中也會更新 ticket 的處理狀況跟進度 ，直到 ticket 被更新為完成為止</p>
<p>最後是我們剛剛新增的錯誤模式文件系統，當我們在執行 ticket 之前跟之後，都需要查詢或者更新相關的問題，蒐集問題，並且提供之後改善我們工作模式的參考素材</p>
<p>所以我們需要 SKILL 說明每個文件的職責，設計相關的 command 做更新或者查詢，用 hook 確保文件進度的同步，這是我們現在的工作模式的核心運作系統</p>
]]></content:encoded></item><item><title>Ticket 拆分標準方法論</title><link>https://tarrragon.github.io/blog/record/ticket-%E6%8B%86%E5%88%86%E6%A8%99%E6%BA%96%E6%96%B9%E6%B3%95%E8%AB%96/</link><pubDate>Mon, 13 Oct 2025 00:00:00 +0000</pubDate><guid>https://tarrragon.github.io/blog/record/ticket-%E6%8B%86%E5%88%86%E6%A8%99%E6%BA%96%E6%96%B9%E6%B3%95%E8%AB%96/</guid><description>&lt;h2 id="方法論概述">方法論概述&lt;/h2>
&lt;h3 id="為什麼需要-ticket-拆分標準">為什麼需要 Ticket 拆分標準&lt;/h3>
&lt;p>&lt;strong>問題背景&lt;/strong>:&lt;/p>
&lt;p>在大型軟體開發專案中，我們經常面臨以下挑戰：&lt;/p>
&lt;ol>
&lt;li>&lt;strong>God Ticket 問題&lt;/strong>：單一任務過於龐大，包含數十個檔案修改，跨越多個架構層級&lt;/li>
&lt;li>&lt;strong>主觀判斷困境&lt;/strong>：不同開發者對「任務大小」的理解不同，導致協作效率低&lt;/li>
&lt;li>&lt;strong>進度追蹤困難&lt;/strong>：任務粒度不一致，難以準確評估完成度&lt;/li>
&lt;li>&lt;strong>風險控制失衡&lt;/strong>：大任務失敗影響大，小任務過碎增加管理成本&lt;/li>
&lt;/ol>
&lt;p>&lt;strong>傳統拆分方法的問題&lt;/strong>:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>經驗導向&lt;/strong>：依賴個人經驗判斷，缺乏客觀標準&lt;/li>
&lt;li>&lt;strong>時間估算&lt;/strong>：受個人能力和環境影響，難以標準化&lt;/li>
&lt;li>&lt;strong>模糊描述&lt;/strong>：「不要太大」「保持適中」等描述無法執行&lt;/li>
&lt;li>&lt;strong>後驗調整&lt;/strong>：任務執行後才發現過大，增加返工成本&lt;/li>
&lt;/ul>
&lt;hr>
&lt;h3 id="核心目標">核心目標&lt;/h3>
&lt;ol>
&lt;li>&lt;strong>標準化任務拆分&lt;/strong>：提供統一的拆分標準，消除主觀判斷&lt;/li>
&lt;li>&lt;strong>控制任務複雜度&lt;/strong>：確保每個 Ticket 在可控範圍內&lt;/li>
&lt;li>&lt;strong>提升協作效率&lt;/strong>：明確的任務邊界，減少溝通成本&lt;/li>
&lt;li>&lt;strong>及早風險管控&lt;/strong>：設計階段就識別過大任務，降低執行風險&lt;/li>
&lt;/ol>
&lt;hr>
&lt;h3 id="與其他方法論的關係">與其他方法論的關係&lt;/h3>
&lt;p>&lt;strong>本方法論的定位&lt;/strong>:&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">Ticket 設計派工方法論 (主方法論)
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">├── Ticket 拆分標準方法論 ← 你正在閱讀
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">│ └── 提供量化拆分標準和決策樹
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">├── Code Smell 品質閘門檢測方法論
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">│ └── 提供設計階段的品質檢測
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">├── Ticket 生命週期管理方法論
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">│ └── 提供 Ticket 執行流程管理
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">└── 即時 Review 機制方法論
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl"> └── 提供執行過程中的 Review 機制&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;hr>
&lt;h2 id="第一章量化指標體系">第一章：量化指標體系&lt;/h2>
&lt;h3 id="11-指標-1職責數量responsibilities-最優先">1.1 指標 1：職責數量（Responsibilities） 最優先&lt;/h3>
&lt;p>&lt;strong>定義&lt;/strong>：Ticket 需要完成的獨立職責數量。&lt;/p>
&lt;p>&lt;strong>為什麼職責是第一指標&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>最客觀&lt;/strong>：不受個人能力影響&lt;/li>
&lt;li>&lt;strong>最穩定&lt;/strong>：不受環境和參考資料影響&lt;/li>
&lt;li>&lt;strong>最易溝通&lt;/strong>：PM 和工程師都能理解&lt;/li>
&lt;li>&lt;strong>最精確&lt;/strong>：直接對應業務需求&lt;/li>
&lt;/ul>
&lt;h4 id="職責的精確定義">職責的精確定義&lt;/h4>
&lt;p>&lt;strong>什麼算一個職責&lt;/strong>：&lt;/p>
&lt;p>一個職責 = 一個明確可驗證的功能點或邊界條件&lt;/p>
&lt;p>&lt;strong>識別方式&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>每個「需要實作的功能點」算一個職責&lt;/li>
&lt;li>每個「需要驗證的邊界條件」算一個職責&lt;/li>
&lt;li>每個「需要處理的錯誤情境」算一個職責&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>範例說明&lt;/strong>：&lt;/p>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">範例任務：實作書籍評分功能
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">職責識別：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">&lt;span class="k">1.&lt;/span> 定義 Rating Value Object（數值範圍驗證） ← 職責 1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">&lt;span class="k">2.&lt;/span> 定義 Rating Entity（包含評分和評論） ← 職責 2
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">&lt;span class="k">3.&lt;/span> 實作 IRatingRepository 介面 ← 職責 3
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">&lt;span class="k">4.&lt;/span> 實作評分儲存邏輯 ← 職責 4
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">&lt;span class="k">5.&lt;/span> 處理無效評分錯誤 ← 職責 5
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">&lt;span class="k">6.&lt;/span> 處理資料庫錯誤 ← 職責 6
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">總計：6 個職責 → 超過 5 個，必須拆分&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h4 id="職責數量標準">職責數量標準&lt;/h4>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>等級&lt;/th>
 &lt;th>職責數量&lt;/th>
 &lt;th>判定&lt;/th>
 &lt;th>說明&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>&lt;strong>簡單 Ticket&lt;/strong>&lt;/td>
 &lt;td>1 個&lt;/td>
 &lt;td>理想&lt;/td>
 &lt;td>單一職責，最易管理&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>中等 Ticket&lt;/strong>&lt;/td>
 &lt;td>2-3 個&lt;/td>
 &lt;td>可接受&lt;/td>
 &lt;td>少數相關職責，可控範圍&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>複雜 Ticket&lt;/strong>&lt;/td>
 &lt;td>3-5 個&lt;/td>
 &lt;td>需檢查&lt;/td>
 &lt;td>多職責，建議拆分&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>&lt;strong>必須拆分&lt;/strong>&lt;/td>
 &lt;td>&amp;gt; 5 個&lt;/td>
 &lt;td>禁止&lt;/td>
 &lt;td>範圍失控，必須拆分&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>&lt;strong>強制規則&lt;/strong>：&lt;/p>
&lt;ul>
&lt;li>&lt;strong>超過 5 個職責 = 必須拆分&lt;/strong>，無例外&lt;/li>
&lt;li>&lt;strong>3-5 個職責 = 評估是否可拆分&lt;/strong>，優先拆分&lt;/li>
&lt;li>&lt;strong>1-2 個職責 = 理想狀態&lt;/strong>，鼓勵維持&lt;/li>
&lt;/ul>
&lt;h4 id="職責識別實例">職責識別實例&lt;/h4>
&lt;h5 id="實例-1簡單-ticket1-職責">實例 1：簡單 Ticket（1 職責）&lt;/h5>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">任務：定義 SelectionManager 介面方法簽名
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">職責分析：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">職責 1：定義 toggleSelection、clearSelection、getSelectedIds 三個方法簽名
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">總計：1 個職責
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">判定：簡單 Ticket&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h6 id="實例-2中等-ticket2-3-職責">實例 2：中等 Ticket（2-3 職責）&lt;/h6>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln">1&lt;/span>&lt;span class="cl">任務：實作 SelectionManager 基礎功能
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">3&lt;/span>&lt;span class="cl">職責分析：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">4&lt;/span>&lt;span class="cl">職責 1：實作 toggleSelection 方法
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">5&lt;/span>&lt;span class="cl">職責 2：實作 clearSelection 方法
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">6&lt;/span>&lt;span class="cl">職責 3：實作 ChangeNotifier 通知機制
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">7&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">8&lt;/span>&lt;span class="cl">總計：3 個職責
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">9&lt;/span>&lt;span class="cl">判定：中等 Ticket（可接受）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h6 id="實例-3複雜-ticket3-5-職責--建議拆分">實例 3：複雜 Ticket（3-5 職責）- 建議拆分&lt;/h6>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">任務：實作完整的 BookRepository
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">職責分析：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">職責 1：實作 getBookByIsbn CRUD 方法
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">職責 2：實作 saveBook CRUD 方法
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">職責 3：實作 Data Mapper 轉換
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">職責 4：實作錯誤處理
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">職責 5：實作 Cache 管理
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">總計：5 個職責
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">判定：複雜 Ticket（建議拆分為 2-3 個 Ticket）&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h6 id="實例-4必須拆分-5-職責">實例 4：必須拆分（&amp;gt; 5 職責）&lt;/h6>





&lt;div class="highlight">&lt;pre tabindex="0" class="chroma">&lt;code class="language-markdown" data-lang="markdown">&lt;span class="line">&lt;span class="ln"> 1&lt;/span>&lt;span class="cl">任務：實作書籍評分完整功能（包含 UI、UseCase、Repository）
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 2&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 3&lt;/span>&lt;span class="cl">職責分析：
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 4&lt;/span>&lt;span class="cl">職責 1：定義 Rating Value Object
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 5&lt;/span>&lt;span class="cl">職責 2：定義 Rating Entity
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 6&lt;/span>&lt;span class="cl">職責 3：建立 RatingWidget UI
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 7&lt;/span>&lt;span class="cl">職責 4：實作 RateBookUseCase
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 8&lt;/span>&lt;span class="cl">職責 5：定義 IRatingRepository
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln"> 9&lt;/span>&lt;span class="cl">職責 6：實作 SQLiteRatingRepository
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">10&lt;/span>&lt;span class="cl">職責 7：處理各種異常情境
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">11&lt;/span>&lt;span class="cl">職責 8：撰寫完整測試
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">12&lt;/span>&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">13&lt;/span>&lt;span class="cl">總計：8 個職責
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="ln">14&lt;/span>&lt;span class="cl">判定：God Ticket 必須拆分&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;strong>拆分建議&lt;/strong>：&lt;/p></description><content:encoded><![CDATA[<h2 id="方法論概述">方法論概述</h2>
<h3 id="為什麼需要-ticket-拆分標準">為什麼需要 Ticket 拆分標準</h3>
<p><strong>問題背景</strong>:</p>
<p>在大型軟體開發專案中，我們經常面臨以下挑戰：</p>
<ol>
<li><strong>God Ticket 問題</strong>：單一任務過於龐大，包含數十個檔案修改，跨越多個架構層級</li>
<li><strong>主觀判斷困境</strong>：不同開發者對「任務大小」的理解不同，導致協作效率低</li>
<li><strong>進度追蹤困難</strong>：任務粒度不一致，難以準確評估完成度</li>
<li><strong>風險控制失衡</strong>：大任務失敗影響大，小任務過碎增加管理成本</li>
</ol>
<p><strong>傳統拆分方法的問題</strong>:</p>
<ul>
<li><strong>經驗導向</strong>：依賴個人經驗判斷，缺乏客觀標準</li>
<li><strong>時間估算</strong>：受個人能力和環境影響，難以標準化</li>
<li><strong>模糊描述</strong>：「不要太大」「保持適中」等描述無法執行</li>
<li><strong>後驗調整</strong>：任務執行後才發現過大，增加返工成本</li>
</ul>
<hr>
<h3 id="核心目標">核心目標</h3>
<ol>
<li><strong>標準化任務拆分</strong>：提供統一的拆分標準，消除主觀判斷</li>
<li><strong>控制任務複雜度</strong>：確保每個 Ticket 在可控範圍內</li>
<li><strong>提升協作效率</strong>：明確的任務邊界，減少溝通成本</li>
<li><strong>及早風險管控</strong>：設計階段就識別過大任務，降低執行風險</li>
</ol>
<hr>
<h3 id="與其他方法論的關係">與其他方法論的關係</h3>
<p><strong>本方法論的定位</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Ticket 設計派工方法論 (主方法論)
</span></span><span class="line"><span class="ln">2</span><span class="cl">├── Ticket 拆分標準方法論 ← 你正在閱讀
</span></span><span class="line"><span class="ln">3</span><span class="cl">│   └── 提供量化拆分標準和決策樹
</span></span><span class="line"><span class="ln">4</span><span class="cl">├── Code Smell 品質閘門檢測方法論
</span></span><span class="line"><span class="ln">5</span><span class="cl">│   └── 提供設計階段的品質檢測
</span></span><span class="line"><span class="ln">6</span><span class="cl">├── Ticket 生命週期管理方法論
</span></span><span class="line"><span class="ln">7</span><span class="cl">│   └── 提供 Ticket 執行流程管理
</span></span><span class="line"><span class="ln">8</span><span class="cl">└── 即時 Review 機制方法論
</span></span><span class="line"><span class="ln">9</span><span class="cl">    └── 提供執行過程中的 Review 機制</span></span></code></pre></div><hr>
<h2 id="第一章量化指標體系">第一章：量化指標體系</h2>
<h3 id="11-指標-1職責數量responsibilities-最優先">1.1 指標 1：職責數量（Responsibilities） 最優先</h3>
<p><strong>定義</strong>：Ticket 需要完成的獨立職責數量。</p>
<p><strong>為什麼職責是第一指標</strong>：</p>
<ul>
<li><strong>最客觀</strong>：不受個人能力影響</li>
<li><strong>最穩定</strong>：不受環境和參考資料影響</li>
<li><strong>最易溝通</strong>：PM 和工程師都能理解</li>
<li><strong>最精確</strong>：直接對應業務需求</li>
</ul>
<h4 id="職責的精確定義">職責的精確定義</h4>
<p><strong>什麼算一個職責</strong>：</p>
<p>一個職責 = 一個明確可驗證的功能點或邊界條件</p>
<p><strong>識別方式</strong>：</p>
<ul>
<li>每個「需要實作的功能點」算一個職責</li>
<li>每個「需要驗證的邊界條件」算一個職責</li>
<li>每個「需要處理的錯誤情境」算一個職責</li>
</ul>
<p><strong>範例說明</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">範例任務：實作書籍評分功能
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">職責識別：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="k">1.</span> 定義 Rating Value Object（數值範圍驗證）      ← 職責 1
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">2.</span> 定義 Rating Entity（包含評分和評論）         ← 職責 2
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">3.</span> 實作 IRatingRepository 介面                  ← 職責 3
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">4.</span> 實作評分儲存邏輯                              ← 職責 4
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">5.</span> 處理無效評分錯誤                              ← 職責 5
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">6.</span> 處理資料庫錯誤                                ← 職責 6
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">總計：6 個職責 → 超過 5 個，必須拆分</span></span></code></pre></div><h4 id="職責數量標準">職責數量標準</h4>
<table>
  <thead>
      <tr>
          <th>等級</th>
          <th>職責數量</th>
          <th>判定</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>簡單 Ticket</strong></td>
          <td>1 個</td>
          <td>理想</td>
          <td>單一職責，最易管理</td>
      </tr>
      <tr>
          <td><strong>中等 Ticket</strong></td>
          <td>2-3 個</td>
          <td>可接受</td>
          <td>少數相關職責，可控範圍</td>
      </tr>
      <tr>
          <td><strong>複雜 Ticket</strong></td>
          <td>3-5 個</td>
          <td>需檢查</td>
          <td>多職責，建議拆分</td>
      </tr>
      <tr>
          <td><strong>必須拆分</strong></td>
          <td>&gt; 5 個</td>
          <td>禁止</td>
          <td>範圍失控，必須拆分</td>
      </tr>
  </tbody>
</table>
<p><strong>強制規則</strong>：</p>
<ul>
<li><strong>超過 5 個職責 = 必須拆分</strong>，無例外</li>
<li><strong>3-5 個職責 = 評估是否可拆分</strong>，優先拆分</li>
<li><strong>1-2 個職責 = 理想狀態</strong>，鼓勵維持</li>
</ul>
<h4 id="職責識別實例">職責識別實例</h4>
<h5 id="實例-1簡單-ticket1-職責">實例 1：簡單 Ticket（1 職責）</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">任務：定義 SelectionManager 介面方法簽名
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">職責分析：
</span></span><span class="line"><span class="ln">4</span><span class="cl">職責 1：定義 toggleSelection、clearSelection、getSelectedIds 三個方法簽名
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl">總計：1 個職責
</span></span><span class="line"><span class="ln">7</span><span class="cl">判定：簡單 Ticket</span></span></code></pre></div><h6 id="實例-2中等-ticket2-3-職責">實例 2：中等 Ticket（2-3 職責）</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">任務：實作 SelectionManager 基礎功能
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">職責分析：
</span></span><span class="line"><span class="ln">4</span><span class="cl">職責 1：實作 toggleSelection 方法
</span></span><span class="line"><span class="ln">5</span><span class="cl">職責 2：實作 clearSelection 方法
</span></span><span class="line"><span class="ln">6</span><span class="cl">職責 3：實作 ChangeNotifier 通知機制
</span></span><span class="line"><span class="ln">7</span><span class="cl">
</span></span><span class="line"><span class="ln">8</span><span class="cl">總計：3 個職責
</span></span><span class="line"><span class="ln">9</span><span class="cl">判定：中等 Ticket（可接受）</span></span></code></pre></div><h6 id="實例-3複雜-ticket3-5-職責--建議拆分">實例 3：複雜 Ticket（3-5 職責）- 建議拆分</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：實作完整的 BookRepository
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">職責分析：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">職責 1：實作 getBookByIsbn CRUD 方法
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">職責 2：實作 saveBook CRUD 方法
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">職責 3：實作 Data Mapper 轉換
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">職責 4：實作錯誤處理
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">職責 5：實作 Cache 管理
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">總計：5 個職責
</span></span><span class="line"><span class="ln">11</span><span class="cl">判定：複雜 Ticket（建議拆分為 2-3 個 Ticket）</span></span></code></pre></div><h6 id="實例-4必須拆分-5-職責">實例 4：必須拆分（&gt; 5 職責）</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：實作書籍評分完整功能（包含 UI、UseCase、Repository）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">職責分析：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">職責 1：定義 Rating Value Object
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">職責 2：定義 Rating Entity
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">職責 3：建立 RatingWidget UI
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">職責 4：實作 RateBookUseCase
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">職責 5：定義 IRatingRepository
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">職責 6：實作 SQLiteRatingRepository
</span></span><span class="line"><span class="ln">10</span><span class="cl">職責 7：處理各種異常情境
</span></span><span class="line"><span class="ln">11</span><span class="cl">職責 8：撰寫完整測試
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">總計：8 個職責
</span></span><span class="line"><span class="ln">14</span><span class="cl">判定：God Ticket 必須拆分</span></span></code></pre></div><p><strong>拆分建議</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">拆分為 4 個 Ticket：
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> Ticket 1: 定義 Rating Domain 模型（職責 1, 2）
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="k">-</span> Ticket 2: 實作 RatingRepository（職責 5, 6）
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">-</span> Ticket 3: 實作 RateBookUseCase（職責 4, 7）
</span></span><span class="line"><span class="ln">6</span><span class="cl">- Ticket 4: 實作 RatingWidget UI（職責 3, 8）</span></span></code></pre></div><hr>
<h3 id="12-指標-2程式碼行數lines-of-code">1.2 指標 2：程式碼行數（Lines of Code）</h3>
<p><strong>定義</strong>：Ticket 涉及的程式碼修改行數（新增 + 修改 + 刪除）。</p>
<p><strong>為什麼需要行數指標</strong>：</p>
<ul>
<li><strong>可量化</strong>：使用 <code>git diff --stat</code> 精確統計</li>
<li><strong>可驗證</strong>：執行後可驗證預估準確性</li>
<li><strong>風險指標</strong>：行數越多，出錯風險越高</li>
</ul>
<h4 id="行數統計標準">行數統計標準</h4>
<p><strong>測量方式</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1"># 統計修改行數</span>
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">git diff --stat
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1"># 範例輸出</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">lib/domain/entities/book.dart        <span class="p">|</span> <span class="m">25</span> +++++++++++++
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">lib/domain/repositories/i_repo.dart  <span class="p">|</span> <span class="m">15</span> ++++++--
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">test/unit/domain/book_test.dart      <span class="p">|</span> <span class="m">40</span> ++++++++++++++++++++
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="m">3</span> files changed, <span class="m">78</span> insertions<span class="o">(</span>+<span class="o">)</span>, <span class="m">2</span> deletions<span class="o">(</span>-<span class="o">)</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"># 計算方式</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="nv">總行數</span> <span class="o">=</span> 新增行數 + 修改行數 + <span class="nv">刪除行數</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">      <span class="o">=</span> <span class="m">25</span> + <span class="m">15</span> + <span class="nv">40</span> <span class="o">=</span> <span class="m">80</span> 行</span></span></code></pre></div><p><strong>計算規則</strong>：</p>
<ul>
<li>包含新增行數</li>
<li>包含修改行數</li>
<li>包含刪除行數</li>
<li>不包含空行（pure whitespace changes）</li>
<li>不包含純註解行（comment-only changes）</li>
</ul>
<h4 id="行數標準">行數標準</h4>
<table>
  <thead>
      <tr>
          <th>等級</th>
          <th>行數範圍</th>
          <th>判定</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>簡單 Ticket</strong></td>
          <td>&lt; 30 行</td>
          <td>理想</td>
          <td>Interface 定義、簡單 Value Object</td>
      </tr>
      <tr>
          <td><strong>中等 Ticket</strong></td>
          <td>30-70 行</td>
          <td>可接受</td>
          <td>中等實作、含測試</td>
      </tr>
      <tr>
          <td><strong>複雜 Ticket</strong></td>
          <td>70-100 行</td>
          <td>需檢查</td>
          <td>複雜實作、多測試案例</td>
      </tr>
      <tr>
          <td><strong>必須拆分</strong></td>
          <td>&gt; 100 行</td>
          <td>禁止</td>
          <td>範圍過大，必須拆分</td>
      </tr>
  </tbody>
</table>
<p><strong>強制規則</strong>：</p>
<ul>
<li><strong>超過 100 行 = 必須拆分</strong></li>
<li><strong>70-100 行 = 評估是否可拆分</strong></li>
<li><strong>&lt; 70 行 = 可接受範圍</strong></li>
</ul>
<h4 id="行數估算實例">行數估算實例</h4>
<h5 id="實例-1簡單-ticket-30-行">實例 1：簡單 Ticket（&lt; 30 行）</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// 任務：定義 IBookRepository 介面
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1">// lib/domain/repositories/i_book_repository.dart
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">IBookRepository</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">  <span class="c1">/// 根據 ISBN 取得書籍
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"></span>  <span class="n">Future</span><span class="o">&lt;</span><span class="n">Book</span><span class="o">?&gt;</span> <span class="n">getBookByIsbn</span><span class="p">(</span><span class="kt">String</span> <span class="n">isbn</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  <span class="c1">/// 儲存書籍
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"></span>  <span class="n">Future</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">saveBook</span><span class="p">(</span><span class="n">Book</span> <span class="n">book</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">  <span class="c1">/// 刪除書籍
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"></span>  <span class="n">Future</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">deleteBook</span><span class="p">(</span><span class="kt">String</span> <span class="n">isbn</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="c1">// 預估行數：~20 行（含註解）
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="c1"></span><span class="o">//</span> <span class="err">判定：簡單</span> <span class="n">Ticket</span></span></span></code></pre></div><h6 id="實例-2中等-ticket30-70-行">實例 2：中等 Ticket（30-70 行）</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// 任務：實作 Rating Value Object
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1">// lib/domain/value_objects/rating.dart + test
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1">// rating.dart (~40 行)
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"></span><span class="kd">class</span> <span class="nc">Rating</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  <span class="kd">final</span> <span class="kt">int</span> <span class="n">value</span><span class="p">;</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  <span class="n">Rating</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="n">value</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">value</span> <span class="o">&lt;</span> <span class="m">1</span> <span class="o">||</span> <span class="n">value</span> <span class="o">&gt;</span> <span class="m">5</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">      <span class="k">throw</span> <span class="n">ValidationException</span><span class="p">.</span><span class="n">invalidRating</span><span class="p">(</span><span class="n">value</span><span class="p">);</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl">  <span class="c1">// ... 其他方法（equals, hashCode, toString）
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="c1">// rating_test.dart (~25 行)
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">  <span class="n">test</span><span class="p">(</span><span class="s1">&#39;建立有效評分&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl">  <span class="n">test</span><span class="p">(</span><span class="s1">&#39;評分過低拋出異常&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">  <span class="n">test</span><span class="p">(</span><span class="s1">&#39;評分過高拋出異常&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="c1">// 總計：~65 行
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="c1"></span><span class="o">//</span> <span class="err">判定：中等</span> <span class="n">Ticket</span></span></span></code></pre></div><h6 id="實例-3複雜-ticket70-100-行--建議拆分">實例 3：複雜 Ticket（70-100 行）- 建議拆分</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// 任務：實作完整的 BookRepository
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1">// lib/infrastructure/repositories/sqlite_book_repository.dart + test
</span></span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="c1">// repository.dart (~80 行)
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"></span><span class="kd">class</span> <span class="nc">SQLiteBookRepository</span> <span class="kd">implements</span> <span class="n">IBookRepository</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  <span class="c1">// ... 建構子和欄位定義
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  <span class="err">@</span><span class="n">override</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  <span class="n">Future</span><span class="o">&lt;</span><span class="n">Book</span><span class="o">?&gt;</span> <span class="n">getBookByIsbn</span><span class="p">(</span><span class="kt">String</span> <span class="n">isbn</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="c1">// ... SQL 查詢邏輯（~15 行）
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"></span>    <span class="c1">// ... Data Mapper 轉換（~10 行）
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"></span>    <span class="c1">// ... 錯誤處理（~5 行）
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="c1"></span>  <span class="p">}</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">  <span class="err">@</span><span class="n">override</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">  <span class="n">Future</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">saveBook</span><span class="p">(</span><span class="n">Book</span> <span class="n">book</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">    <span class="c1">// ... SQL 插入/更新邏輯（~20 行）
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"></span>    <span class="c1">// ... Data Mapper 轉換（~10 行）
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="c1"></span>    <span class="c1">// ... 錯誤處理（~5 行）
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="c1"></span>  <span class="p">}</span>
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl">  <span class="err">@</span><span class="n">override</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl">  <span class="n">Future</span><span class="o">&lt;</span><span class="kt">void</span><span class="o">&gt;</span> <span class="n">deleteBook</span><span class="p">(</span><span class="kt">String</span> <span class="n">isbn</span><span class="p">)</span> <span class="kd">async</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">    <span class="c1">// ... SQL 刪除邏輯（~10 行）
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="c1"></span>    <span class="c1">// ... 錯誤處理（~5 行）
</span></span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="c1"></span>  <span class="p">}</span>
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl">
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="c1">// repository_test.dart (~80 行)
</span></span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="c1">// ... 8 個測試案例
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="c1">// 總計：~160 行
</span></span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="c1"></span><span class="o">//</span> <span class="err">判定：超過</span> <span class="m">100</span> <span class="err">行，必須拆分</span></span></span></code></pre></div><p><strong>拆分建議</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">拆分為 3 個 Ticket：
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> Ticket 1: 定義 IBookRepository 介面（~20 行）
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="k">-</span> Ticket 2: 實作 getBookByIsbn + 測試（~60 行）
</span></span><span class="line"><span class="ln">5</span><span class="cl">- Ticket 3: 實作 saveBook + deleteBook + 測試（~80 行）</span></span></code></pre></div><hr>
<h3 id="13-指標-3涉及檔案數files">1.3 指標 3：涉及檔案數（Files）</h3>
<p><strong>定義</strong>：Ticket 需要修改的檔案數量（不含測試檔案）。</p>
<p><strong>為什麼需要檔案數指標</strong>：</p>
<ul>
<li><strong>架構層級指標</strong>：檔案數反映任務的架構範圍</li>
<li><strong>風險管控</strong>：修改越多檔案，影響範圍越大</li>
<li><strong>測試複雜度</strong>：檔案數越多，測試整合越複雜</li>
</ul>
<h4 id="檔案統計標準">檔案統計標準</h4>
<p><strong>測量方式</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="ln">1</span><span class="cl"><span class="c1"># 統計修改檔案數</span>
</span></span><span class="line"><span class="ln">2</span><span class="cl">git diff --name-only <span class="p">|</span> grep -v <span class="s1">&#39;_test\.dart$&#39;</span> <span class="p">|</span> wc -l
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="c1"># 範例輸出</span>
</span></span><span class="line"><span class="ln">5</span><span class="cl">lib/domain/entities/book.dart
</span></span><span class="line"><span class="ln">6</span><span class="cl">lib/domain/repositories/i_book_repository.dart
</span></span><span class="line"><span class="ln">7</span><span class="cl">lib/infrastructure/repositories/sqlite_book_repository.dart
</span></span><span class="line"><span class="ln">8</span><span class="cl">
</span></span><span class="line"><span class="ln">9</span><span class="cl"><span class="c1"># 結果：3 個檔案（不含測試）</span></span></span></code></pre></div><p><strong>計算規則</strong>：</p>
<ul>
<li>包含新建檔案</li>
<li>包含修改檔案</li>
<li>包含刪除檔案</li>
<li>不包含測試檔案（測試檔案另計為「測試數量」指標）</li>
<li>不包含配置檔案（如 pubspec.yaml, analysis_options.yaml）</li>
</ul>
<h4 id="檔案數標準">檔案數標準</h4>
<table>
  <thead>
      <tr>
          <th>等級</th>
          <th>檔案數量</th>
          <th>判定</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>簡單 Ticket</strong></td>
          <td>1 個</td>
          <td>理想</td>
          <td>單一檔案修改</td>
      </tr>
      <tr>
          <td><strong>中等 Ticket</strong></td>
          <td>2-3 個</td>
          <td>可接受</td>
          <td>相關檔案修改</td>
      </tr>
      <tr>
          <td><strong>複雜 Ticket</strong></td>
          <td>3-5 個</td>
          <td>需檢查</td>
          <td>多檔案修改，建議拆分</td>
      </tr>
      <tr>
          <td><strong>必須拆分</strong></td>
          <td>&gt; 5 個</td>
          <td>禁止</td>
          <td>範圍過大，必須拆分</td>
      </tr>
  </tbody>
</table>
<p><strong>強制規則</strong>：</p>
<ul>
<li><strong>超過 5 個檔案 = 必須拆分</strong></li>
<li><strong>3-5 個檔案 = 評估是否可拆分</strong></li>
<li><strong>1-2 個檔案 = 理想狀態</strong></li>
</ul>
<h4 id="檔案數實例">檔案數實例</h4>
<h5 id="實例-1簡單-ticket1-個檔案">實例 1：簡單 Ticket（1 個檔案）</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">任務：建立 Rating Value Object
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">涉及檔案：
</span></span><span class="line"><span class="ln">4</span><span class="cl">lib/domain/value_objects/rating.dart
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl">總計：1 個檔案
</span></span><span class="line"><span class="ln">7</span><span class="cl">判定：簡單 Ticket</span></span></code></pre></div><h6 id="實例-2中等-ticket2-3-個檔案">實例 2：中等 Ticket（2-3 個檔案）</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">任務：更新 Book Entity 增加評分欄位
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">涉及檔案：
</span></span><span class="line"><span class="ln">4</span><span class="cl">lib/domain/entities/book.dart         （修改）
</span></span><span class="line"><span class="ln">5</span><span class="cl">lib/domain/value_objects/rating.dart  （新增）
</span></span><span class="line"><span class="ln">6</span><span class="cl">
</span></span><span class="line"><span class="ln">7</span><span class="cl">總計：2 個檔案
</span></span><span class="line"><span class="ln">8</span><span class="cl">判定：中等 Ticket</span></span></code></pre></div><h6 id="實例-3複雜-ticket3-5-個檔案--建議拆分">實例 3：複雜 Ticket（3-5 個檔案）- 建議拆分</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：實作完整的書籍評分功能
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">涉及檔案：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">lib/domain/entities/rating.dart
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">lib/domain/entities/book.dart
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">lib/domain/repositories/i_rating_repository.dart
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">lib/infrastructure/repositories/sqlite_rating_repository.dart
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">lib/infrastructure/mappers/rating_mapper.dart
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">總計：5 個檔案
</span></span><span class="line"><span class="ln">11</span><span class="cl">判定：複雜 Ticket（建議拆分）</span></span></code></pre></div><h6 id="實例-4必須拆分-5-個檔案">實例 4：必須拆分（&gt; 5 個檔案）</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：實作評分功能（含 UI、UseCase、Repository）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">涉及檔案：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">lib/presentation/widgets/rating_widget.dart
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">lib/presentation/controllers/rating_controller.dart
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">lib/application/use_cases/rate_book_use_case.dart
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">lib/domain/entities/rating.dart
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">lib/domain/entities/book.dart
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">lib/domain/repositories/i_rating_repository.dart
</span></span><span class="line"><span class="ln">10</span><span class="cl">lib/infrastructure/repositories/sqlite_rating_repository.dart
</span></span><span class="line"><span class="ln">11</span><span class="cl">lib/infrastructure/mappers/rating_mapper.dart
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">總計：8 個檔案
</span></span><span class="line"><span class="ln">14</span><span class="cl">判定：God Ticket，必須拆分</span></span></code></pre></div><p><strong>拆分建議</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">按 Clean Architecture 分層拆分為 4 個 Ticket：
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> Ticket 1: Domain 層（檔案 4, 5, 6）             - 3 個檔案
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="k">-</span> Ticket 2: Infrastructure 層（檔案 7, 8）        - 2 個檔案
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">-</span> Ticket 3: Application 層（檔案 3）              - 1 個檔案
</span></span><span class="line"><span class="ln">6</span><span class="cl">- Ticket 4: Presentation 層（檔案 1, 2）          - 2 個檔案</span></span></code></pre></div><hr>
<h3 id="14-指標-4測試用例數tests">1.4 指標 4：測試用例數（Tests）</h3>
<p><strong>定義</strong>：Ticket 對應的測試用例數量。</p>
<p><strong>為什麼需要測試數量指標</strong>：</p>
<ul>
<li><strong>品質保證指標</strong>：測試數量反映功能複雜度</li>
<li><strong>執行時間預估</strong>：測試數量影響 TDD 循環時間</li>
<li><strong>維護成本</strong>：過多測試增加維護負擔</li>
</ul>
<h4 id="測試統計標準">測試統計標準</h4>
<p><strong>測量方式</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// 計算測試方法數
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span><span class="kt">void</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">  <span class="n">group</span><span class="p">(</span><span class="s1">&#39;Rating Value Object&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;建立有效評分&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>           <span class="c1">// 測試 1
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;評分過低拋出異常&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>        <span class="c1">// 測試 2
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;評分過高拋出異常&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>        <span class="c1">// 測試 3
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;相同評分視為相等&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>        <span class="c1">// 測試 4
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"></span>  <span class="p">});</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="o">//</span> <span class="err">總計：</span><span class="m">4</span> <span class="err">個測試</span></span></span></code></pre></div><p><strong>計算規則</strong>：</p>
<ul>
<li>每個 <code>test('...', () {...})</code> 算一個測試</li>
<li>每個 <code>testWidgets('...', () {...})</code> 算一個測試</li>
<li>包含單元測試和整合測試</li>
<li>不包含 <code>group()</code> 本身（只是測試組織）</li>
</ul>
<h4 id="測試數量標準">測試數量標準</h4>
<table>
  <thead>
      <tr>
          <th>等級</th>
          <th>測試數量</th>
          <th>判定</th>
          <th>說明</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>簡單 Ticket</strong></td>
          <td>1-3 個</td>
          <td>理想</td>
          <td>基本功能測試</td>
      </tr>
      <tr>
          <td><strong>中等 Ticket</strong></td>
          <td>3-6 個</td>
          <td>可接受</td>
          <td>含邊界和異常測試</td>
      </tr>
      <tr>
          <td><strong>複雜 Ticket</strong></td>
          <td>6-10 個</td>
          <td>需檢查</td>
          <td>複雜邏輯，多測試案例</td>
      </tr>
      <tr>
          <td><strong>必須拆分</strong></td>
          <td>&gt; 10 個</td>
          <td>禁止</td>
          <td>測試過多，必須拆分</td>
      </tr>
  </tbody>
</table>
<p><strong>強制規則</strong>：</p>
<ul>
<li><strong>超過 10 個測試 = 必須拆分</strong></li>
<li><strong>6-10 個測試 = 評估是否可拆分</strong></li>
<li><strong>1-6 個測試 = 可接受範圍</strong></li>
</ul>
<h4 id="測試數量實例">測試數量實例</h4>
<h5 id="實例-1簡單-ticket1-3-個測試">實例 1：簡單 Ticket（1-3 個測試）</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// 任務：定義 Rating Value Object
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  <span class="n">group</span><span class="p">(</span><span class="s1">&#39;Rating Value Object&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;建立有效評分&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">      <span class="kd">final</span> <span class="n">rating</span> <span class="o">=</span> <span class="n">Rating</span><span class="p">(</span><span class="m">4</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">      <span class="n">expect</span><span class="p">(</span><span class="n">rating</span><span class="p">.</span><span class="n">value</span><span class="p">,</span> <span class="m">4</span><span class="p">);</span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;評分過低拋出異常&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl">      <span class="n">expect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="n">Rating</span><span class="p">(</span><span class="m">0</span><span class="p">),</span> <span class="n">throwsA</span><span class="p">(</span><span class="n">isA</span><span class="o">&lt;</span><span class="n">ValidationException</span><span class="o">&gt;</span><span class="p">()));</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl">    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;評分過高拋出異常&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">      <span class="n">expect</span><span class="p">(()</span> <span class="o">=&gt;</span> <span class="n">Rating</span><span class="p">(</span><span class="m">6</span><span class="p">),</span> <span class="n">throwsA</span><span class="p">(</span><span class="n">isA</span><span class="o">&lt;</span><span class="n">ValidationException</span><span class="o">&gt;</span><span class="p">()));</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl">  <span class="p">});</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="c1">// 總計：3 個測試
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="c1"></span><span class="o">//</span> <span class="err">判定：簡單</span> <span class="n">Ticket</span></span></span></code></pre></div><h6 id="實例-2中等-ticket3-6-個測試">實例 2：中等 Ticket（3-6 個測試）</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// 任務：實作 BookRepository.getBookByIsbn
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  <span class="n">group</span><span class="p">(</span><span class="s1">&#39;BookRepository.getBookByIsbn&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;成功取得存在的書籍&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>          <span class="c1">// 測試 1
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;書籍不存在回傳 null&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>          <span class="c1">// 測試 2
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;無效 ISBN 拋出 ValidationException&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span> <span class="c1">// 測試 3
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;資料庫錯誤拋出 StorageException&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>    <span class="c1">// 測試 4
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;資料庫連線失敗拋出 NetworkException&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span> <span class="c1">// 測試 5
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"></span>  <span class="p">});</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="c1">// 總計：5 個測試
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="c1"></span><span class="o">//</span> <span class="err">判定：中等</span> <span class="n">Ticket</span></span></span></code></pre></div><h6 id="實例-3複雜-ticket6-10-個測試--建議拆分">實例 3：複雜 Ticket（6-10 個測試）- 建議拆分</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-dart" data-lang="dart"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="c1">// 任務：實作完整的 BookRepository CRUD
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="kt">void</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">  <span class="n">group</span><span class="p">(</span><span class="s1">&#39;BookRepository CRUD&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    <span class="c1">// getBookByIsbn 測試
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;取得存在的書籍&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>              <span class="c1">// 測試 1
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;書籍不存在回傳 null&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>         <span class="c1">// 測試 2
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    <span class="c1">// saveBook 測試
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;新增書籍成功&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>                <span class="c1">// 測試 3
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;更新書籍成功&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>                <span class="c1">// 測試 4
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;儲存時資料庫錯誤&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>            <span class="c1">// 測試 5
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln">14</span><span class="cl">    <span class="c1">// deleteBook 測試
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;刪除存在的書籍&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>              <span class="c1">// 測試 6
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;刪除不存在的書籍&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>            <span class="c1">// 測試 7
</span></span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;刪除時資料庫錯誤&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>            <span class="c1">// 測試 8
</span></span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">    <span class="c1">// Data Mapper 測試
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;Entity 轉 DTO 正確&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>          <span class="c1">// 測試 9
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="c1"></span>    <span class="n">test</span><span class="p">(</span><span class="s1">&#39;DTO 轉 Entity 正確&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">{</span> <span class="p">...</span> <span class="p">});</span>          <span class="c1">// 測試 10
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="c1"></span>  <span class="p">});</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl">
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="c1">// 總計：10 個測試
</span></span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="c1"></span><span class="o">//</span> <span class="err">判定：複雜</span> <span class="n">Ticket</span><span class="err">（達上限，建議拆分）</span></span></span></code></pre></div><p><strong>拆分建議</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">拆分為 3 個 Ticket：
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> Ticket 1: getBookByIsbn + 測試（2 個測試）    
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="k">-</span> Ticket 2: saveBook + 測試（3 個測試）         
</span></span><span class="line"><span class="ln">5</span><span class="cl">- Ticket 3: deleteBook + Mapper + 測試（5 個測試）</span></span></code></pre></div><hr>
<h3 id="15-指標整合評估方法">1.5 指標整合評估方法</h3>
<h4 id="整合評估原則">整合評估原則</h4>
<p><strong>最高等級原則</strong>：</p>
<ul>
<li>取 4 個指標中「最高的複雜度等級」作為最終評估結果</li>
<li>任一指標達到「必須拆分」，則整個 Ticket 必須拆分</li>
</ul>
<p><strong>評估公式</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">Ticket 複雜度 = max(職責複雜度, 行數複雜度, 檔案數複雜度, 測試數複雜度)
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">where 複雜度等級：
</span></span><span class="line"><span class="ln">4</span><span class="cl">  簡單 = 1
</span></span><span class="line"><span class="ln">5</span><span class="cl">  中等 = 2
</span></span><span class="line"><span class="ln">6</span><span class="cl">  複雜 = 3
</span></span><span class="line"><span class="ln">7</span><span class="cl">  必須拆分 = 4</span></span></code></pre></div><h4 id="整合評估實例">整合評估實例</h4>
<h5 id="實例-1所有指標都是簡單--簡單-ticket">實例 1：所有指標都是簡單 → 簡單 Ticket</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：定義 Rating Value Object
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">指標評估：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> 職責數量：1 個職責 → 簡單
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 程式碼行數：25 行 → 簡單
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 涉及檔案：1 個檔案 → 簡單
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">-</span> 測試用例：3 個測試 → 簡單
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">最終判定：簡單 Ticket（最理想狀態）</span></span></code></pre></div><h6 id="實例-2有一個指標是中等--中等-ticket">實例 2：有一個指標是中等 → 中等 Ticket</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：實作 Rating Value Object
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">指標評估：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> 職責數量：2 個職責（建立、驗證）→ 中等
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 程式碼行數：45 行 → 中等
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 涉及檔案：1 個檔案 → 簡單
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">-</span> 測試用例：5 個測試 → 中等
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">最終判定：中等 Ticket（可接受）</span></span></code></pre></div><h6 id="實例-3有一個指標是複雜--複雜-ticket建議拆分">實例 3：有一個指標是複雜 → 複雜 Ticket（建議拆分）</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：實作 BookRepository.getBookByIsbn
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">指標評估：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> 職責數量：3 個職責（查詢、轉換、異常處理）→ 複雜
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 程式碼行數：65 行 → 中等
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 涉及檔案：2 個檔案 → 中等
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">-</span> 測試用例：6 個測試 → 複雜
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">最終判定：複雜 Ticket（建議拆分）</span></span></code></pre></div><h6 id="實例-4有任一指標超標--必須拆分">實例 4：有任一指標超標 → 必須拆分</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：實作完整的書籍評分功能
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">指標評估：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> 職責數量：8 個職責 → 必須拆分
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 程式碼行數：180 行 → 必須拆分
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 涉及檔案：7 個檔案 → 必須拆分
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">-</span> 測試用例：15 個測試 → 必須拆分
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">最終判定：God Ticket 必須立即拆分</span></span></code></pre></div><h4 id="評估決策流程">評估決策流程</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">步驟 1：計算 4 個指標
</span></span><span class="line"><span class="ln">2</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln">3</span><span class="cl">步驟 2：取最高複雜度等級
</span></span><span class="line"><span class="ln">4</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln">5</span><span class="cl">    ├─ 簡單 → 可直接建立 Ticket
</span></span><span class="line"><span class="ln">6</span><span class="cl">    ├─ 中等 → 可直接建立 Ticket（可選：評估是否拆分為更小 Ticket）
</span></span><span class="line"><span class="ln">7</span><span class="cl">    ├─ 複雜 → 強烈建議拆分（可選：無法拆分時勉強接受）
</span></span><span class="line"><span class="ln">8</span><span class="cl">    └─ 必須拆分 → 阻止建立，必須先拆分再重新評估</span></span></code></pre></div><p><strong>評估檢查清單</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已計算 4 個指標的值
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已確定每個指標的複雜度等級
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已取最高複雜度等級作為最終判定
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 如為「必須拆分」，已執行拆分並重新評估
</span></span><span class="line"><span class="ln">5</span><span class="cl">□ 如為「複雜」，已評估是否可拆分為更小 Ticket</span></span></code></pre></div><hr>
<h2 id="第二章複雜度評估方法">第二章：複雜度評估方法</h2>
<h3 id="21-複雜度等級定義">2.1 複雜度等級定義</h3>
<p><strong>4 級複雜度體系</strong>：</p>
<table>
  <thead>
      <tr>
          <th>等級</th>
          <th>職責</th>
          <th>行數</th>
          <th>檔案</th>
          <th>測試</th>
          <th>描述</th>
          <th>處理方式</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>Level 1: 簡單</strong></td>
          <td>1 個</td>
          <td>&lt; 30 行</td>
          <td>1 個</td>
          <td>1-3 個</td>
          <td>單一職責，單一檔案</td>
          <td>直接建立 Ticket</td>
      </tr>
      <tr>
          <td><strong>Level 2: 中等</strong></td>
          <td>2-3 個</td>
          <td>30-70 行</td>
          <td>2-3 個</td>
          <td>3-6 個</td>
          <td>少數相關職責，少數檔案</td>
          <td>直接建立 Ticket</td>
      </tr>
      <tr>
          <td><strong>Level 3: 複雜</strong></td>
          <td>3-5 個</td>
          <td>70-100 行</td>
          <td>3-5 個</td>
          <td>6-10 個</td>
          <td>多職責，多檔案</td>
          <td>建議拆分</td>
      </tr>
      <tr>
          <td><strong>Level 4: 超標</strong></td>
          <td>&gt; 5 個</td>
          <td>&gt; 100 行</td>
          <td>&gt; 5 個</td>
          <td>&gt; 10 個</td>
          <td>範圍失控</td>
          <td>必須拆分</td>
      </tr>
  </tbody>
</table>
<p><strong>複雜度特徵</strong>：</p>
<h4 id="level-1-簡單">Level 1: 簡單</h4>
<ul>
<li><strong>特徵</strong>: 最小可交付單元，職責明確</li>
<li><strong>適用</strong>: Interface 定義、單一 Value Object、單一方法實作</li>
<li><strong>優點</strong>: 風險低、易測試、易 Review</li>
<li><strong>預估時間</strong>: 5-20 分鐘</li>
</ul>
<h5 id="level-2-中等">Level 2: 中等</h5>
<ul>
<li><strong>特徵</strong>: 少數相關職責，內聚性高</li>
<li><strong>適用</strong>: 含業務邏輯的 Entity、基礎 Repository 方法</li>
<li><strong>注意</strong>: 確保職責相關性，避免職責分散</li>
<li><strong>預估時間</strong>: 20-40 分鐘</li>
</ul>
<h6 id="level-3-複雜">Level 3: 複雜</h6>
<ul>
<li><strong>特徵</strong>: 多職責或跨檔案，整合性高</li>
<li><strong>適用</strong>: 完整 UseCase、Repository CRUD、複雜業務邏輯</li>
<li><strong>風險</strong>: 測試複雜、Review 困難、易出錯</li>
<li><strong>預估時間</strong>: 40-60 分鐘</li>
<li><strong>建議</strong>: 優先評估是否可拆分為 Level 1-2</li>
</ul>
<h6 id="level-4-超標">Level 4: 超標</h6>
<ul>
<li><strong>特徵</strong>: 任一指標超標，範圍失控</li>
<li><strong>問題</strong>: God Ticket、高風險、難以管理</li>
<li><strong>處理</strong>: 必須拆分，無例外</li>
<li><strong>禁止</strong>: 禁止建立此等級 Ticket</li>
</ul>
<hr>
<h3 id="22-評估流程">2.2 評估流程</h3>
<p><strong>3 步驟評估流程</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">步驟 1: 初步評估（基於任務描述）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    計算 4 個指標的預估值
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">步驟 2: 複雜度確認（取最高等級）
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    取 4 個指標中最高的複雜度等級
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">步驟 3: 拆分決策（基於等級決定）
</span></span><span class="line"><span class="ln">10</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln">11</span><span class="cl">    ├─ Level 1-2 → 可直接建立 Ticket
</span></span><span class="line"><span class="ln">12</span><span class="cl">    ├─ Level 3 → 評估是否可拆分
</span></span><span class="line"><span class="ln">13</span><span class="cl">    └─ Level 4 → 必須拆分</span></span></code></pre></div><h4 id="步驟-1初步評估">步驟 1：初步評估</h4>
<p><strong>目標</strong>: 快速估算 4 個指標的值</p>
<p><strong>評估依據</strong>:</p>
<ol>
<li>任務描述（What to do）</li>
<li>驗收條件（Acceptance Criteria）</li>
<li>預期步驟（Steps）</li>
</ol>
<p><strong>評估方法</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">範例任務：實作 Book Entity
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">步驟 1-1：估算職責數量
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="k">-</span> 分析任務描述，列出所有需要完成的功能點
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> 功能點 1：定義 Entity 欄位
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 功能點 2：實作 equals/hashCode
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 功能點 3：實作 toString
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">-</span> 功能點 4：撰寫測試
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">→ 預估：4 個職責
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">步驟 1-2：估算程式碼行數
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">-</span> 根據類似任務經驗估算
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> Entity 定義：~30 行
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">-</span> equals/hashCode：~15 行
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">-</span> toString：~5 行
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">-</span> 測試：~40 行
</span></span><span class="line"><span class="ln">17</span><span class="cl">→ 預估：~90 行
</span></span><span class="line"><span class="ln">18</span><span class="cl">
</span></span><span class="line"><span class="ln">19</span><span class="cl">步驟 1-3：估算檔案數量
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">-</span> 列出需要建立/修改的檔案
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">-</span> lib/domain/entities/book.dart（新增）
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">-</span> test/unit/domain/entities/book_test.dart（新增）
</span></span><span class="line"><span class="ln">23</span><span class="cl">→ 預估：2 個檔案（1 個生產 + 1 個測試）
</span></span><span class="line"><span class="ln">24</span><span class="cl">
</span></span><span class="line"><span class="ln">25</span><span class="cl">步驟 1-4：估算測試數量
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">-</span> 根據驗收條件估算測試案例
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">-</span> 測試 Entity 建立
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">-</span> 測試 equals（相等/不等）
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="k">-</span> 測試 hashCode
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="k">-</span> 測試 toString
</span></span><span class="line"><span class="ln">31</span><span class="cl">→ 預估：5 個測試</span></span></code></pre></div><h4 id="步驟-2複雜度確認">步驟 2：複雜度確認</h4>
<p><strong>目標</strong>: 確定最終複雜度等級</p>
<p><strong>確認方法</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">對應 4 個指標到複雜度等級：
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">職責數量：4 個 → Level 3（複雜）
</span></span><span class="line"><span class="ln">4</span><span class="cl">程式碼行數：90 行 → Level 3（複雜）
</span></span><span class="line"><span class="ln">5</span><span class="cl">檔案數量：2 個（1 生產 + 1 測試）→ Level 2（中等）
</span></span><span class="line"><span class="ln">6</span><span class="cl">測試數量：5 個 → Level 2（中等）
</span></span><span class="line"><span class="ln">7</span><span class="cl">
</span></span><span class="line"><span class="ln">8</span><span class="cl">取最高等級：Level 3（複雜）</span></span></code></pre></div><p><strong>確認檢查清單</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已計算所有 4 個指標
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已對應每個指標到複雜度等級
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已確定最高複雜度等級
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 已記錄評估依據</span></span></code></pre></div><h4 id="步驟-3拆分決策">步驟 3：拆分決策</h4>
<p><strong>目標</strong>: 決定是否拆分以及如何拆分</p>
<p><strong>決策規則</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Level 1-2 → 可直接建立 Ticket
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    ├─ 無需拆分
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">    └─ 直接進入 Phase 2（測試設計）
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">Level 3 → 評估是否可拆分
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    ├─ 可拆分為 Level 1-2 → 執行拆分
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    └─ 無法拆分 → 勉強接受，加強 Review
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">Level 4 → 必須拆分
</span></span><span class="line"><span class="ln">10</span><span class="cl">    ├─ 阻止建立 Ticket
</span></span><span class="line"><span class="ln">11</span><span class="cl">    ├─ 執行拆分（使用第三章拆分策略）
</span></span><span class="line"><span class="ln">12</span><span class="cl">    └─ 重新評估每個拆分後的子 Ticket</span></span></code></pre></div><p><strong>Level 3 拆分評估</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">範例：實作 Book Entity（Level 3）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">拆分評估：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="k">1.</span> 是否可拆分為更小 Ticket？
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">   → 是，可拆分為兩個 Ticket
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">2.</span> 如何拆分？
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   Ticket A: 定義 Book Entity 欄位和基礎方法
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   <span class="k">-</span> 職責：定義欄位 + equals/hashCode
</span></span><span class="line"><span class="ln">10</span><span class="cl">   <span class="k">-</span> 行數：~45 行
</span></span><span class="line"><span class="ln">11</span><span class="cl">   <span class="k">-</span> 檔案：1 個
</span></span><span class="line"><span class="ln">12</span><span class="cl">   <span class="k">-</span> 測試：3 個
</span></span><span class="line"><span class="ln">13</span><span class="cl">   → Level 2（中等）
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">   Ticket B: 補充 Book Entity 完整功能
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> 職責：toString + 完整測試
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> 行數：~45 行
</span></span><span class="line"><span class="ln">18</span><span class="cl">   <span class="k">-</span> 檔案：1 個（修改）
</span></span><span class="line"><span class="ln">19</span><span class="cl">   <span class="k">-</span> 測試：2 個
</span></span><span class="line"><span class="ln">20</span><span class="cl">   → Level 1（簡單）
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">3.</span> 拆分後依賴關係？
</span></span><span class="line"><span class="ln">23</span><span class="cl">   → Ticket B 依賴 Ticket A（B 在 A 完成後執行）
</span></span><span class="line"><span class="ln">24</span><span class="cl">
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">4.</span> 拆分價值評估？
</span></span><span class="line"><span class="ln">26</span><span class="cl">   → 降低風險：兩個 Level 1-2 比一個 Level 3 更易管理
</span></span><span class="line"><span class="ln">27</span><span class="cl">   → 易於 Review：分兩次 Review，每次範圍更小
</span></span><span class="line"><span class="ln">28</span><span class="cl">   → 成本：增加一個 Ticket，但風險降低值得
</span></span><span class="line"><span class="ln">29</span><span class="cl">
</span></span><span class="line"><span class="ln">30</span><span class="cl">結論：建議拆分</span></span></code></pre></div><p><strong>Level 4 拆分處理</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">範例：實作完整書籍評分功能（Level 4）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">當前狀態：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> 職責：8 個 → Level 4
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 行數：180 行 → Level 4
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 檔案：7 個 → Level 4
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">-</span> 測試：15 個 → Level 4
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">拆分決策：必須拆分（無選項）
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">拆分方式：使用「基於 Clean Architecture 分層拆分策略」（詳見第三章）</span></span></code></pre></div><hr>
<h3 id="23-評估決策樹">2.3 評估決策樹</h3>
<p><strong>完整決策流程圖</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">[開始評估]
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">[計算 4 個指標]
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">[取最高複雜度等級]
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    ├─ Level 1（簡單）
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    │   [可直接建立 Ticket]
</span></span><span class="line"><span class="ln">10</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln">11</span><span class="cl">    │   [進入 Phase 2：測試設計]
</span></span><span class="line"><span class="ln">12</span><span class="cl">    │
</span></span><span class="line"><span class="ln">13</span><span class="cl">    ├─ Level 2（中等）
</span></span><span class="line"><span class="ln">14</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln">15</span><span class="cl">    │   [可直接建立 Ticket]
</span></span><span class="line"><span class="ln">16</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln">17</span><span class="cl">    │   [（可選）評估是否拆分為更小 Ticket]
</span></span><span class="line"><span class="ln">18</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln">19</span><span class="cl">    │   [進入 Phase 2：測試設計]
</span></span><span class="line"><span class="ln">20</span><span class="cl">    │
</span></span><span class="line"><span class="ln">21</span><span class="cl">    ├─ Level 3（複雜）
</span></span><span class="line"><span class="ln">22</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln">23</span><span class="cl">    │   [評估是否可拆分]
</span></span><span class="line"><span class="ln">24</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln">25</span><span class="cl">    │   ├─ 可拆分？
</span></span><span class="line"><span class="ln">26</span><span class="cl">    │   │   ├─ Yes → [執行拆分]
</span></span><span class="line"><span class="ln">27</span><span class="cl">    │   │   │           ↓
</span></span><span class="line"><span class="ln">28</span><span class="cl">    │   │   │       [重新評估子 Ticket]
</span></span><span class="line"><span class="ln">29</span><span class="cl">    │   │   │           ↓
</span></span><span class="line"><span class="ln">30</span><span class="cl">    │   │   │       [確保所有子 Ticket 為 Level 1-2]
</span></span><span class="line"><span class="ln">31</span><span class="cl">    │   │   │
</span></span><span class="line"><span class="ln">32</span><span class="cl">    │   │   └─ No → [勉強接受]
</span></span><span class="line"><span class="ln">33</span><span class="cl">    │   │              ↓
</span></span><span class="line"><span class="ln">34</span><span class="cl">    │   │          [標記為高風險 Ticket]
</span></span><span class="line"><span class="ln">35</span><span class="cl">    │   │              ↓
</span></span><span class="line"><span class="ln">36</span><span class="cl">    │   │          [加強 Review 機制]
</span></span><span class="line"><span class="ln">37</span><span class="cl">    │   │              ↓
</span></span><span class="line"><span class="ln">38</span><span class="cl">    │   │          [進入 Phase 2]
</span></span><span class="line"><span class="ln">39</span><span class="cl">    │
</span></span><span class="line"><span class="ln">40</span><span class="cl">    └─ Level 4（超標）
</span></span><span class="line"><span class="ln">41</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">42</span><span class="cl">        [禁止建立 Ticket]
</span></span><span class="line"><span class="ln">43</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">44</span><span class="cl">        [阻止進入 Phase 2]
</span></span><span class="line"><span class="ln">45</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">46</span><span class="cl">        [必須拆分（使用第三章策略）]
</span></span><span class="line"><span class="ln">47</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">48</span><span class="cl">        [重新評估所有子 Ticket]
</span></span><span class="line"><span class="ln">49</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">50</span><span class="cl">        [確保所有子 Ticket ≤ Level 3]</span></span></code></pre></div><p><strong>決策節點詳細說明</strong>:</p>
<h4 id="節點-1level-3-拆分評估">節點 1：Level 3 拆分評估</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">問題：此 Ticket 是否可拆分為更小 Ticket？
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">評估準則：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">1. 職責是否可分離？
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">   - 是否包含多個獨立功能點？
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">   - 是否可按照 Clean Architecture 分層拆分？
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">2. 拆分後是否降低複雜度？
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   - 拆分後每個子 Ticket 是否 ≤ Level 2？
</span></span><span class="line"><span class="ln">10</span><span class="cl">   - 是否減少單一 Ticket 的風險？
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">3. 拆分成本是否合理？
</span></span><span class="line"><span class="ln">13</span><span class="cl">   - 增加的管理成本 vs 降低的風險
</span></span><span class="line"><span class="ln">14</span><span class="cl">   - 是否需要額外的整合測試？
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">決策：
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">- 滿足 1 且 2 → 建議拆分
</span></span><span class="line"><span class="ln">19</span><span class="cl">- 不滿足 1 或 2，但 3 成本高 → 勉強接受 Level 3</span></span></code></pre></div><h5 id="節點-2level-4-強制拆分">節點 2：Level 4 強制拆分</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Level 4 無需評估，必須拆分
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">拆分方法（按優先順序）：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">1. 優先：按 Clean Architecture 分層拆分（詳見第三章 3.1-3.4）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">2. 次之：按職責拆分（每個職責獨立 Ticket）
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">3. 最後：按檔案拆分（每個檔案獨立 Ticket）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">拆分要求：
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">- 所有子 Ticket 必須 ≤ Level 3
</span></span><span class="line"><span class="ln">11</span><span class="cl">- 建議所有子 Ticket ≤ Level 2
</span></span><span class="line"><span class="ln">12</span><span class="cl">- 理想所有子 Ticket = Level 1
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl">拆分後驗證：
</span></span><span class="line"><span class="ln">15</span><span class="cl">□ 所有子 Ticket 都已重新評估
</span></span><span class="line"><span class="ln">16</span><span class="cl">□ 所有子 Ticket 都 ≤ Level 3
</span></span><span class="line"><span class="ln">17</span><span class="cl">□ 子 Ticket 依賴關係明確
</span></span><span class="line"><span class="ln">18</span><span class="cl">□ 子 Ticket 總和涵蓋原始 Ticket 所有功能</span></span></code></pre></div><hr>
<h3 id="24-複雜度評估實例">2.4 複雜度評估實例</h3>
<p><strong>完整評估案例</strong>：</p>
<h4 id="案例-1簡單-ticket-評估">案例 1：簡單 Ticket 評估</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：定義 IBookRepository 介面
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">步驟 1：初步評估
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="k">-</span> 職責數量：1 個（定義介面方法簽名）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> 程式碼行數：~20 行
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 涉及檔案：1 個（i_book_repository.dart）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 測試數量：0 個（Interface 不需測試）
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">步驟 2：複雜度確認
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">-</span> 職責：1 個 → Level 1
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">-</span> 行數：20 行 → Level 1
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">-</span> 檔案：1 個 → Level 1
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> 測試：0 個 → Level 1
</span></span><span class="line"><span class="ln">14</span><span class="cl">→ 最高等級：Level 1
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">步驟 3：拆分決策
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">-</span> Level 1 → 可直接建立 Ticket
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">-</span> 無需拆分
</span></span><span class="line"><span class="ln">19</span><span class="cl">- 進入 Phase 2</span></span></code></pre></div><h4 id="案例-2中等-ticket-評估">案例 2：中等 Ticket 評估</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：實作 Rating Value Object
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">步驟 1：初步評估
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="k">-</span> 職責數量：2 個（建立 + 驗證）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> 程式碼行數：~50 行（含測試）
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 涉及檔案：1 個（rating.dart）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 測試數量：5 個
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">步驟 2：複雜度確認
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">-</span> 職責：2 個 → Level 2
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">-</span> 行數：50 行 → Level 2
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">-</span> 檔案：1 個 → Level 1
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> 測試：5 個 → Level 2
</span></span><span class="line"><span class="ln">14</span><span class="cl">→ 最高等級：Level 2
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">步驟 3：拆分決策
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">-</span> Level 2 → 可直接建立 Ticket
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">-</span> 評估：可選拆分，但不必要（職責內聚性高）
</span></span><span class="line"><span class="ln">19</span><span class="cl">- 進入 Phase 2</span></span></code></pre></div><h4 id="案例-3複雜-ticket-評估與拆分">案例 3：複雜 Ticket 評估與拆分</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：實作 BookRepository CRUD
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">步驟 1：初步評估
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="k">-</span> 職責數量：5 個（get + save + delete + mapper + 錯誤處理）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> 程式碼行數：~160 行（含測試）
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 涉及檔案：2 個（repository.dart + mapper.dart）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 測試數量：10 個
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">步驟 2：複雜度確認
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">-</span> 職責：5 個 → Level 3
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">-</span> 行數：160 行 → Level 4（超過 100 行）
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">-</span> 檔案：2 個 → Level 2
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> 測試：10 個 → Level 3
</span></span><span class="line"><span class="ln">14</span><span class="cl">→ 最高等級：Level 4（行數超標）
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">步驟 3：拆分決策
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">-</span> Level 4 → 必須拆分
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">-</span> 拆分方式：按 CRUD 方法拆分
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl">  Ticket A: 實作 getBookByIsbn
</span></span><span class="line"><span class="ln">21</span><span class="cl">  <span class="k">-</span> 職責：2 個（查詢 + 轉換）
</span></span><span class="line"><span class="ln">22</span><span class="cl">  <span class="k">-</span> 行數：~50 行
</span></span><span class="line"><span class="ln">23</span><span class="cl">  <span class="k">-</span> 檔案：2 個
</span></span><span class="line"><span class="ln">24</span><span class="cl">  <span class="k">-</span> 測試：3 個
</span></span><span class="line"><span class="ln">25</span><span class="cl">  → Level 2
</span></span><span class="line"><span class="ln">26</span><span class="cl">
</span></span><span class="line"><span class="ln">27</span><span class="cl">  Ticket B: 實作 saveBook
</span></span><span class="line"><span class="ln">28</span><span class="cl">  <span class="k">-</span> 職責：2 個（儲存 + 錯誤處理）
</span></span><span class="line"><span class="ln">29</span><span class="cl">  <span class="k">-</span> 行數：~60 行
</span></span><span class="line"><span class="ln">30</span><span class="cl">  <span class="k">-</span> 檔案：1 個（修改 repository.dart）
</span></span><span class="line"><span class="ln">31</span><span class="cl">  <span class="k">-</span> 測試：4 個
</span></span><span class="line"><span class="ln">32</span><span class="cl">  → Level 2
</span></span><span class="line"><span class="ln">33</span><span class="cl">
</span></span><span class="line"><span class="ln">34</span><span class="cl">  Ticket C: 實作 deleteBook
</span></span><span class="line"><span class="ln">35</span><span class="cl">  <span class="k">-</span> 職責：2 個（刪除 + 錯誤處理）
</span></span><span class="line"><span class="ln">36</span><span class="cl">  <span class="k">-</span> 行數：~50 行
</span></span><span class="line"><span class="ln">37</span><span class="cl">  <span class="k">-</span> 檔案：1 個（修改 repository.dart）
</span></span><span class="line"><span class="ln">38</span><span class="cl">  <span class="k">-</span> 測試：3 個
</span></span><span class="line"><span class="ln">39</span><span class="cl">  → Level 2
</span></span><span class="line"><span class="ln">40</span><span class="cl">
</span></span><span class="line"><span class="ln">41</span><span class="cl">結果：拆分為 3 個 Level 2 Ticket</span></span></code></pre></div><h4 id="案例-4god-ticket-評估與拆分">案例 4：God Ticket 評估與拆分</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">任務：實作完整書籍評分功能（UI + UseCase + Repository）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">步驟 1：初步評估
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="k">-</span> 職責數量：8 個（UI + Controller + UseCase + Entity + Repository + Mapper + 測試 + 整合）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> 程式碼行數：~300 行
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 涉及檔案：8 個（跨 4 個架構層級）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 測試數量：20 個
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">步驟 2：複雜度確認
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">-</span> 職責：8 個 → Level 4
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">-</span> 行數：300 行 → Level 4
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">-</span> 檔案：8 個 → Level 4
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> 測試：20 個 → Level 4
</span></span><span class="line"><span class="ln">14</span><span class="cl">→ 最高等級：Level 4（所有指標都超標）
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">步驟 3：拆分決策
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">-</span> Level 4 → 必須拆分（God Ticket）
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">-</span> 拆分方式：使用 Clean Architecture 分層拆分策略
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl">  Ticket 1: Domain 層實作（Layer 5）
</span></span><span class="line"><span class="ln">21</span><span class="cl">  <span class="k">-</span> Rating Entity + Rating Value Object
</span></span><span class="line"><span class="ln">22</span><span class="cl">  <span class="k">-</span> 職責：2 個
</span></span><span class="line"><span class="ln">23</span><span class="cl">  <span class="k">-</span> 行數：~60 行
</span></span><span class="line"><span class="ln">24</span><span class="cl">  <span class="k">-</span> 檔案：2 個
</span></span><span class="line"><span class="ln">25</span><span class="cl">  <span class="k">-</span> 測試：6 個
</span></span><span class="line"><span class="ln">26</span><span class="cl">  → Level 2
</span></span><span class="line"><span class="ln">27</span><span class="cl">
</span></span><span class="line"><span class="ln">28</span><span class="cl">  Ticket 2: Repository 層實作（Layer 4-5 Interface + Infra）
</span></span><span class="line"><span class="ln">29</span><span class="cl">  <span class="k">-</span> IRatingRepository + SQLiteRatingRepository + Mapper
</span></span><span class="line"><span class="ln">30</span><span class="cl">  <span class="k">-</span> 職責：3 個
</span></span><span class="line"><span class="ln">31</span><span class="cl">  <span class="k">-</span> 行數：~90 行
</span></span><span class="line"><span class="ln">32</span><span class="cl">  <span class="k">-</span> 檔案：3 個
</span></span><span class="line"><span class="ln">33</span><span class="cl">  <span class="k">-</span> 測試：8 個
</span></span><span class="line"><span class="ln">34</span><span class="cl">  → Level 3（可接受）
</span></span><span class="line"><span class="ln">35</span><span class="cl">
</span></span><span class="line"><span class="ln">36</span><span class="cl">  Ticket 3: UseCase 層實作（Layer 3）
</span></span><span class="line"><span class="ln">37</span><span class="cl">  <span class="k">-</span> RateBookUseCase
</span></span><span class="line"><span class="ln">38</span><span class="cl">  <span class="k">-</span> 職責：2 個
</span></span><span class="line"><span class="ln">39</span><span class="cl">  <span class="k">-</span> 行數：~60 行
</span></span><span class="line"><span class="ln">40</span><span class="cl">  <span class="k">-</span> 檔案：1 個
</span></span><span class="line"><span class="ln">41</span><span class="cl">  <span class="k">-</span> 測試：4 個
</span></span><span class="line"><span class="ln">42</span><span class="cl">  → Level 2
</span></span><span class="line"><span class="ln">43</span><span class="cl">
</span></span><span class="line"><span class="ln">44</span><span class="cl">  Ticket 4: Presentation 層實作（Layer 1-2）
</span></span><span class="line"><span class="ln">45</span><span class="cl">  <span class="k">-</span> RatingWidget + RatingController
</span></span><span class="line"><span class="ln">46</span><span class="cl">  <span class="k">-</span> 職責：2 個
</span></span><span class="line"><span class="ln">47</span><span class="cl">  <span class="k">-</span> 行數：~90 行
</span></span><span class="line"><span class="ln">48</span><span class="cl">  <span class="k">-</span> 檔案：2 個
</span></span><span class="line"><span class="ln">49</span><span class="cl">  <span class="k">-</span> 測試：4 個（Widget 測試）
</span></span><span class="line"><span class="ln">50</span><span class="cl">  → Level 2
</span></span><span class="line"><span class="ln">51</span><span class="cl">
</span></span><span class="line"><span class="ln">52</span><span class="cl">結果：拆分為 4 個 Ticket（3 個 Level 2 + 1 個 Level 3）
</span></span><span class="line"><span class="ln">53</span><span class="cl">依賴順序：Ticket 1 → Ticket 2 → Ticket 3 → Ticket 4</span></span></code></pre></div><hr>
<h2 id="第三章clean-architecture-分層拆分策略">第三章：Clean Architecture 分層拆分策略</h2>
<h3 id="為什麼需要基於架構分層拆分">為什麼需要基於架構分層拆分</h3>
<p><strong>架構分層拆分的核心價值</strong>:</p>
<ol>
<li>
<p><strong>單層修改原則</strong>（Single Layer Modification Principle）</p>
<ul>
<li>每個 Ticket 專注於單一架構層級</li>
<li>降低跨層依賴帶來的複雜度</li>
<li>提升程式碼審查效率</li>
</ul>
</li>
<li>
<p>依賴方向一致性</p>
<ul>
<li>遵循 Clean Architecture 依賴規則（內層不依賴外層）</li>
<li>避免循環依賴</li>
<li>確保架構穩定性</li>
</ul>
</li>
<li>
<p>測試可獨立性</p>
<ul>
<li>每層有明確的測試策略</li>
<li>可獨立測試不依賴其他層</li>
<li>簡化 Mock 和 Stub</li>
</ul>
</li>
</ol>
<p><strong>本章內容結構</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">3.1 Clean Architecture 五層架構回顧
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    └── 快速回顧五層架構和依賴規則
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">3.2 四種標準拆分策略
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    ├── 策略 1: Interface 定義 Ticket
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">    ├── 策略 2: 具體實作 Ticket
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    ├── 策略 3: 測試驗證 Ticket
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    └── 策略 4: 整合連接 Ticket
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">3.3 分層拆分決策指引
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    └── 如何選擇合適的拆分策略
</span></span><span class="line"><span class="ln">10</span><span class="cl">3.4 分層拆分實務案例
</span></span><span class="line"><span class="ln">11</span><span class="cl">    └── 完整的書籍評分功能拆分範例</span></span></code></pre></div><hr>
<h3 id="31-clean-architecture-五層架構回顧">3.1 Clean Architecture 五層架構回顧</h3>
<p><strong>五層架構定義</strong>（引用自 Clean Architecture 實作方法論）:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Layer 1 (UI - 最外層)
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">├── 職責: 使用者介面元件
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">├── 路徑: lib/presentation/widgets/, lib/presentation/pages/
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">├── 依賴: Layer 2 (Behavior)
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">└── 不依賴: Layer 3-5
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">Layer 2 (Behavior)
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">├── 職責: UI 行為控制（State Management）
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">├── 路徑: lib/presentation/controllers/, lib/presentation/providers/
</span></span><span class="line"><span class="ln">10</span><span class="cl">├── 依賴: Layer 3 (UseCase)
</span></span><span class="line"><span class="ln">11</span><span class="cl">└── 不依賴: Layer 1, 4-5
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">Layer 3 (UseCase)
</span></span><span class="line"><span class="ln">14</span><span class="cl">├── 職責: 業務用例協調
</span></span><span class="line"><span class="ln">15</span><span class="cl">├── 路徑: lib/application/use_cases/, lib/application/services/
</span></span><span class="line"><span class="ln">16</span><span class="cl">├── 依賴: Layer 4-5 (Domain)
</span></span><span class="line"><span class="ln">17</span><span class="cl">└── 不依賴: Layer 1-2
</span></span><span class="line"><span class="ln">18</span><span class="cl">
</span></span><span class="line"><span class="ln">19</span><span class="cl">Layer 4 (Domain Events/Interfaces)
</span></span><span class="line"><span class="ln">20</span><span class="cl">├── 職責: 領域事件和介面定義
</span></span><span class="line"><span class="ln">21</span><span class="cl">├── 路徑: lib/domain/events/, lib/domain/repositories/ (介面)
</span></span><span class="line"><span class="ln">22</span><span class="cl">├── 依賴: Layer 5 (Domain Implementation)
</span></span><span class="line"><span class="ln">23</span><span class="cl">└── 不依賴: Layer 1-3
</span></span><span class="line"><span class="ln">24</span><span class="cl">
</span></span><span class="line"><span class="ln">25</span><span class="cl">Layer 5 (Domain Implementation - 最內層)
</span></span><span class="line"><span class="ln">26</span><span class="cl">├── 職責: 領域模型實作和基礎設施
</span></span><span class="line"><span class="ln">27</span><span class="cl">├── 路徑: lib/domain/entities/, lib/domain/value_objects/, lib/infrastructure/
</span></span><span class="line"><span class="ln">28</span><span class="cl">├── 依賴: 無（核心層）
</span></span><span class="line"><span class="ln">29</span><span class="cl">└── 不依賴: 任何層</span></span></code></pre></div><p><strong>依賴規則（Dependency Rule）</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln">1</span><span class="cl">外層 → 內層 允許
</span></span><span class="line"><span class="ln">2</span><span class="cl">內層 → 外層 禁止
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">範例：
</span></span><span class="line"><span class="ln">5</span><span class="cl">
</span></span><span class="line"><span class="ln">6</span><span class="cl">- Layer 2 (Behavior) → Layer 3 (UseCase)
</span></span><span class="line"><span class="ln">7</span><span class="cl">- Layer 3 (UseCase) → Layer 2 (Behavior)</span></span></code></pre></div><p><strong>單層修改原則</strong>:</p>
<ul>
<li><strong>理想</strong>: 每個 Ticket 只修改單一層級</li>
<li><strong>可接受</strong>: Ticket 修改相鄰兩層（如 Interface + Implementation）</li>
<li><strong>禁止</strong>: Ticket 跨越超過 2 層（如 UI → Domain 直接跨越）</li>
</ul>
<hr>
<h3 id="32-四種標準拆分策略">3.2 四種標準拆分策略</h3>
<h4 id="策略-1interface-定義-ticket">策略 1：Interface 定義 Ticket</h4>
<p><strong>定義</strong>: 定義一個介面及其輸入輸出契約。</p>
<p><strong>適用層級</strong>: 主要用於 Layer 4 (Domain Interfaces)</p>
<p><strong>職責範圍</strong>:</p>
<ul>
<li>定義 Interface 簽名</li>
<li>定義輸入參數類型</li>
<li>定義回傳類型</li>
<li>撰寫文檔註解（含業務需求編號）</li>
</ul>
<p><strong>禁止包含</strong>:</p>
<ul>
<li>具體實作邏輯</li>
<li>資料庫操作</li>
<li>業務邏輯</li>
</ul>
<p><strong>Ticket 範本</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #NNN: 定義 {Interface 名稱} 介面
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>[引用業務需求編號，如 REQ-001]
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>建立 <span class="sb">`{Interface 名稱}`</span> 介面，定義 {業務功能} 的契約
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 在 <span class="sb">`lib/domain/repositories/`</span> 建立 <span class="sb">`{interface_file}.dart`</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">2.</span> 定義 <span class="sb">`{method1}`</span> 方法簽名
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">3.</span> 定義 <span class="sb">`{method2}`</span> 方法簽名
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">4.</span> 撰寫文檔註解（含需求編號）
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> Interface 檔案建立在正確位置
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">- [ ]</span> 所有方法簽名完整且明確
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">- [ ]</span> 輸入輸出類型定義清楚
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">- [ ]</span> 包含完整的文檔註解（含需求編號）
</span></span><span class="line"><span class="ln">20</span><span class="cl">- [ ] dart analyze 0 錯誤</span></span></code></pre></div><p><strong>實務範例</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #101: 定義 IBookRepository 介面
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>REQ-LIB-001: 書籍資料存取功能
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>建立 <span class="sb">`IBookRepository`</span> 介面，定義書籍資料存取的契約
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 在 <span class="sb">`lib/domain/repositories/`</span> 建立 <span class="sb">`i_book_repository.dart`</span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">2.</span> 定義 <span class="sb">`getBookByIsbn`</span> 方法簽名
</span></span><span class="line"><span class="ln">12</span><span class="cl">   ```dart
</span></span><span class="line"><span class="ln">13</span><span class="cl">   /// [REQ-LIB-001.1] 根據 ISBN 查詢書籍
</span></span><span class="line"><span class="ln">14</span><span class="cl">   ///
</span></span><span class="line"><span class="ln">15</span><span class="cl">   /// 參數:
</span></span><span class="line"><span class="ln">16</span><span class="cl">   /// - isbn: 書籍 ISBN 編號
</span></span><span class="line"><span class="ln">17</span><span class="cl">   ///
</span></span><span class="line"><span class="ln">18</span><span class="cl">   /// 回傳:
</span></span><span class="line"><span class="ln">19</span><span class="cl">   /// - Book 物件（存在）或 null（不存在）
</span></span><span class="line"><span class="ln">20</span><span class="cl">   Future<span class="p">&lt;</span><span class="nt">Book</span><span class="err">?</span><span class="p">&gt;</span> getBookByIsbn(String isbn);</span></span></code></pre></div><ol start="3">
<li>定義 <code>saveBook</code> 方法簽名</li>
<li>定義 <code>deleteBook</code> 方法簽名</li>
<li>撰寫文檔註解</li>
</ol>
<h3 id="驗收條件">驗收條件</h3>
<ul>
<li><input disabled="" type="checkbox"> Interface 檔案建立在 <code>lib/domain/repositories/</code></li>
<li><input disabled="" type="checkbox"> 3 個方法簽名完整且明確</li>
<li><input disabled="" type="checkbox"> 輸入輸出類型定義清楚</li>
<li><input disabled="" type="checkbox"> 包含完整的文檔註解（含需求編號）</li>
<li><input disabled="" type="checkbox"> dart analyze 0 錯誤</li>
</ul>
<h3 id="指標評估">指標評估</h3>
<ul>
<li>職責: 1 個（定義介面）</li>
<li>行數: ~25 行</li>
<li>檔案: 1 個</li>
<li>測試: 0 個（Interface 不需單元測試）</li>
</ul>
<p>→ Level 1（簡單）</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">---
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">#### 策略 2：具體實作 Ticket
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">**定義**: 實作一個類別的核心邏輯。
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">**適用層級**:
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">- Layer 5 (Domain Implementation): Entity, Value Object
</span></span><span class="line"><span class="ln">10</span><span class="cl">- Layer 5 (Infrastructure): Repository 實作, Service 實作
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">**職責範圍**:
</span></span><span class="line"><span class="ln">13</span><span class="cl">- 實作類別邏輯
</span></span><span class="line"><span class="ln">14</span><span class="cl">- 實現介面方法
</span></span><span class="line"><span class="ln">15</span><span class="cl">- 處理異常
</span></span><span class="line"><span class="ln">16</span><span class="cl">- 撰寫單元測試
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">**禁止包含**:
</span></span><span class="line"><span class="ln">19</span><span class="cl">- UI 元件
</span></span><span class="line"><span class="ln">20</span><span class="cl">- 跨層整合（如直接呼叫 UseCase）
</span></span><span class="line"><span class="ln">21</span><span class="cl">- 測試以外的其他層修改
</span></span><span class="line"><span class="ln">22</span><span class="cl">
</span></span><span class="line"><span class="ln">23</span><span class="cl">**Ticket 範本**:
</span></span><span class="line"><span class="ln">24</span><span class="cl">
</span></span><span class="line"><span class="ln">25</span><span class="cl">```markdown
</span></span><span class="line"><span class="ln">26</span><span class="cl">## Ticket #NNN: 實作 {類別名稱}
</span></span><span class="line"><span class="ln">27</span><span class="cl">
</span></span><span class="line"><span class="ln">28</span><span class="cl">### 業務需求
</span></span><span class="line"><span class="ln">29</span><span class="cl">[引用業務需求編號]
</span></span><span class="line"><span class="ln">30</span><span class="cl">
</span></span><span class="line"><span class="ln">31</span><span class="cl">### 目標
</span></span><span class="line"><span class="ln">32</span><span class="cl">實作 `{類別名稱}`，提供 {業務功能} 的具體實現
</span></span><span class="line"><span class="ln">33</span><span class="cl">
</span></span><span class="line"><span class="ln">34</span><span class="cl">### 依賴 Ticket
</span></span><span class="line"><span class="ln">35</span><span class="cl">- Ticket #XXX: 定義 {Interface 名稱} 介面（必須先完成）
</span></span><span class="line"><span class="ln">36</span><span class="cl">
</span></span><span class="line"><span class="ln">37</span><span class="cl">### 步驟
</span></span><span class="line"><span class="ln">38</span><span class="cl">1. 建立 `{類別名稱}` 類別（實作 `{Interface}`）
</span></span><span class="line"><span class="ln">39</span><span class="cl">2. 實作 `{method1}` 方法
</span></span><span class="line"><span class="ln">40</span><span class="cl">3. 實作 `{method2}` 方法
</span></span><span class="line"><span class="ln">41</span><span class="cl">4. 處理異常情況
</span></span><span class="line"><span class="ln">42</span><span class="cl">5. 撰寫單元測試（正常流程 + 異常處理）
</span></span><span class="line"><span class="ln">43</span><span class="cl">6. 確保所有測試通過
</span></span><span class="line"><span class="ln">44</span><span class="cl">
</span></span><span class="line"><span class="ln">45</span><span class="cl">### 驗收條件
</span></span><span class="line"><span class="ln">46</span><span class="cl">- [ ] 實作所有 Interface 方法
</span></span><span class="line"><span class="ln">47</span><span class="cl">- [ ] 異常處理完整
</span></span><span class="line"><span class="ln">48</span><span class="cl">- [ ] 單元測試 100% 通過
</span></span><span class="line"><span class="ln">49</span><span class="cl">- [ ] 測試覆蓋正常流程和異常處理
</span></span><span class="line"><span class="ln">50</span><span class="cl">- [ ] dart analyze 0 錯誤</span></span></code></pre></div><p><strong>實務範例</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #102: 實作 SQLiteBookRepository
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>REQ-LIB-001: 書籍資料存取功能
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>實作 <span class="sb">`SQLiteBookRepository`</span>，提供書籍資料的 SQLite 儲存
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 依賴 Ticket
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span><span class="k">-</span> Ticket <span class="ni">#101:</span> 定義 IBookRepository 介面（必須先完成）
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 在 <span class="sb">`lib/infrastructure/repositories/`</span> 建立 <span class="sb">`sqlite_book_repository.dart`</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">2.</span> 實作 <span class="sb">`getBookByIsbn`</span> 方法
</span></span><span class="line"><span class="ln">15</span><span class="cl">   <span class="k">-</span> SQL 查詢邏輯
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> Data Mapper 轉換（DTO → Entity）
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> 錯誤處理（Database Exception）
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">3.</span> 實作 <span class="sb">`saveBook`</span> 方法
</span></span><span class="line"><span class="ln">19</span><span class="cl">   <span class="k">-</span> SQL 插入/更新邏輯
</span></span><span class="line"><span class="ln">20</span><span class="cl">   <span class="k">-</span> Data Mapper 轉換（Entity → DTO）
</span></span><span class="line"><span class="ln">21</span><span class="cl">   <span class="k">-</span> 錯誤處理
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">4.</span> 實作 <span class="sb">`deleteBook`</span> 方法
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="k">5.</span> 撰寫單元測試
</span></span><span class="line"><span class="ln">24</span><span class="cl">   <span class="k">-</span> 正常流程：CRUD 操作成功
</span></span><span class="line"><span class="ln">25</span><span class="cl">   <span class="k">-</span> 異常處理：資料庫錯誤、資料不存在
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">6.</span> 確保所有測試通過
</span></span><span class="line"><span class="ln">27</span><span class="cl">
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> 實作所有 IBookRepository 方法
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="k">- [ ]</span> 異常處理完整（DatabaseException, ValidationException）
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 6 個測試案例）
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">33</span><span class="cl">
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責: 3 個（CRUD 實作、Mapper、異常處理）
</span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="k">-</span> 行數: ~80 行（含測試）
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="k">-</span> 檔案: 1 個
</span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="k">-</span> 測試: 6 個
</span></span><span class="line"><span class="ln">39</span><span class="cl">→ Level 2（中等）</span></span></code></pre></div><hr>
<h4 id="策略-3測試驗證-ticket">策略 3：測試驗證 Ticket</h4>
<p><strong>定義</strong>: 撰寫一組相關的測試用例，補強現有實作的測試覆蓋率。</p>
<p><strong>適用時機</strong>:</p>
<ul>
<li>現有實作缺乏完整測試</li>
<li>需要補充邊界測試和異常測試</li>
<li>TDD 紅綠燈循環中的「紅燈」階段</li>
</ul>
<p><strong>職責範圍</strong>:</p>
<ul>
<li>撰寫單元測試</li>
<li>覆蓋正常流程</li>
<li>覆蓋邊界條件</li>
<li>覆蓋異常處理</li>
<li>確保測試通過</li>
</ul>
<p><strong>禁止包含</strong>:</p>
<ul>
<li>修改生產程式碼（除非是修正測試發現的 Bug）</li>
<li>新增功能</li>
<li>重構（測試 Ticket 專注於驗證，不做重構）</li>
</ul>
<p><strong>Ticket 範本</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #NNN: 撰寫 {功能} 測試
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>[引用業務需求編號]
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>撰寫 <span class="sb">`{類別名稱}`</span> 的完整測試用例，確保 {業務功能} 正確性
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 依賴 Ticket
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span><span class="k">-</span> Ticket <span class="ni">#XXX:</span> 實作 {類別名稱}（必須先完成）
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立測試檔案 <span class="sb">`{class}_test.dart`</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">2.</span> 撰寫正常流程測試
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">3.</span> 撰寫邊界條件測試
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">4.</span> 撰寫異常處理測試
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">5.</span> 確保所有測試通過
</span></span><span class="line"><span class="ln">18</span><span class="cl">
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> 測試檔案建立在正確位置
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">- [ ]</span> 至少 N 個測試用例
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">- [ ]</span> 覆蓋正常流程、邊界條件和異常處理
</span></span><span class="line"><span class="ln">23</span><span class="cl">- [ ] 所有測試 100% 通過</span></span></code></pre></div><p><strong>實務範例</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #103: 撰寫 BookRepository 整合測試
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>REQ-LIB-001: 書籍資料存取功能
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>撰寫 <span class="sb">`BookRepository`</span> 的整合測試，驗證資料庫操作正確性
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 依賴 Ticket
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span><span class="k">-</span> Ticket <span class="ni">#102:</span> 實作 SQLiteBookRepository（必須先完成）
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立測試檔案 <span class="sb">`test/integration/repositories/book_repository_test.dart`</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">2.</span> 撰寫 <span class="sb">`getBookByIsbn`</span> 測試
</span></span><span class="line"><span class="ln">15</span><span class="cl">   <span class="k">-</span> 測試 1: 成功取得存在的書籍
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> 測試 2: 書籍不存在回傳 null
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> 測試 3: 無效 ISBN 拋出異常
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">3.</span> 撰寫 <span class="sb">`saveBook`</span> 測試
</span></span><span class="line"><span class="ln">19</span><span class="cl">   <span class="k">-</span> 測試 4: 新增書籍成功
</span></span><span class="line"><span class="ln">20</span><span class="cl">   <span class="k">-</span> 測試 5: 更新現有書籍成功
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">4.</span> 撰寫 <span class="sb">`deleteBook`</span> 測試
</span></span><span class="line"><span class="ln">22</span><span class="cl">   <span class="k">-</span> 測試 6: 刪除存在的書籍
</span></span><span class="line"><span class="ln">23</span><span class="cl">   <span class="k">-</span> 測試 7: 刪除不存在的書籍無異常
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="k">5.</span> 確保所有測試通過
</span></span><span class="line"><span class="ln">25</span><span class="cl">
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> 測試檔案建立在 <span class="sb">`test/integration/repositories/`</span>
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">- [ ]</span> 至少 7 個整合測試案例
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="k">- [ ]</span> 覆蓋正常流程和異常處理
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="k">- [ ]</span> 所有測試 100% 通過
</span></span><span class="line"><span class="ln">31</span><span class="cl">
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責: 1 個（撰寫測試）
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="k">-</span> 行數: ~60 行（純測試）
</span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="k">-</span> 檔案: 1 個（測試檔案）
</span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="k">-</span> 測試: 7 個
</span></span><span class="line"><span class="ln">37</span><span class="cl">→ Level 2（中等）</span></span></code></pre></div><hr>
<h4 id="策略-4整合連接-ticket">策略 4：整合連接 Ticket</h4>
<p><strong>定義</strong>: 連接兩個模組並驗證整合，實現端到端流程。</p>
<p><strong>適用時機</strong>:</p>
<ul>
<li>需要連接 Layer 3 (UseCase) 和 Layer 5 (Repository)</li>
<li>需要連接 Layer 2 (Controller) 和 Layer 3 (UseCase)</li>
<li>完成分層實作後的整合階段</li>
</ul>
<p><strong>職責範圍</strong>:</p>
<ul>
<li>連接 Use Case 和 Repository</li>
<li>實作依賴注入</li>
<li>撰寫整合測試</li>
<li>驗證端到端流程</li>
</ul>
<p><strong>禁止包含</strong>:</p>
<ul>
<li>修改核心業務邏輯（應在具體實作 Ticket 完成）</li>
<li>跨越超過 2 層的整合</li>
<li>UI 實作（應獨立為 Presentation 層 Ticket）</li>
</ul>
<p><strong>Ticket 範本</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #NNN: 整合 {UseCase} 到 {Repository}
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>[引用業務需求編號]
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>將 <span class="sb">`{Repository}`</span> 整合到 <span class="sb">`{UseCase}`</span>，實現 {業務功能} 完整流程
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 依賴 Ticket
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span><span class="k">-</span> Ticket <span class="ni">#XXX:</span> 定義 {Interface}（必須先完成）
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">-</span> Ticket <span class="ni">#YYY:</span> 實作 {Repository}（必須先完成）
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 修改 <span class="sb">`{UseCase}`</span> 注入 <span class="sb">`{Interface}`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">2.</span> 在 <span class="sb">`execute`</span> 方法中呼叫 Repository 方法
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">3.</span> 處理 Repository 異常
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">4.</span> 撰寫整合測試驗證端到端流程
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">5.</span> 確保所有測試通過
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> <span class="sb">`{UseCase}`</span> 正確注入 <span class="sb">`{Interface}`</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">- [ ]</span> 端到端流程正常運作
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="k">- [ ]</span> 整合測試 100% 通過
</span></span><span class="line"><span class="ln">24</span><span class="cl">- [ ] 異常處理完整</span></span></code></pre></div><p><strong>實務範例</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #104: 整合 BookRepository 到 GetBookUseCase
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>REQ-LIB-001: 書籍查詢功能
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>將 <span class="sb">`BookRepository`</span> 整合到 <span class="sb">`GetBookUseCase`</span>，實現完整書籍查詢流程
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 依賴 Ticket
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span><span class="k">-</span> Ticket <span class="ni">#101:</span> 定義 IBookRepository 介面（必須先完成）
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">-</span> Ticket <span class="ni">#102:</span> 實作 SQLiteBookRepository（必須先完成）
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 修改 <span class="sb">`GetBookInteractor`</span> 注入 <span class="sb">`IBookRepository`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl">   ```dart
</span></span><span class="line"><span class="ln">16</span><span class="cl">   class GetBookInteractor implements GetBookUseCase {
</span></span><span class="line"><span class="ln">17</span><span class="cl">     final IBookRepository _repository;
</span></span><span class="line"><span class="ln">18</span><span class="cl">
</span></span><span class="line"><span class="ln">19</span><span class="cl">     GetBookInteractor(this._repository);
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl">     <span class="ni">@override</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl">     Future<span class="p">&lt;</span><span class="nt">Book</span><span class="err">?</span><span class="p">&gt;</span> execute(String isbn) async {
</span></span><span class="line"><span class="ln">23</span><span class="cl">       // 呼叫 Repository
</span></span><span class="line"><span class="ln">24</span><span class="cl">     }
</span></span><span class="line"><span class="ln">25</span><span class="cl">   }</span></span></code></pre></div><ol start="2">
<li>在 <code>execute</code> 方法中呼叫 <code>repository.getBookByIsbn</code></li>
<li>處理 Repository 異常（ValidationException, StorageException）</li>
<li>撰寫整合測試
<ul>
<li>測試 1: 成功查詢書籍</li>
<li>測試 2: 書籍不存在</li>
<li>測試 3: Repository 異常處理</li>
</ul>
</li>
<li>確保所有測試通過</li>
</ol>
<h3 id="驗收條件整合應用案例">驗收條件（整合應用案例）</h3>
<ul>
<li><input disabled="" type="checkbox"> <code>GetBookInteractor</code> 正確注入 <code>IBookRepository</code></li>
<li><input disabled="" type="checkbox"> 端到端流程正常運作</li>
<li><input disabled="" type="checkbox"> 整合測試 100% 通過（至少 3 個測試案例）</li>
<li><input disabled="" type="checkbox"> 異常處理完整</li>
</ul>
<h3 id="指標評估整合應用案例">指標評估（整合應用案例）</h3>
<ul>
<li>職責: 2 個（注入、整合）</li>
<li>行數: ~50 行（含測試）</li>
<li>檔案: 1 個（修改 UseCase）</li>
<li>測試: 3 個</li>
</ul>
<p>→ Level 2（中等）</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">---
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">### 3.3 分層拆分決策指引
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">**決策流程圖**:
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">```text
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">[分析 Ticket 涉及的架構層級]
</span></span><span class="line"><span class="ln">10</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln">11</span><span class="cl">    ├─ 單層修改？
</span></span><span class="line"><span class="ln">12</span><span class="cl">    │   ├─ Yes → 選擇對應策略
</span></span><span class="line"><span class="ln">13</span><span class="cl">    │   │   ├─ Layer 4 Interface → 策略 1: Interface 定義
</span></span><span class="line"><span class="ln">14</span><span class="cl">    │   │   ├─ Layer 5 Implementation → 策略 2: 具體實作
</span></span><span class="line"><span class="ln">15</span><span class="cl">    │   │   └─ 補充測試 → 策略 3: 測試驗證
</span></span><span class="line"><span class="ln">16</span><span class="cl">    │   │
</span></span><span class="line"><span class="ln">17</span><span class="cl">    │   └─ No → 跨層修改？
</span></span><span class="line"><span class="ln">18</span><span class="cl">    │       ├─ 相鄰兩層整合 → 策略 4: 整合連接
</span></span><span class="line"><span class="ln">19</span><span class="cl">    │       └─ 跨越超過 2 層 → 必須拆分為多個 Ticket</span></span></code></pre></div><p><strong>決策準則</strong>:</p>
<h4 id="準則-1-優先單層修改">準則 1: 優先單層修改</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">問題: Ticket 是否只修改單一架構層級？
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> Yes → 選擇策略 1-3（Interface / 實作 / 測試）
</span></span><span class="line"><span class="ln">4</span><span class="cl">- No → 評估是否可拆分為多個單層 Ticket</span></span></code></pre></div><h5 id="準則-2-相鄰層整合可接受">準則 2: 相鄰層整合可接受</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">問題: 是否為相鄰兩層的整合？
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">範例：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> Layer 3 (UseCase) + Layer 4-5 (Repository) 可接受
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> Layer 2 (Controller) + Layer 3 (UseCase) 可接受
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> Layer 1 (UI) + Layer 5 (Domain) 禁止（跨越太多層）
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">決策：
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">-</span> 相鄰兩層整合 → 策略 4: 整合連接
</span></span><span class="line"><span class="ln">12</span><span class="cl">- 跨越超過 2 層 → 必須拆分為多個 Ticket</span></span></code></pre></div><h6 id="準則-3-interface-先行">準則 3: Interface 先行</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">原則: Interface 定義必須先於實作
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">範例拆分順序：
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="k">1.</span> Ticket A: 定義 IBookRepository（策略 1）
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">2.</span> Ticket B: 實作 SQLiteBookRepository（策略 2）
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="k">3.</span> Ticket C: 整合到 GetBookUseCase（策略 4）
</span></span><span class="line"><span class="ln">7</span><span class="cl">
</span></span><span class="line"><span class="ln">8</span><span class="cl">依賴關係: Ticket C 依賴 B，B 依賴 A</span></span></code></pre></div><h6 id="準則-4-測試獨立或整合">準則 4: 測試獨立或整合</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">問題: 測試應該獨立 Ticket 還是整合到實作 Ticket？
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">決策：
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">-</span> 實作 Ticket <span class="p">&lt;</span> <span class="nt">Level</span> <span class="na">2</span> <span class="err">→</span> <span class="na">整合測試到實作</span> <span class="na">Ticket</span>
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="k">-</span> <span class="na">實作</span> <span class="na">Ticket </span><span class="o">=</span> <span class="s">Level</span> <span class="na">2-3</span> <span class="err">→</span> <span class="na">可選擇獨立測試</span> <span class="na">Ticket</span>
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="na">-</span> <span class="na">測試案例</span> <span class="p">&gt;</span> 10 個 → 必須獨立測試 Ticket（策略 3）</span></span></code></pre></div><hr>
<h3 id="34-分層拆分實務案例">3.4 分層拆分實務案例</h3>
<h4 id="完整案例書籍評分功能實作">完整案例：書籍評分功能實作</h4>
<h4 id="原始-god-ticket-分析">原始 God Ticket 分析</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">原始任務: 實作完整書籍評分功能（UI + UseCase + Repository）
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">指標評估:
</span></span><span class="line"><span class="ln">4</span><span class="cl"><span class="k">-</span> 職責: 8 個
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">-</span> 行數: ~300 行
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="k">-</span> 檔案: 8 個
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="k">-</span> 測試: 20 個
</span></span><span class="line"><span class="ln">8</span><span class="cl">→ Level 4（所有指標都超標）必須拆分</span></span></code></pre></div><h4 id="分層拆分方案">分層拆分方案</h4>
<p><strong>拆分為 6 個 Ticket（按 Clean Architecture 分層）</strong>:</p>
<hr>
<h5 id="ticket-1-定義-rating-domain-模型layer-5---domain-implementation">Ticket 1: 定義 Rating Domain 模型（Layer 5 - Domain Implementation）</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #201: 定義 Rating Value Object
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級: Layer 5 (Domain Implementation)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略: 策略 2（具體實作）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>REQ-RATING-001: 書籍評分功能
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span>建立 <span class="sb">`Rating`</span> Value Object，封裝評分規則（1-5 分）
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立 <span class="sb">`lib/domain/value_objects/rating.dart`</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">2.</span> 實作 Rating 類別
</span></span><span class="line"><span class="ln">15</span><span class="cl">   <span class="k">-</span> 建構子驗證（1-5 分）
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> equals / hashCode
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> toString
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">3.</span> 撰寫單元測試（正常、邊界、異常）
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">4.</span> 確保測試通過
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> Rating 類別實作完整
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="k">- [ ]</span> 驗證邏輯正確（1-5 分）
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 5 個測試）
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">26</span><span class="cl">
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責: 1 個
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="k">-</span> 行數: ~50 行
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="k">-</span> 檔案: 1 個
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="k">-</span> 測試: 5 個
</span></span><span class="line"><span class="ln">32</span><span class="cl">→ Level 2（中等）</span></span></code></pre></div><hr>
<h4 id="ticket-2-定義-rating-entitylayer-5---domain-implementation">Ticket 2: 定義 Rating Entity（Layer 5 - Domain Implementation）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #202: 定義 Rating Entity
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級: Layer 5 (Domain Implementation)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略: 策略 2（具體實作）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 依賴: Ticket #201（Rating Value Object）
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span>REQ-RATING-001: 書籍評分功能
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>建立 <span class="sb">`Rating`</span> Entity，包含評分和評論資訊
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立 <span class="sb">`lib/domain/entities/rating.dart`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">2.</span> 實作 Rating Entity
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> 欄位: ratingValue (Rating VO), comment (String), userId, bookIsbn
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> equals / hashCode
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">3.</span> 撰寫單元測試
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">4.</span> 確保測試通過
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> Rating Entity 實作完整
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="k">- [ ]</span> 使用 Rating Value Object
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 3 個測試）
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">26</span><span class="cl">
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責: 1 個
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="k">-</span> 行數: ~40 行
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="k">-</span> 檔案: 1 個
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="k">-</span> 測試: 3 個
</span></span><span class="line"><span class="ln">32</span><span class="cl">→ Level 1（簡單）</span></span></code></pre></div><hr>
<h4 id="ticket-3-定義-iratingrepository-介面layer-4---domain-interfaces">Ticket 3: 定義 IRatingRepository 介面（Layer 4 - Domain Interfaces）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #203: 定義 IRatingRepository 介面
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級: Layer 4 (Domain Interfaces)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略: 策略 1（Interface 定義）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>REQ-RATING-001: 書籍評分功能
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span>建立 <span class="sb">`IRatingRepository`</span> 介面，定義評分資料存取契約
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立 <span class="sb">`lib/domain/repositories/i_rating_repository.dart`</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">2.</span> 定義 <span class="sb">`saveRating`</span> 方法簽名
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">3.</span> 定義 <span class="sb">`getRatingsByBookIsbn`</span> 方法簽名
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">4.</span> 撰寫文檔註解
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> Interface 檔案建立在正確位置
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">- [ ]</span> 2 個方法簽名完整
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">- [ ]</span> 文檔註解包含需求編號
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責: 1 個
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">-</span> 行數: ~20 行
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">-</span> 檔案: 1 個
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">-</span> 測試: 0 個
</span></span><span class="line"><span class="ln">29</span><span class="cl">→ Level 1（簡單）</span></span></code></pre></div><hr>
<h4 id="ticket-4-實作-sqliteratingrepositorylayer-5---infrastructure">Ticket 4: 實作 SQLiteRatingRepository（Layer 5 - Infrastructure）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #204: 實作 SQLiteRatingRepository
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級: Layer 5 (Infrastructure)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略: 策略 2（具體實作）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 依賴: Ticket #202, #203
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span>REQ-RATING-001: 書籍評分功能
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>實作 <span class="sb">`SQLiteRatingRepository`</span>，提供評分資料的 SQLite 儲存
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立 <span class="sb">`lib/infrastructure/repositories/sqlite_rating_repository.dart`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">2.</span> 實作 <span class="sb">`saveRating`</span> 方法
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> SQL 插入邏輯
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> Data Mapper 轉換
</span></span><span class="line"><span class="ln">18</span><span class="cl">   <span class="k">-</span> 錯誤處理
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">3.</span> 實作 <span class="sb">`getRatingsByBookIsbn`</span> 方法
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">4.</span> 撰寫單元測試（CRUD + 異常）
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">5.</span> 確保測試通過
</span></span><span class="line"><span class="ln">22</span><span class="cl">
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> 實作所有 IRatingRepository 方法
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">- [ ]</span> 異常處理完整
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 6 個測試）
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">28</span><span class="cl">
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責: 3 個（CRUD、Mapper、異常）
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="k">-</span> 行數: ~90 行
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">-</span> 檔案: 1 個
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="k">-</span> 測試: 6 個
</span></span><span class="line"><span class="ln">34</span><span class="cl">→ Level 3（複雜）可接受</span></span></code></pre></div><hr>
<h4 id="ticket-5-實作-ratebookusecaselayer-3---usecase">Ticket 5: 實作 RateBookUseCase（Layer 3 - UseCase）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #205: 實作 RateBookUseCase
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級: Layer 3 (UseCase)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略: 策略 4（整合連接）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 依賴: Ticket #203, #204
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span>REQ-RATING-001: 書籍評分功能
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>實作 <span class="sb">`RateBookUseCase`</span>，協調書籍評分業務流程
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立 <span class="sb">`lib/application/use_cases/rate_book_use_case.dart`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">2.</span> 注入 <span class="sb">`IRatingRepository`</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">3.</span> 實作 <span class="sb">`execute`</span> 方法
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> 建立 Rating Entity
</span></span><span class="line"><span class="ln">18</span><span class="cl">   <span class="k">-</span> 呼叫 Repository 儲存
</span></span><span class="line"><span class="ln">19</span><span class="cl">   <span class="k">-</span> 處理異常
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">4.</span> 撰寫整合測試
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">5.</span> 確保測試通過
</span></span><span class="line"><span class="ln">22</span><span class="cl">
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> UseCase 正確注入 IRatingRepository
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">- [ ]</span> 業務流程完整
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">- [ ]</span> 整合測試 100% 通過（至少 4 個測試）
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">- [ ]</span> 異常處理完整
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">29</span><span class="cl">
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責: 2 個（協調、整合）
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">-</span> 行數: ~60 行
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="k">-</span> 檔案: 1 個
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="k">-</span> 測試: 4 個
</span></span><span class="line"><span class="ln">35</span><span class="cl">→ Level 2（中等）</span></span></code></pre></div><hr>
<h4 id="ticket-6-實作-ratingwidget-uilayer-1-2---presentation">Ticket 6: 實作 RatingWidget UI（Layer 1-2 - Presentation）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #206: 實作 RatingWidget 和 RatingController
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級: Layer 1 (UI) + Layer 2 (Behavior)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略: 策略 2 + 策略 4（實作 + 整合）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 依賴: Ticket #205
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span>REQ-RATING-001: 書籍評分功能
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>實作評分 UI 元件和行為控制
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立 <span class="sb">`lib/presentation/widgets/rating_widget.dart`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">2.</span> 實作 RatingWidget（5 星評分 UI）
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">3.</span> 建立 <span class="sb">`lib/presentation/controllers/rating_controller.dart`</span>
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">4.</span> 實作 RatingController
</span></span><span class="line"><span class="ln">18</span><span class="cl">   <span class="k">-</span> 注入 RateBookUseCase
</span></span><span class="line"><span class="ln">19</span><span class="cl">   <span class="k">-</span> 呼叫 UseCase 評分
</span></span><span class="line"><span class="ln">20</span><span class="cl">   <span class="k">-</span> 狀態管理
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">5.</span> 撰寫 Widget 測試
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">6.</span> 確保測試通過
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> RatingWidget UI 正確顯示
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">- [ ]</span> RatingController 正確整合 UseCase
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">- [ ]</span> Widget 測試 100% 通過（至少 4 個測試）
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">29</span><span class="cl">
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責: 2 個（UI、Controller）
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">-</span> 行數: ~80 行
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="k">-</span> 檔案: 2 個
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="k">-</span> 測試: 4 個
</span></span><span class="line"><span class="ln">35</span><span class="cl">→ Level 2（中等）</span></span></code></pre></div><hr>
<h4 id="拆分結果總結">拆分結果總結</h4>
<p><strong>拆分前後對比</strong>:</p>
<table>
  <thead>
      <tr>
          <th>項目</th>
          <th>拆分前（God Ticket）</th>
          <th>拆分後（6 個 Ticket）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>職責數量</td>
          <td>8 個</td>
          <td>平均 1.7 個</td>
      </tr>
      <tr>
          <td>程式碼行數</td>
          <td>~300 行</td>
          <td>平均 57 行</td>
      </tr>
      <tr>
          <td>檔案數量</td>
          <td>8 個</td>
          <td>平均 1.2 個</td>
      </tr>
      <tr>
          <td>測試數量</td>
          <td>20 個</td>
          <td>平均 4 個</td>
      </tr>
      <tr>
          <td>複雜度等級</td>
          <td>Level 4</td>
          <td>5 個 Level 1-2<br>1 個 Level 3</td>
      </tr>
  </tbody>
</table>
<p><strong>拆分效益</strong>:</p>
<ul>
<li><strong>風險降低</strong>: 從 1 個高風險任務 → 6 個低風險任務</li>
<li><strong>並行開發</strong>: 可 2-3 人同時開發不同層級</li>
<li><strong>易於 Review</strong>: 每個 PR 範圍小，Review 時間縮短</li>
<li><strong>依賴明確</strong>: 清楚的 Ticket 依賴順序</li>
<li><strong>測試獨立</strong>: 每層可獨立測試，Mock 簡單</li>
</ul>
<p><strong>執行順序</strong>:</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Phase 1（可並行）:
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">├─ Ticket #201: Rating Value Object
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">└─ Ticket #202: Rating Entity （依賴 #201）
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">Phase 2（可並行）:
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">├─ Ticket #203: IRatingRepository Interface
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">└─ Ticket #204: SQLiteRatingRepository （依賴 #202, #203）
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">Phase 3:
</span></span><span class="line"><span class="ln">10</span><span class="cl">└─ Ticket #205: RateBookUseCase （依賴 #204）
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">Phase 4:
</span></span><span class="line"><span class="ln">13</span><span class="cl">└─ Ticket #206: RatingWidget UI （依賴 #205）</span></span></code></pre></div><hr>
<h2 id="第四章ticket-大小標準與範例">第四章：Ticket 大小標準與範例</h2>
<h3 id="41-簡單-ticket-標準與範例level-1">4.1 簡單 Ticket 標準與範例（Level 1）</h3>
<p><strong>Level 1 特徵</strong>：</p>
<ul>
<li>職責：1 個明確職責</li>
<li>行數：&lt; 30 行</li>
<li>檔案：1 個</li>
<li>測試：1-3 個</li>
</ul>
<p><strong>適用場景</strong>：</p>
<ul>
<li>Interface 定義</li>
<li>單一 Value Object</li>
<li>單一方法實作</li>
<li>簡單配置修改</li>
</ul>
<hr>
<h4 id="範例-1定義-ibookrepository-介面">範例 1：定義 IBookRepository 介面</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #1: 定義 IBookRepository 介面
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 4 (Domain Interfaces)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>REQ-LIB-001: 書籍資料存取功能
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu"></span>建立 <span class="sb">`IBookRepository`</span> 介面，定義書籍資料存取的契約
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 在 <span class="sb">`lib/domain/repositories/`</span> 建立 <span class="sb">`i_book_repository.dart`</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">2.</span> 定義 <span class="sb">`getBookByIsbn(String isbn)`</span> 方法簽名
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">3.</span> 定義 <span class="sb">`saveBook(Book book)`</span> 方法簽名
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">4.</span> 定義 <span class="sb">`deleteBook(String isbn)`</span> 方法簽名
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">5.</span> 撰寫文檔註解（含需求編號）
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> Interface 檔案建立在 <span class="sb">`lib/domain/repositories/`</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">- [ ]</span> 3 個方法簽名完整且明確
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">- [ ]</span> 輸入輸出類型定義清楚
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">- [ ]</span> 文檔註解包含需求編號 REQ-LIB-001
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">24</span><span class="cl">
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責數量：1 個（定義介面契約）
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">-</span> 程式碼行數：~20 行
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">-</span> 涉及檔案：1 個
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="k">-</span> 測試用例：0 個（Interface 不需單元測試）
</span></span><span class="line"><span class="ln">30</span><span class="cl">→ Level 1（簡單）
</span></span><span class="line"><span class="ln">31</span><span class="cl">
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="gu"></span>10-15 分鐘</span></span></code></pre></div><hr>
<h4 id="範例-2建立-rating-value-object">範例 2：建立 Rating Value Object</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #2: 建立 Rating Value Object
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 5 (Domain Implementation)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>REQ-RATING-001: 書籍評分功能
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu"></span>建立 <span class="sb">`Rating`</span> Value Object，封裝評分規則（1-5 分）
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 在 <span class="sb">`lib/domain/value_objects/`</span> 建立 <span class="sb">`rating.dart`</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">2.</span> 實作 Rating 類別
</span></span><span class="line"><span class="ln">14</span><span class="cl">   <span class="k">-</span> 建構子驗證（1-5 分範圍）
</span></span><span class="line"><span class="ln">15</span><span class="cl">   <span class="k">-</span> equals / hashCode
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> toString
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">3.</span> 撰寫單元測試
</span></span><span class="line"><span class="ln">18</span><span class="cl">   <span class="k">-</span> 測試 1：建立有效評分
</span></span><span class="line"><span class="ln">19</span><span class="cl">   <span class="k">-</span> 測試 2：評分過低拋出異常
</span></span><span class="line"><span class="ln">20</span><span class="cl">   <span class="k">-</span> 測試 3：評分過高拋出異常
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">4.</span> 確保所有測試通過
</span></span><span class="line"><span class="ln">22</span><span class="cl">
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> Rating 類別實作完整
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">- [ ]</span> 驗證邏輯正確（1-5 分）
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">- [ ]</span> equals / hashCode / toString 實作正確
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 3 個測試）
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">29</span><span class="cl">
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責數量：1 個（實作 Value Object）
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">-</span> 程式碼行數：~25 行（含測試）
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="k">-</span> 涉及檔案：1 個
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="k">-</span> 測試用例：3 個
</span></span><span class="line"><span class="ln">35</span><span class="cl">→ Level 1（簡單）
</span></span><span class="line"><span class="ln">36</span><span class="cl">
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="gu"></span>15-20 分鐘</span></span></code></pre></div><hr>
<h3 id="42-中等-ticket-標準與範例level-2">4.2 中等 Ticket 標準與範例（Level 2）</h3>
<p><strong>Level 2 特徵</strong>：</p>
<ul>
<li>職責：2-3 個相關職責</li>
<li>行數：30-70 行</li>
<li>檔案：2-3 個</li>
<li>測試：3-6 個</li>
</ul>
<p><strong>適用場景</strong>：</p>
<ul>
<li>含業務邏輯的 Entity</li>
<li>基礎 Repository 方法</li>
<li>簡單 UseCase</li>
<li>單一功能的 Controller</li>
</ul>
<hr>
<h4 id="範例-3實作-book-entity">範例 3：實作 Book Entity</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #3: 實作 Book Entity
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 5 (Domain Implementation)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>REQ-LIB-001: 書籍資料模型
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu"></span>建立 <span class="sb">`Book`</span> Entity，封裝書籍核心資料
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 在 <span class="sb">`lib/domain/entities/`</span> 建立 <span class="sb">`book.dart`</span>
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">2.</span> 定義 Entity 欄位
</span></span><span class="line"><span class="ln">14</span><span class="cl">   <span class="k">-</span> isbn (String, required)
</span></span><span class="line"><span class="ln">15</span><span class="cl">   <span class="k">-</span> title (String, required)
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> author (String, required)
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> publishDate (DateTime, optional)
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">3.</span> 實作 equals / hashCode（基於 isbn）
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">4.</span> 實作 toString
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">5.</span> 撰寫單元測試
</span></span><span class="line"><span class="ln">21</span><span class="cl">   <span class="k">-</span> 測試 1：建立有效 Book
</span></span><span class="line"><span class="ln">22</span><span class="cl">   <span class="k">-</span> 測試 2：equals 正確比較（相同 ISBN）
</span></span><span class="line"><span class="ln">23</span><span class="cl">   <span class="k">-</span> 測試 3：equals 正確比較（不同 ISBN）
</span></span><span class="line"><span class="ln">24</span><span class="cl">   <span class="k">-</span> 測試 4：hashCode 一致性
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">6.</span> 確保測試通過
</span></span><span class="line"><span class="ln">26</span><span class="cl">
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> Book Entity 欄位定義完整
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="k">- [ ]</span> equals / hashCode 實作正確（基於 isbn）
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="k">- [ ]</span> toString 回傳清楚的字串表示
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 4 個測試）
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">33</span><span class="cl">
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責數量：3 個（欄位定義、equals/hashCode、toString）
</span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="k">-</span> 程式碼行數：~50 行（含測試）
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="k">-</span> 涉及檔案：1 個
</span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="k">-</span> 測試用例：4 個
</span></span><span class="line"><span class="ln">39</span><span class="cl">→ Level 2（中等）
</span></span><span class="line"><span class="ln">40</span><span class="cl">
</span></span><span class="line"><span class="ln">41</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">42</span><span class="cl"><span class="gu"></span>25-35 分鐘</span></span></code></pre></div><hr>
<h4 id="範例-4實作-getbookusecase">範例 4：實作 GetBookUseCase</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #4: 實作 GetBookUseCase
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 3 (UseCase)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>REQ-LIB-001: 查詢書籍功能
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu"></span>實作 <span class="sb">`GetBookUseCase`</span>，協調書籍查詢業務流程
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu">### 依賴 Ticket
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu"></span><span class="k">-</span> Ticket <span class="ni">#1:</span> 定義 IBookRepository 介面（必須先完成）
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 在 <span class="sb">`lib/application/use_cases/`</span> 建立 <span class="sb">`get_book_use_case.dart`</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">2.</span> 定義 <span class="sb">`GetBookUseCase`</span> 介面
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">3.</span> 實作 <span class="sb">`GetBookInteractor`</span>
</span></span><span class="line"><span class="ln">18</span><span class="cl">   <span class="k">-</span> 注入 <span class="sb">`IBookRepository`</span>
</span></span><span class="line"><span class="ln">19</span><span class="cl">   <span class="k">-</span> 實作 <span class="sb">`execute(String isbn)`</span> 方法
</span></span><span class="line"><span class="ln">20</span><span class="cl">   <span class="k">-</span> 處理 Repository 異常
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">4.</span> 撰寫單元測試
</span></span><span class="line"><span class="ln">22</span><span class="cl">   <span class="k">-</span> 測試 1：成功查詢書籍
</span></span><span class="line"><span class="ln">23</span><span class="cl">   <span class="k">-</span> 測試 2：書籍不存在回傳 null
</span></span><span class="line"><span class="ln">24</span><span class="cl">   <span class="k">-</span> 測試 3：無效 ISBN 拋出 ValidationException
</span></span><span class="line"><span class="ln">25</span><span class="cl">   <span class="k">-</span> 測試 4：Repository 異常正確處理
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">5.</span> 確保測試通過
</span></span><span class="line"><span class="ln">27</span><span class="cl">
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> GetBookInteractor 正確注入 IBookRepository
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="k">- [ ]</span> execute 方法實作正確
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="k">- [ ]</span> 異常處理完整
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 4 個測試）
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">34</span><span class="cl">
</span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責數量：2 個（業務協調、異常處理）
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="k">-</span> 程式碼行數：~55 行（含測試）
</span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="k">-</span> 涉及檔案：1 個
</span></span><span class="line"><span class="ln">39</span><span class="cl"><span class="k">-</span> 測試用例：4 個
</span></span><span class="line"><span class="ln">40</span><span class="cl">→ Level 2（中等）
</span></span><span class="line"><span class="ln">41</span><span class="cl">
</span></span><span class="line"><span class="ln">42</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">43</span><span class="cl"><span class="gu"></span>30-40 分鐘</span></span></code></pre></div><hr>
<h3 id="43-複雜-ticket-標準與範例level-3">4.3 複雜 Ticket 標準與範例（Level 3）</h3>
<p><strong>Level 3 特徵</strong>：</p>
<ul>
<li>職責：3-5 個相關職責</li>
<li>行數：70-100 行</li>
<li>檔案：3-5 個</li>
<li>測試：6-10 個</li>
</ul>
<p><strong>適用場景</strong>：</p>
<ul>
<li>完整 Repository CRUD</li>
<li>複雜 UseCase（含多重驗證）</li>
<li>複雜業務邏輯實作</li>
</ul>
<p><strong>注意</strong>：Level 3 Ticket 建議優先評估是否可拆分為更小 Ticket</p>
<hr>
<h4 id="範例-5實作-bookrepository-crud建議拆分">範例 5：實作 BookRepository CRUD（建議拆分）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #5: 實作 SQLiteBookRepository CRUD
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 5 (Infrastructure)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>REQ-LIB-001: 書籍資料存取功能
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu"></span>實作 <span class="sb">`SQLiteBookRepository`</span>，提供完整的 CRUD 操作
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu">### 依賴 Ticket
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu"></span><span class="k">-</span> Ticket <span class="ni">#1:</span> 定義 IBookRepository 介面（必須先完成）
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu">### 複雜度警告
</span></span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="gu"></span>此 Ticket 為 Level 3（複雜），建議拆分為 3 個 Level 2 Ticket：
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">-</span> Ticket A: 實作 getBookByIsbn + 測試
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">-</span> Ticket B: 實作 saveBook + 測試
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">-</span> Ticket C: 實作 deleteBook + Data Mapper + 測試
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="gu">### 步驟（如不拆分）
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 在 <span class="sb">`lib/infrastructure/repositories/`</span> 建立 <span class="sb">`sqlite_book_repository.dart`</span>
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="k">2.</span> 在 <span class="sb">`lib/infrastructure/mappers/`</span> 建立 <span class="sb">`book_mapper.dart`</span>
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="k">3.</span> 實作 <span class="sb">`getBookByIsbn`</span> 方法
</span></span><span class="line"><span class="ln">25</span><span class="cl">   <span class="k">-</span> SQL 查詢邏輯
</span></span><span class="line"><span class="ln">26</span><span class="cl">   <span class="k">-</span> Data Mapper 轉換（DTO → Entity）
</span></span><span class="line"><span class="ln">27</span><span class="cl">   <span class="k">-</span> 錯誤處理
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">4.</span> 實作 <span class="sb">`saveBook`</span> 方法
</span></span><span class="line"><span class="ln">29</span><span class="cl">   <span class="k">-</span> SQL 插入/更新邏輯
</span></span><span class="line"><span class="ln">30</span><span class="cl">   <span class="k">-</span> Data Mapper 轉換（Entity → DTO）
</span></span><span class="line"><span class="ln">31</span><span class="cl">   <span class="k">-</span> 錯誤處理
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">5.</span> 實作 <span class="sb">`deleteBook`</span> 方法
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="k">6.</span> 撰寫完整測試
</span></span><span class="line"><span class="ln">34</span><span class="cl">   <span class="k">-</span> getBookByIsbn: 成功、不存在、異常（3 個測試）
</span></span><span class="line"><span class="ln">35</span><span class="cl">   <span class="k">-</span> saveBook: 新增、更新、異常（3 個測試）
</span></span><span class="line"><span class="ln">36</span><span class="cl">   <span class="k">-</span> deleteBook: 成功、不存在、異常（3 個測試）
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="k">7.</span> 確保所有測試通過
</span></span><span class="line"><span class="ln">38</span><span class="cl">
</span></span><span class="line"><span class="ln">39</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> 實作所有 IBookRepository 方法
</span></span><span class="line"><span class="ln">41</span><span class="cl"><span class="k">- [ ]</span> Data Mapper 轉換正確
</span></span><span class="line"><span class="ln">42</span><span class="cl"><span class="k">- [ ]</span> 異常處理完整
</span></span><span class="line"><span class="ln">43</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 9 個測試）
</span></span><span class="line"><span class="ln">44</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">45</span><span class="cl">
</span></span><span class="line"><span class="ln">46</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">47</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責數量：5 個（get、save、delete、mapper、異常處理）
</span></span><span class="line"><span class="ln">48</span><span class="cl"><span class="k">-</span> 程式碼行數：~160 行（含測試）
</span></span><span class="line"><span class="ln">49</span><span class="cl"><span class="k">-</span> 涉及檔案：2 個
</span></span><span class="line"><span class="ln">50</span><span class="cl"><span class="k">-</span> 測試用例：9 個
</span></span><span class="line"><span class="ln">51</span><span class="cl">→ Level 3（複雜）建議拆分
</span></span><span class="line"><span class="ln">52</span><span class="cl">
</span></span><span class="line"><span class="ln">53</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">54</span><span class="cl"><span class="gu"></span>60-90 分鐘
</span></span><span class="line"><span class="ln">55</span><span class="cl">
</span></span><span class="line"><span class="ln">56</span><span class="cl"><span class="gu">### 建議拆分方案
</span></span></span><span class="line"><span class="ln">57</span><span class="cl"><span class="gu"></span>拆分為 3 個 Ticket（詳見第五章決策樹）</span></span></code></pre></div><hr>
<h3 id="44-必須拆分標準level-4">4.4 必須拆分標準（Level 4）</h3>
<p><strong>Level 4 特徵</strong>：</p>
<ul>
<li>職責：&gt; 5 個</li>
<li>行數：&gt; 100 行</li>
<li>檔案：&gt; 5 個</li>
<li>測試：&gt; 10 個</li>
</ul>
<p><strong>處理方式</strong>：</p>
<ul>
<li><strong>禁止建立 Level 4 Ticket</strong></li>
<li><strong>必須拆分為多個 Level 1-2 Ticket</strong></li>
<li><strong>拆分後可接受少數 Level 3 Ticket</strong></li>
</ul>
<hr>
<h4 id="範例-6god-ticket-檢測與拆分">範例 6：God Ticket 檢測與拆分</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## 禁止：實作完整書籍評分功能
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 原始任務描述
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span>實作書籍評分功能，包含 UI、Controller、UseCase、Repository
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### God Ticket 檢測結果
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責數量：8 個 → Level 4
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">-</span> 程式碼行數：~300 行 → Level 4
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">-</span> 涉及檔案：8 個 → Level 4
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">-</span> 測試用例：20 個 → Level 4
</span></span><span class="line"><span class="ln">11</span><span class="cl">→ <span class="gs">**所有指標都超標，必須拆分**</span>
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 拆分決策
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span>使用「Clean Architecture 分層拆分策略」（詳見第三章 3.4）
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">拆分為 6 個 Ticket：
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">1.</span> Ticket <span class="ni">#201:</span> Rating Value Object（Level 2）
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">2.</span> Ticket <span class="ni">#202:</span> Rating Entity（Level 1）
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">3.</span> Ticket <span class="ni">#203:</span> IRatingRepository Interface（Level 1）
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">4.</span> Ticket <span class="ni">#204:</span> SQLiteRatingRepository（Level 3）
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">5.</span> Ticket <span class="ni">#205:</span> RateBookUseCase（Level 2）
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">6.</span> Ticket <span class="ni">#206:</span> RatingWidget UI（Level 2）
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl">結果：5 個 Level 1-2 + 1 個 Level 3 全部可接受</span></span></code></pre></div><hr>
<h3 id="45-ticket-大小對照表">4.5 Ticket 大小對照表</h3>
<p><strong>快速參考表</strong>：</p>
<table>
  <thead>
      <tr>
          <th>Level</th>
          <th>職責</th>
          <th>行數</th>
          <th>檔案</th>
          <th>測試</th>
          <th>預估時間</th>
          <th>範例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>1 簡單</strong></td>
          <td>1</td>
          <td>&lt;30</td>
          <td>1</td>
          <td>1-3</td>
          <td>5-20分鐘</td>
          <td>Interface 定義、簡單 VO</td>
      </tr>
      <tr>
          <td><strong>2 中等</strong></td>
          <td>2-3</td>
          <td>30-70</td>
          <td>2-3</td>
          <td>3-6</td>
          <td>20-40分鐘</td>
          <td>Entity、基礎 UseCase</td>
      </tr>
      <tr>
          <td><strong>3 複雜</strong></td>
          <td>3-5</td>
          <td>70-100</td>
          <td>3-5</td>
          <td>6-10</td>
          <td>40-90分鐘</td>
          <td>完整 Repository CRUD</td>
      </tr>
      <tr>
          <td><strong>4 超標</strong></td>
          <td>&gt;5</td>
          <td>&gt;100</td>
          <td>&gt;5</td>
          <td>&gt;10</td>
          <td>N/A</td>
          <td>禁止建立</td>
      </tr>
  </tbody>
</table>
<p><strong>決策建議</strong>：</p>
<ul>
<li>Level 1-2：直接建立 Ticket</li>
<li>Level 3：優先評估是否可拆分</li>
<li>Level 4：必須拆分，無例外</li>
</ul>
<hr>
<h2 id="第五章拆分決策樹">第五章：拆分決策樹</h2>
<h3 id="51-決策樹總覽">5.1 決策樹總覽</h3>
<p><strong>完整決策流程</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">[Ticket 設計階段]
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">[計算 4 個量化指標]
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">[取最高複雜度等級]
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">    ↓
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">    ├─ Level 1-2
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">    │   [直接建立 Ticket]
</span></span><span class="line"><span class="ln">10</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln">11</span><span class="cl">    │   [進入 Phase 2（測試設計）]
</span></span><span class="line"><span class="ln">12</span><span class="cl">    │
</span></span><span class="line"><span class="ln">13</span><span class="cl">    ├─ Level 3
</span></span><span class="line"><span class="ln">14</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln">15</span><span class="cl">    │   [拆分評估決策]
</span></span><span class="line"><span class="ln">16</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln">17</span><span class="cl">    │   ├─ 可拆分？
</span></span><span class="line"><span class="ln">18</span><span class="cl">    │   │   ├─ Yes → [執行拆分策略] → [重新評估]
</span></span><span class="line"><span class="ln">19</span><span class="cl">    │   │   └─ No → [勉強接受] → [標記高風險]
</span></span><span class="line"><span class="ln">20</span><span class="cl">    │   ↓
</span></span><span class="line"><span class="ln">21</span><span class="cl">    │   [進入 Phase 2]
</span></span><span class="line"><span class="ln">22</span><span class="cl">    │
</span></span><span class="line"><span class="ln">23</span><span class="cl">    └─ Level 4
</span></span><span class="line"><span class="ln">24</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">25</span><span class="cl">        [阻止建立 Ticket]
</span></span><span class="line"><span class="ln">26</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">27</span><span class="cl">        [執行強制拆分]
</span></span><span class="line"><span class="ln">28</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">29</span><span class="cl">        [選擇拆分策略]
</span></span><span class="line"><span class="ln">30</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">31</span><span class="cl">        ├─ 優先：按架構分層拆分
</span></span><span class="line"><span class="ln">32</span><span class="cl">        ├─ 次之：按職責拆分
</span></span><span class="line"><span class="ln">33</span><span class="cl">        └─ 最後：按檔案拆分
</span></span><span class="line"><span class="ln">34</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">35</span><span class="cl">        [重新評估所有子 Ticket]
</span></span><span class="line"><span class="ln">36</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">37</span><span class="cl">        [確保所有子 Ticket ≤ Level 3]
</span></span><span class="line"><span class="ln">38</span><span class="cl">        ↓
</span></span><span class="line"><span class="ln">39</span><span class="cl">        [可建立 Ticket]</span></span></code></pre></div><hr>
<h3 id="52-level-3-拆分評估決策">5.2 Level 3 拆分評估決策</h3>
<p><strong>決策問題</strong>：此 Level 3 Ticket 是否應該拆分？</p>
<p><strong>評估準則</strong>：</p>
<h4 id="準則-1職責可分離性">準則 1：職責可分離性</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">問題：職責是否可獨立分離為多個 Ticket？
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">評估方法：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">1. 列出所有職責
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">2. 檢查職責之間的依賴關係
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">3. 判斷是否可獨立完成
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">範例：
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">原始任務：實作 BookRepository CRUD
</span></span><span class="line"><span class="ln">10</span><span class="cl">職責分析：
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">- 職責 1：getBookByIsbn → 可獨立
</span></span><span class="line"><span class="ln">13</span><span class="cl">- 職責 2：saveBook → 可獨立（依賴職責 1 的測試模式）
</span></span><span class="line"><span class="ln">14</span><span class="cl">- 職責 3：deleteBook → 可獨立
</span></span><span class="line"><span class="ln">15</span><span class="cl">- 職責 4：Data Mapper → 可整合到職責 1-3
</span></span><span class="line"><span class="ln">16</span><span class="cl">- 職責 5：異常處理 → 可整合到職責 1-3
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">結論：可拆分為 3 個 Ticket（每個職責對應 1 個 Ticket）</span></span></code></pre></div><h4 id="準則-2拆分後複雜度降低">準則 2：拆分後複雜度降低</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">問題：拆分後每個子 Ticket 是否 ≤ Level 2？
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">評估方法：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">對每個拆分後的子 Ticket 重新計算 4 個指標
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">範例：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">原始 Ticket（Level 3）：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">- 職責：5 個
</span></span><span class="line"><span class="ln">10</span><span class="cl">- 行數：160 行
</span></span><span class="line"><span class="ln">11</span><span class="cl">- 檔案：2 個
</span></span><span class="line"><span class="ln">12</span><span class="cl">- 測試：9 個
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl">拆分後 Ticket A：getBookByIsbn
</span></span><span class="line"><span class="ln">15</span><span class="cl">- 職責：2 個（查詢 + 轉換）
</span></span><span class="line"><span class="ln">16</span><span class="cl">- 行數：50 行
</span></span><span class="line"><span class="ln">17</span><span class="cl">- 檔案：2 個
</span></span><span class="line"><span class="ln">18</span><span class="cl">- 測試：3 個
</span></span><span class="line"><span class="ln">19</span><span class="cl">→ Level 2
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl">拆分後 Ticket B：saveBook
</span></span><span class="line"><span class="ln">22</span><span class="cl">- 職責：2 個（儲存 + 異常處理）
</span></span><span class="line"><span class="ln">23</span><span class="cl">- 行數：60 行
</span></span><span class="line"><span class="ln">24</span><span class="cl">- 檔案：1 個（修改）
</span></span><span class="line"><span class="ln">25</span><span class="cl">- 測試：3 個
</span></span><span class="line"><span class="ln">26</span><span class="cl">→ Level 2
</span></span><span class="line"><span class="ln">27</span><span class="cl">
</span></span><span class="line"><span class="ln">28</span><span class="cl">拆分後 Ticket C：deleteBook
</span></span><span class="line"><span class="ln">29</span><span class="cl">- 職責：2 個（刪除 + 異常處理）
</span></span><span class="line"><span class="ln">30</span><span class="cl">- 行數：50 行
</span></span><span class="line"><span class="ln">31</span><span class="cl">- 檔案：1 個（修改）
</span></span><span class="line"><span class="ln">32</span><span class="cl">- 測試：3 個
</span></span><span class="line"><span class="ln">33</span><span class="cl">→ Level 2
</span></span><span class="line"><span class="ln">34</span><span class="cl">
</span></span><span class="line"><span class="ln">35</span><span class="cl">結論：拆分成功，所有子 Ticket 都降為 Level 2</span></span></code></pre></div><h4 id="準則-3拆分成本合理性">準則 3：拆分成本合理性</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">問題：拆分帶來的管理成本是否合理？
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">成本考量：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">- 收益：風險降低、易於 Review、可並行開發
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">- 成本：增加 Ticket 數量、需要管理依賴關係
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">決策：
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">- 拆分收益 &gt; 拆分成本 → 建議拆分
</span></span><span class="line"><span class="ln">11</span><span class="cl">- 拆分收益 ≈ 拆分成本 → 可選擇
</span></span><span class="line"><span class="ln">12</span><span class="cl">- 拆分收益 &lt; 拆分成本 → 不建議拆分
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl">範例：
</span></span><span class="line"><span class="ln">15</span><span class="cl">原始 Ticket：Level 3（複雜 Repository CRUD）
</span></span><span class="line"><span class="ln">16</span><span class="cl">拆分收益：
</span></span><span class="line"><span class="ln">17</span><span class="cl">+ 風險降低：1 個高風險 → 3 個低風險
</span></span><span class="line"><span class="ln">18</span><span class="cl">+ Review 效率：每次 Review 50-60 行 vs 160 行
</span></span><span class="line"><span class="ln">19</span><span class="cl">+ 可並行：3 個 Ticket 可依序快速開發
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl">拆分成本：
</span></span><span class="line"><span class="ln">22</span><span class="cl">
</span></span><span class="line"><span class="ln">23</span><span class="cl">- 管理成本：需要管理 3 個 Ticket 依賴
</span></span><span class="line"><span class="ln">24</span><span class="cl">- 整合測試：需要額外的整合測試（但本來就需要）
</span></span><span class="line"><span class="ln">25</span><span class="cl">
</span></span><span class="line"><span class="ln">26</span><span class="cl">結論：拆分收益 &gt; 拆分成本，建議拆分</span></span></code></pre></div><hr>
<h3 id="53-level-4-強制拆分策略">5.3 Level 4 強制拆分策略</h3>
<h4 id="level-4-無需評估必須拆分">Level 4 無需評估，必須拆分</h4>
<h4 id="拆分策略優先順序">拆分策略優先順序</h4>
<h5 id="策略-1按-clean-architecture-分層拆分優先">策略 1：按 Clean Architecture 分層拆分（優先）</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">適用情況：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">- Ticket 跨越多個架構層級（Layer 1-5）
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">- 檔案分布在不同層級目錄
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">- 涉及 UI、UseCase、Repository 等多層
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">拆分方法：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">1. 按照 Layer 1 → Layer 5 順序分組檔案
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">2. 每個 Layer 建立獨立 Ticket
</span></span><span class="line"><span class="ln">10</span><span class="cl">3. 相鄰兩層可合併為單一 Ticket（如 Interface + Implementation）
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">範例（書籍評分功能）：
</span></span><span class="line"><span class="ln">13</span><span class="cl">原始：8 個檔案，跨越 4 層
</span></span><span class="line"><span class="ln">14</span><span class="cl">拆分後：
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">- Ticket 1: Layer 5 Domain（Rating VO + Entity）
</span></span><span class="line"><span class="ln">17</span><span class="cl">- Ticket 2: Layer 5 + 4 Repository（Interface + Impl）
</span></span><span class="line"><span class="ln">18</span><span class="cl">- Ticket 3: Layer 3 UseCase
</span></span><span class="line"><span class="ln">19</span><span class="cl">- Ticket 4: Layer 1-2 Presentation（UI + Controller）
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl">結果：4 個 Level 1-2 Ticket</span></span></code></pre></div><h6 id="策略-2按職責拆分次之">策略 2：按職責拆分（次之）</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">適用情況：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">- 所有檔案在同一層級，但職責過多
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">- 單一 Repository 包含過多 CRUD 方法
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">- 單一 UseCase 包含過多業務邏輯
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">拆分方法：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">1. 列出所有職責
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">2. 每個獨立職責建立 Ticket
</span></span><span class="line"><span class="ln">10</span><span class="cl">3. 相關職責可合併（最多 2-3 個職責）
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">範例（BookRepository CRUD）：
</span></span><span class="line"><span class="ln">13</span><span class="cl">原始：5 個職責（get + save + delete + mapper + error）
</span></span><span class="line"><span class="ln">14</span><span class="cl">拆分後：
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">- Ticket A: getBookByIsbn + mapper + error（2-3 職責）
</span></span><span class="line"><span class="ln">17</span><span class="cl">- Ticket B: saveBook + error（2 職責）
</span></span><span class="line"><span class="ln">18</span><span class="cl">- Ticket C: deleteBook + error（2 職責）
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl">結果：3 個 Level 2 Ticket</span></span></code></pre></div><h6 id="策略-3按檔案拆分最後">策略 3：按檔案拆分（最後）</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">適用情況：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">- 前兩種策略都無法適用
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">- 檔案之間相對獨立
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">- 每個檔案本身就是一個完整單元
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">拆分方法：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">1. 每個檔案建立獨立 Ticket
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">2. 相關檔案可合併（最多 2-3 個檔案）
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">範例：
</span></span><span class="line"><span class="ln">12</span><span class="cl">原始：7 個檔案
</span></span><span class="line"><span class="ln">13</span><span class="cl">拆分後：
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">- Ticket 1: file1.dart + file2.dart（相關）
</span></span><span class="line"><span class="ln">16</span><span class="cl">- Ticket 2: file3.dart
</span></span><span class="line"><span class="ln">17</span><span class="cl">- Ticket 3: file4.dart + file5.dart（相關）
</span></span><span class="line"><span class="ln">18</span><span class="cl">- Ticket 4: file6.dart + file7.dart（相關）
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl">結果：4 個 Ticket</span></span></code></pre></div><hr>
<h3 id="54-拆分決策檢查清單">5.4 拆分決策檢查清單</h3>
<p><strong>Level 3 拆分評估檢查清單</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已列出所有職責
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已評估職責可分離性
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已計算拆分後每個子 Ticket 的指標
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 已確認所有子 Ticket ≤ Level 2
</span></span><span class="line"><span class="ln">5</span><span class="cl">□ 已評估拆分成本 vs 收益
</span></span><span class="line"><span class="ln">6</span><span class="cl">□ 已確定是否拆分的最終決策</span></span></code></pre></div><p><strong>Level 4 強制拆分檢查清單</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已識別 Ticket 為 Level 4（任一指標超標）
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已選擇拆分策略（分層 / 職責 / 檔案）
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已執行拆分（列出所有子 Ticket）
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 已重新評估所有子 Ticket
</span></span><span class="line"><span class="ln">5</span><span class="cl">□ 已確認所有子 Ticket ≤ Level 3
</span></span><span class="line"><span class="ln">6</span><span class="cl">□ 已標記子 Ticket 依賴關係
</span></span><span class="line"><span class="ln">7</span><span class="cl">□ 已確認子 Ticket 總和涵蓋原始功能</span></span></code></pre></div><hr>
<h2 id="第六章ticket-拆分檢查清單">第六章：Ticket 拆分檢查清單</h2>
<h3 id="61-拆分前檢查清單">6.1 拆分前檢查清單</h3>
<h4 id="階段-1需求理解">階段 1：需求理解</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已閱讀完整的業務需求
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已理解 Ticket 的業務目標
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已確認 Ticket 的驗收條件
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 已識別所有需要完成的功能點
</span></span><span class="line"><span class="ln">5</span><span class="cl">□ 已確認與其他 Ticket 的依賴關係</span></span></code></pre></div><h5 id="階段-2指標計算">階段 2：指標計算</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已列出所有職責（功能點 + 邊界條件 + 異常處理）
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已估算程式碼行數（參考類似任務）
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已列出所有涉及檔案（含新建和修改）
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 已估算測試用例數（正常 + 邊界 + 異常）
</span></span><span class="line"><span class="ln">5</span><span class="cl">□ 已取最高複雜度等級作為最終評估</span></span></code></pre></div><h6 id="階段-3複雜度確認">階段 3：複雜度確認</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已確定 Ticket 的複雜度等級（Level 1-4）
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 如為 Level 4，已阻止建立並準備拆分
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 如為 Level 3，已評估是否拆分
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 如為 Level 1-2，已確認可直接建立</span></span></code></pre></div><hr>
<h3 id="62-拆分過程檢查清單">6.2 拆分過程檢查清單</h3>
<h4 id="階段-4拆分策略選擇">階段 4：拆分策略選擇</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已分析 Ticket 涉及的架構層級
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已確定拆分策略（分層 / 職責 / 檔案）
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已列出所有拆分後的子 Ticket
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 已為每個子 Ticket 撰寫初步描述</span></span></code></pre></div><h5 id="階段-5子-ticket-設計">階段 5：子 Ticket 設計</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 每個子 Ticket 都有明確的目標
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 每個子 Ticket 都有清楚的步驟
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 每個子 Ticket 都有具體的驗收條件
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 每個子 Ticket 都標記了層級（[Layer X]）
</span></span><span class="line"><span class="ln">5</span><span class="cl">□ 每個子 Ticket 都標記了依賴關係</span></span></code></pre></div><h6 id="階段-6依賴關係確認">階段 6：依賴關係確認</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已識別所有子 Ticket 之間的依賴
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已確保依賴方向符合 Clean Architecture 規則
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已標記依賴順序（Phase 1 → Phase 2 → ...）
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 已確認可並行執行的 Ticket</span></span></code></pre></div><hr>
<h3 id="63-拆分後驗證清單">6.3 拆分後驗證清單</h3>
<h4 id="階段-7指標重新評估">階段 7：指標重新評估</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已重新計算每個子 Ticket 的 4 個指標
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已確認所有子 Ticket ≤ Level 3
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已確認大多數子 Ticket ≤ Level 2
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 如有 Level 3 子 Ticket，已評估合理性</span></span></code></pre></div><h5 id="階段-8完整性驗證">階段 8：完整性驗證</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 所有子 Ticket 功能總和 = 原始 Ticket 功能
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 沒有遺漏任何功能點
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 沒有重複的功能實作
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 所有檔案都被包含在某個子 Ticket 中
</span></span><span class="line"><span class="ln">5</span><span class="cl">□ 所有測試案例都被包含</span></span></code></pre></div><h6 id="階段-9品質檢查">階段 9：品質檢查</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 每個子 Ticket 都有業務需求引用
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 每個子 Ticket 都有指標評估
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 每個子 Ticket 都有預估時間
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 每個子 Ticket 的職責明確且不重疊
</span></span><span class="line"><span class="ln">5</span><span class="cl">□ 每個子 Ticket 的標題包含 [Layer X] 標籤</span></span></code></pre></div><hr>
<h3 id="64-特殊情況檢查清單">6.4 特殊情況檢查清單</h3>
<h4 id="情況-1無法拆分的-level-3-ticket">情況 1：無法拆分的 Level 3 Ticket</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已明確記錄為何無法拆分
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已標記為「高風險 Ticket」
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已安排額外的 Code Review
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 已增加測試覆蓋率要求（&gt; 90%）
</span></span><span class="line"><span class="ln">5</span><span class="cl">□ 已準備更長的開發時間</span></span></code></pre></div><h5 id="情況-2跨層整合-ticket">情況 2：跨層整合 Ticket</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已確認只涉及相鄰兩層（如 Layer 3 + Layer 4-5）
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ 已確認符合依賴規則（外層 → 內層）
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已明確標記為「整合 Ticket」
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 已包含整合測試驗收條件</span></span></code></pre></div><h6 id="情況-3測試獨立-ticket">情況 3：測試獨立 Ticket</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">□ 已確認生產程式碼已完成（依賴 Ticket）
</span></span><span class="line"><span class="ln">2</span><span class="cl">□ Ticket 只包含測試程式碼
</span></span><span class="line"><span class="ln">3</span><span class="cl">□ 已列出所有測試案例（正常 + 邊界 + 異常）
</span></span><span class="line"><span class="ln">4</span><span class="cl">□ 已確認測試數量在合理範圍（<span class="p">&lt;</span> <span class="nt">10</span> <span class="na">個</span><span class="err">）</span></span></span></code></pre></div><hr>
<h2 id="第七章實務案例與最佳實踐">第七章：實務案例與最佳實踐</h2>
<h3 id="71-完整案例書籍搜尋功能">7.1 完整案例：書籍搜尋功能</h3>
<p><strong>業務需求</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">REQ-SEARCH-001: 實作書籍搜尋功能
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="k">-</span> 使用者可輸入關鍵字搜尋書籍
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">-</span> 支援書名、作者、ISBN 搜尋
</span></span><span class="line"><span class="ln">4</span><span class="cl">- 顯示搜尋結果列表</span></span></code></pre></div><hr>
<h4 id="初步評估識別為-god-ticket">初步評估：識別為 God Ticket</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">原始任務分析：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">實作完整書籍搜尋功能（包含 UI、Controller、UseCase、Repository）
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">指標計算：
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 職責數量：10 個
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  <span class="k">1.</span> SearchBar UI 元件
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  <span class="k">2.</span> SearchResultList UI 元件
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  <span class="k">3.</span> SearchController 狀態管理
</span></span><span class="line"><span class="ln">10</span><span class="cl">  <span class="k">4.</span> SearchBookUseCase 業務協調
</span></span><span class="line"><span class="ln">11</span><span class="cl">  <span class="k">5.</span> Repository 查詢方法（書名搜尋）
</span></span><span class="line"><span class="ln">12</span><span class="cl">  <span class="k">6.</span> Repository 查詢方法（作者搜尋）
</span></span><span class="line"><span class="ln">13</span><span class="cl">  <span class="k">7.</span> Repository 查詢方法（ISBN 搜尋）
</span></span><span class="line"><span class="ln">14</span><span class="cl">  <span class="k">8.</span> 錯誤處理
</span></span><span class="line"><span class="ln">15</span><span class="cl">  <span class="k">9.</span> 載入狀態處理
</span></span><span class="line"><span class="ln">16</span><span class="cl">  <span class="k">10.</span> 空結果處理
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">-</span> 程式碼行數：~400 行
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">-</span> 涉及檔案：10 個
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">-</span> 測試用例：25 個
</span></span><span class="line"><span class="ln">21</span><span class="cl">
</span></span><span class="line"><span class="ln">22</span><span class="cl">複雜度評估：
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="k">-</span> 職責：10 個 → Level 4
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">-</span> 行數：400 行 → Level 4
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">-</span> 檔案：10 個 → Level 4
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">-</span> 測試：25 個 → Level 4
</span></span><span class="line"><span class="ln">28</span><span class="cl">
</span></span><span class="line"><span class="ln">29</span><span class="cl">結論：God Ticket 必須拆分</span></span></code></pre></div><hr>
<h4 id="拆分策略clean-architecture-分層拆分">拆分策略：Clean Architecture 分層拆分</h4>
<h5 id="第一步按層級分組檔案">第一步：按層級分組檔案</h5>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">Layer 5 (Domain + Infrastructure):
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">- SearchQuery Value Object
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">- IBookRepository.searchByTitle()
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">- IBookRepository.searchByAuthor()
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">- IBookRepository.searchByIsbn()
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">- SQLiteBookRepository 查詢實作
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">Layer 3 (UseCase):
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">- SearchBookUseCase
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">Layer 2 (Behavior):
</span></span><span class="line"><span class="ln">12</span><span class="cl">- SearchController
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl">Layer 1 (UI):
</span></span><span class="line"><span class="ln">15</span><span class="cl">- SearchBar Widget
</span></span><span class="line"><span class="ln">16</span><span class="cl">- SearchResultList Widget</span></span></code></pre></div><h6 id="第二步設計拆分後的-ticket">第二步：設計拆分後的 Ticket</h6>
<hr>
<h6 id="ticket-1-定義-searchquery-value-objectlayer-5">Ticket 1: 定義 SearchQuery Value Object（Layer 5）</h6>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #301: 定義 SearchQuery Value Object
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 5 (Domain Implementation)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略：策略 2（具體實作）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>REQ-SEARCH-001: 書籍搜尋功能
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span>建立 <span class="sb">`SearchQuery`</span> Value Object，封裝搜尋條件驗證
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立 <span class="sb">`lib/domain/value_objects/search_query.dart`</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">2.</span> 實作 SearchQuery 類別
</span></span><span class="line"><span class="ln">15</span><span class="cl">   <span class="k">-</span> 驗證查詢字串長度（最少 2 個字元）
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> trim() 處理空白
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> equals / hashCode
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">3.</span> 撰寫單元測試
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">4.</span> 確保測試通過
</span></span><span class="line"><span class="ln">20</span><span class="cl">
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> SearchQuery 類別實作完整
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="k">- [ ]</span> 驗證邏輯正確（最少 2 字元）
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 4 個測試）
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">26</span><span class="cl">
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責：1 個
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="k">-</span> 行數：~30 行
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="k">-</span> 檔案：1 個
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="k">-</span> 測試：4 個
</span></span><span class="line"><span class="ln">32</span><span class="cl">→ Level 1（簡單）
</span></span><span class="line"><span class="ln">33</span><span class="cl">
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="gu"></span>15-20 分鐘</span></span></code></pre></div><hr>
<h4 id="ticket-2-擴充-ibookrepository-查詢方法layer-4">Ticket 2: 擴充 IBookRepository 查詢方法（Layer 4）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #302: 定義 IBookRepository 搜尋方法
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 4 (Domain Interfaces)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略：策略 1（Interface 定義）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>REQ-SEARCH-001: 書籍搜尋功能
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span>在 <span class="sb">`IBookRepository`</span> 介面新增搜尋方法簽名
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 修改 <span class="sb">`lib/domain/repositories/i_book_repository.dart`</span>
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">2.</span> 新增 <span class="sb">`searchByTitle(String query)`</span> 方法簽名
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">3.</span> 新增 <span class="sb">`searchByAuthor(String query)`</span> 方法簽名
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">4.</span> 新增 <span class="sb">`searchByIsbn(String query)`</span> 方法簽名
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">5.</span> 撰寫文檔註解
</span></span><span class="line"><span class="ln">18</span><span class="cl">
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> 3 個搜尋方法簽名完整
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">- [ ]</span> 回傳類型為 <span class="sb">`Future&lt;List&lt;Book&gt;&gt;`</span>
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">- [ ]</span> 文檔註解包含需求編號
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">24</span><span class="cl">
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責：1 個（定義介面）
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">-</span> 行數：~15 行
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">-</span> 檔案：1 個（修改）
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="k">-</span> 測試：0 個
</span></span><span class="line"><span class="ln">30</span><span class="cl">→ Level 1（簡單）
</span></span><span class="line"><span class="ln">31</span><span class="cl">
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="gu"></span>10 分鐘</span></span></code></pre></div><hr>
<h4 id="ticket-3-實作-bookrepository-搜尋方法layer-5">Ticket 3: 實作 BookRepository 搜尋方法（Layer 5）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #303: 實作 SQLiteBookRepository 搜尋
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 5 (Infrastructure)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略：策略 2（具體實作）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 依賴：Ticket #301, #302
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span>REQ-SEARCH-001: 書籍搜尋功能
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>實作 <span class="sb">`SQLiteBookRepository`</span> 的 3 個搜尋方法
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 修改 <span class="sb">`lib/infrastructure/repositories/sqlite_book_repository.dart`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">2.</span> 實作 <span class="sb">`searchByTitle`</span> 方法
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> SQL LIKE 查詢
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> Data Mapper 轉換
</span></span><span class="line"><span class="ln">18</span><span class="cl">   <span class="k">-</span> 錯誤處理
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">3.</span> 實作 <span class="sb">`searchByAuthor`</span> 方法
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">4.</span> 實作 <span class="sb">`searchByIsbn`</span> 方法
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">5.</span> 撰寫單元測試（每個方法 2-3 個測試）
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">6.</span> 確保測試通過
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> 3 個搜尋方法實作完整
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">- [ ]</span> SQL 查詢使用 LIKE 模糊搜尋
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">- [ ]</span> 異常處理完整
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 8 個測試）
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">30</span><span class="cl">
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責：4 個（3 個搜尋方法 + 異常處理）
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="k">-</span> 行數：~95 行
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="k">-</span> 檔案：1 個（修改）
</span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="k">-</span> 測試：8 個
</span></span><span class="line"><span class="ln">36</span><span class="cl">→ Level 3（複雜）可接受
</span></span><span class="line"><span class="ln">37</span><span class="cl">（註：3 個搜尋方法邏輯相似，整合實作較有效率）
</span></span><span class="line"><span class="ln">38</span><span class="cl">
</span></span><span class="line"><span class="ln">39</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="gu"></span>60-75 分鐘</span></span></code></pre></div><hr>
<h4 id="ticket-4-實作-searchbookusecaselayer-3">Ticket 4: 實作 SearchBookUseCase（Layer 3）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #304: 實作 SearchBookUseCase
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 3 (UseCase)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略：策略 4（整合連接）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 依賴：Ticket #302, #303
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span>REQ-SEARCH-001: 書籍搜尋功能
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>實作 <span class="sb">`SearchBookUseCase`</span>，協調搜尋業務流程
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立 <span class="sb">`lib/application/use_cases/search_book_use_case.dart`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">2.</span> 注入 <span class="sb">`IBookRepository`</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">3.</span> 實作 <span class="sb">`execute(SearchQuery query, SearchType type)`</span> 方法
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> 根據 SearchType 呼叫對應的 Repository 方法
</span></span><span class="line"><span class="ln">18</span><span class="cl">   <span class="k">-</span> 處理空結果
</span></span><span class="line"><span class="ln">19</span><span class="cl">   <span class="k">-</span> 處理異常
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">4.</span> 撰寫整合測試
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">5.</span> 確保測試通過
</span></span><span class="line"><span class="ln">22</span><span class="cl">
</span></span><span class="line"><span class="ln">23</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> UseCase 正確注入 IBookRepository
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">- [ ]</span> 支援 3 種搜尋類型（Title / Author / ISBN）
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">- [ ]</span> 整合測試 100% 通過（至少 5 個測試）
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">- [ ]</span> 異常處理完整
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">29</span><span class="cl">
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責：2 個（業務協調、異常處理）
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">-</span> 行數：~65 行
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="k">-</span> 檔案：1 個
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="k">-</span> 測試：5 個
</span></span><span class="line"><span class="ln">35</span><span class="cl">→ Level 2（中等）
</span></span><span class="line"><span class="ln">36</span><span class="cl">
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="gu"></span>35-45 分鐘</span></span></code></pre></div><hr>
<h4 id="ticket-5-實作-searchcontrollerlayer-2">Ticket 5: 實作 SearchController（Layer 2）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #305: 實作 SearchController
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 2 (Behavior)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略：策略 4（整合連接）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 依賴：Ticket #304
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span>REQ-SEARCH-001: 書籍搜尋功能
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>實作 <span class="sb">`SearchController`</span>，管理搜尋狀態
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立 <span class="sb">`lib/presentation/controllers/search_controller.dart`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">2.</span> 注入 <span class="sb">`SearchBookUseCase`</span>
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">3.</span> 實作狀態管理
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> isLoading（載入中）
</span></span><span class="line"><span class="ln">18</span><span class="cl">   <span class="k">-</span> searchResults（搜尋結果）
</span></span><span class="line"><span class="ln">19</span><span class="cl">   <span class="k">-</span> errorMessage（錯誤訊息）
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">4.</span> 實作 <span class="sb">`search(String query, SearchType type)`</span> 方法
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">5.</span> 撰寫單元測試
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">6.</span> 確保測試通過
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> SearchController 正確注入 UseCase
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">- [ ]</span> 狀態管理正確（loading / success / error）
</span></span><span class="line"><span class="ln">27</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 5 個測試）
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">29</span><span class="cl">
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責：2 個（狀態管理、UseCase 整合）
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">-</span> 行數：~70 行
</span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="k">-</span> 檔案：1 個
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="k">-</span> 測試：5 個
</span></span><span class="line"><span class="ln">35</span><span class="cl">→ Level 2（中等）
</span></span><span class="line"><span class="ln">36</span><span class="cl">
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="gu"></span>40 分鐘</span></span></code></pre></div><hr>
<h4 id="ticket-6-實作搜尋-ui-元件layer-1">Ticket 6: 實作搜尋 UI 元件（Layer 1）</h4>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gu">## Ticket #306: 實作 SearchBar 和 SearchResultList
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer 1 (UI)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略：策略 2（具體實作）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu">### 依賴：Ticket #305
</span></span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">### 業務需求
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span>REQ-SEARCH-001: 書籍搜尋功能
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>實作搜尋介面的 UI 元件
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu">### 步驟
</span></span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="gu"></span><span class="k">1.</span> 建立 <span class="sb">`lib/presentation/widgets/search_bar.dart`</span>
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">2.</span> 實作 SearchBar Widget
</span></span><span class="line"><span class="ln">16</span><span class="cl">   <span class="k">-</span> TextField 輸入框
</span></span><span class="line"><span class="ln">17</span><span class="cl">   <span class="k">-</span> SearchType 選擇器
</span></span><span class="line"><span class="ln">18</span><span class="cl">   <span class="k">-</span> 搜尋按鈕
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">3.</span> 建立 <span class="sb">`lib/presentation/widgets/search_result_list.dart`</span>
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">4.</span> 實作 SearchResultList Widget
</span></span><span class="line"><span class="ln">21</span><span class="cl">   <span class="k">-</span> 顯示搜尋結果
</span></span><span class="line"><span class="ln">22</span><span class="cl">   <span class="k">-</span> 載入中狀態
</span></span><span class="line"><span class="ln">23</span><span class="cl">   <span class="k">-</span> 空結果提示
</span></span><span class="line"><span class="ln">24</span><span class="cl">   <span class="k">-</span> 錯誤提示
</span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="k">5.</span> 撰寫 Widget 測試
</span></span><span class="line"><span class="ln">26</span><span class="cl"><span class="k">6.</span> 確保測試通過
</span></span><span class="line"><span class="ln">27</span><span class="cl">
</span></span><span class="line"><span class="ln">28</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> SearchBar UI 正確顯示和互動
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="k">- [ ]</span> SearchResultList 正確顯示各種狀態
</span></span><span class="line"><span class="ln">31</span><span class="cl"><span class="k">- [ ]</span> Widget 測試 100% 通過（至少 6 個測試）
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">33</span><span class="cl">
</span></span><span class="line"><span class="ln">34</span><span class="cl"><span class="gu">### 指標評估
</span></span></span><span class="line"><span class="ln">35</span><span class="cl"><span class="gu"></span><span class="k">-</span> 職責：2 個（SearchBar、SearchResultList）
</span></span><span class="line"><span class="ln">36</span><span class="cl"><span class="k">-</span> 行數：~90 行
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="k">-</span> 檔案：2 個
</span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="k">-</span> 測試：6 個
</span></span><span class="line"><span class="ln">39</span><span class="cl">→ Level 2（中等）
</span></span><span class="line"><span class="ln">40</span><span class="cl">
</span></span><span class="line"><span class="ln">41</span><span class="cl"><span class="gu">### 預估時間
</span></span></span><span class="line"><span class="ln">42</span><span class="cl"><span class="gu"></span>50-60 分鐘</span></span></code></pre></div><hr>
<h4 id="拆分結果總結-1">拆分結果總結</h4>
<p><strong>拆分前後對比</strong>：</p>
<table>
  <thead>
      <tr>
          <th>項目</th>
          <th>拆分前（God Ticket）</th>
          <th>拆分後（6 個 Ticket）</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>職責數量</td>
          <td>10 個</td>
          <td>平均 1.8 個</td>
      </tr>
      <tr>
          <td>程式碼行數</td>
          <td>~400 行</td>
          <td>平均 61 行</td>
      </tr>
      <tr>
          <td>檔案數量</td>
          <td>10 個</td>
          <td>平均 1.2 個</td>
      </tr>
      <tr>
          <td>測試數量</td>
          <td>25 個</td>
          <td>平均 4.7 個</td>
      </tr>
      <tr>
          <td>複雜度等級</td>
          <td>Level 4</td>
          <td>5 個 Level 1-2<br>1 個 Level 3</td>
      </tr>
      <tr>
          <td>預估總時間</td>
          <td>N/A（無法估算）</td>
          <td>210-250 分鐘</td>
      </tr>
  </tbody>
</table>
<p><strong>拆分效益分析</strong>：</p>
<ol>
<li>
<p><strong>風險大幅降低</strong>：</p>
<ul>
<li>從 1 個無法管理的 God Ticket → 6 個可控 Ticket</li>
<li>單一 Ticket 失敗不影響其他 Ticket</li>
</ul>
</li>
<li>
<p><strong>支援並行開發</strong>：</p>
<ul>
<li>Phase 1: Ticket #301, #302 可並行</li>
<li>Phase 2: Ticket #303 執行</li>
<li>Phase 3: Ticket #304 執行</li>
<li>Phase 4: Ticket #305, #306 可部分並行</li>
</ul>
</li>
<li>
<p><strong>Review 效率提升</strong>：</p>
<ul>
<li>每次 Review 平均 61 行（vs 400 行）</li>
<li>Review 時間縮短 85%</li>
</ul>
</li>
<li>
<p><strong>測試獨立性</strong>：</p>
<ul>
<li>每層可獨立測試</li>
<li>Mock 依賴簡單明確</li>
</ul>
</li>
</ol>
<hr>
<h3 id="72-常見錯誤與解決方案">7.2 常見錯誤與解決方案</h3>
<h4 id="錯誤-1過度拆分">錯誤 1：過度拆分</h4>
<p><strong>問題描述</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">將 Level 2（中等）Ticket 拆分為多個 Level 1 Ticket，
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">反而增加管理成本且沒有實質收益。
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">範例：
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">原始 Ticket（Level 2）：實作 Rating Value Object
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> 職責：2 個（建立 + 驗證）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> 行數：50 行
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">-</span> 測試：5 個
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">過度拆分為 2 個 Ticket：
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">-</span> Ticket A：實作 Rating 建構子（Level 1，25 行）
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> Ticket B：實作 Rating 驗證邏輯（Level 1，25 行）
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">問題：
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">-</span> 兩個 Ticket 高度耦合，必須連續執行
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">-</span> 增加了額外的管理成本
</span></span><span class="line"><span class="ln">19</span><span class="cl">- 沒有實質的風險降低</span></span></code></pre></div><p><strong>解決方案</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">保持原始 Level 2 Ticket 不拆分
</span></span><span class="line"><span class="ln">2</span><span class="cl">
</span></span><span class="line"><span class="ln">3</span><span class="cl">判斷準則：
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">-</span> Level 1-2 Ticket 通常不需要拆分
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="k">-</span> 只有 Level 3-4 才需要評估拆分
</span></span><span class="line"><span class="ln">7</span><span class="cl">- 拆分後的子 Ticket 應該相對獨立</span></span></code></pre></div><hr>
<h4 id="錯誤-2拆分後依賴過於複雜">錯誤 2：拆分後依賴過於複雜</h4>
<p><strong>問題描述</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">拆分方式導致依賴關係過於複雜，
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">難以理解和管理執行順序。
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">範例：
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">拆分為 8 個 Ticket，依賴關係如下：
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">Ticket 1 → Ticket 2 → Ticket 4
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">Ticket 1 → Ticket 3 → Ticket 5
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">Ticket 2 → Ticket 6
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">Ticket 3 → Ticket 6
</span></span><span class="line"><span class="ln">10</span><span class="cl">Ticket 5 → Ticket 7
</span></span><span class="line"><span class="ln">11</span><span class="cl">Ticket 6 → Ticket 7 → Ticket 8
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">問題：
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">-</span> 依賴網絡複雜，難以追蹤
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">-</span> 執行順序不明確
</span></span><span class="line"><span class="ln">17</span><span class="cl">- 容易遺漏依賴</span></span></code></pre></div><p><strong>解決方案</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">使用線性或樹狀依賴結構
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">優化後的依賴關係：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">Phase 1（並行）:
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">├─ Ticket 1, Ticket 2
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">Phase 2（並行）:
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">├─ Ticket 3, Ticket 4（依賴 Phase 1）
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">Phase 3:
</span></span><span class="line"><span class="ln">11</span><span class="cl">└─ Ticket 5（依賴 Phase 2）
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">Phase 4:
</span></span><span class="line"><span class="ln">14</span><span class="cl">└─ Ticket 6（依賴 Phase 3）
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">判斷準則：
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">-</span> 優先使用 Phase 分組（線性依賴）
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="k">-</span> 同 Phase 內的 Ticket 可並行
</span></span><span class="line"><span class="ln">20</span><span class="cl">- 避免跨 Phase 的複雜依賴</span></span></code></pre></div><hr>
<h4 id="錯誤-3拆分邊界不清晰">錯誤 3：拆分邊界不清晰</h4>
<p><strong>問題描述</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">拆分後的子 Ticket 職責重疊或邊界模糊，
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">導致實作時不知道該在哪個 Ticket 完成。
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">範例：
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">原始：實作完整 BookRepository
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">拆分後：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">-</span> Ticket A：實作 getBookByIsbn
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">-</span> Ticket B：實作 Data Mapper
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">-</span> Ticket C：實作異常處理
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">問題：
</span></span><span class="line"><span class="ln">13</span><span class="cl">
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">-</span> Ticket A 需要 Data Mapper（依賴 Ticket B）
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">-</span> Ticket A 需要異常處理（依賴 Ticket C）
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">-</span> 但 Ticket A 應該先完成？
</span></span><span class="line"><span class="ln">17</span><span class="cl">- 邊界模糊，無法獨立完成</span></span></code></pre></div><p><strong>解決方案</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">確保每個子 Ticket 可獨立完成
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">正確拆分：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> Ticket A：實作 getBookByIsbn（含 Mapper + 異常處理）
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> Ticket B：實作 saveBook（含 Mapper + 異常處理）
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> Ticket C：實作 deleteBook（含異常處理）
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">判斷準則：
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">-</span> 每個子 Ticket 應該是「最小可交付單元」
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">-</span> 避免將共用邏輯獨立為 Ticket
</span></span><span class="line"><span class="ln">13</span><span class="cl">- 共用邏輯應整合到使用它的 Ticket 中</span></span></code></pre></div><hr>
<h3 id="73-拆分最佳實踐">7.3 拆分最佳實踐</h3>
<h4 id="實踐-1優先選擇架構分層拆分">實踐 1：優先選擇架構分層拆分</h4>
<p><strong>原則</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">當 Ticket 跨越多個架構層級時，
</span></span><span class="line"><span class="ln">2</span><span class="cl">優先按照 Clean Architecture 分層拆分。
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">優點：
</span></span><span class="line"><span class="ln">5</span><span class="cl">依賴方向清晰（內層不依賴外層）
</span></span><span class="line"><span class="ln">6</span><span class="cl">測試策略明確（每層有標準測試方法）
</span></span><span class="line"><span class="ln">7</span><span class="cl">可並行開發（不同層可由不同開發者負責）
</span></span><span class="line"><span class="ln">8</span><span class="cl">符合單一職責原則</span></span></code></pre></div><p><strong>範例</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">原始任務：實作書籍評分功能（跨越 4 層）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">錯誤：按功能模組拆分
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="k">-</span> Ticket A：評分輸入功能（UI + Controller + UseCase）
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> Ticket B：評分儲存功能（Repository + Mapper）
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">問題：
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">-</span> Ticket A 跨越 3 層，依賴關係複雜
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">-</span> 測試困難（需要 Mock 多層）
</span></span><span class="line"><span class="ln">11</span><span class="cl">
</span></span><span class="line"><span class="ln">12</span><span class="cl">正確：按架構分層拆分
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> Ticket 1：Rating Domain 模型（Layer 5）
</span></span><span class="line"><span class="ln">14</span><span class="cl"><span class="k">-</span> Ticket 2：IRatingRepository + Impl（Layer 4-5）
</span></span><span class="line"><span class="ln">15</span><span class="cl"><span class="k">-</span> Ticket 3：RateBookUseCase（Layer 3）
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">-</span> Ticket 4：RatingController + Widget（Layer 1-2）
</span></span><span class="line"><span class="ln">17</span><span class="cl">
</span></span><span class="line"><span class="ln">18</span><span class="cl">優點：
</span></span><span class="line"><span class="ln">19</span><span class="cl">
</span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="k">-</span> 每個 Ticket 職責單一
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">-</span> 依賴方向清楚
</span></span><span class="line"><span class="ln">22</span><span class="cl">- 測試獨立簡單</span></span></code></pre></div><hr>
<h4 id="實踐-2保持線性依賴順序">實踐 2：保持線性依賴順序</h4>
<p><strong>原則</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">優先設計線性或樹狀依賴結構，
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">避免複雜的網狀依賴關係。
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">建議結構：
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">線性依賴：Ticket 1 → Ticket 2 → Ticket 3 → Ticket 4
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">樹狀依賴：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">   Ticket 1
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">   ├─ Ticket 2
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">   │  └─ Ticket 4
</span></span><span class="line"><span class="ln">10</span><span class="cl">   └─ Ticket 3
</span></span><span class="line"><span class="ln">11</span><span class="cl">      └─ Ticket 5
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">避免結構：
</span></span><span class="line"><span class="ln">14</span><span class="cl">網狀依賴：多個交叉依賴，難以追蹤</span></span></code></pre></div><p><strong>實施方法</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">步驟 1：識別「核心 Ticket」
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="k">-</span> Domain 層 Ticket 通常是核心
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="k">-</span> 其他層依賴 Domain 層
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">步驟 2：按照 Clean Architecture 依賴方向排序
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> Layer 5 → Layer 4 → Layer 3 → Layer 2 → Layer 1
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">步驟 3：標記 Phase
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="k">-</span> Phase 1：Layer 5（Domain）
</span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="k">-</span> Phase 2：Layer 4-5（Repository）
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">-</span> Phase 3：Layer 3（UseCase）
</span></span><span class="line"><span class="ln">12</span><span class="cl">- Phase 4：Layer 1-2（Presentation）</span></span></code></pre></div><hr>
<h4 id="實踐-3每個-ticket-包含完整測試">實踐 3：每個 Ticket 包含完整測試</h4>
<p><strong>原則</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">每個 Ticket 應該包含對應的測試，
</span></span><span class="line"><span class="ln">2</span><span class="cl">不要將測試獨立為單獨 Ticket（除非測試數量 &gt; 10）。
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">優點：
</span></span><span class="line"><span class="ln">5</span><span class="cl">TDD 紅綠燈循環完整
</span></span><span class="line"><span class="ln">6</span><span class="cl">每個 Ticket 交付時就是可測試的
</span></span><span class="line"><span class="ln">7</span><span class="cl">避免「實作完成但測試缺失」的情況</span></span></code></pre></div><p><strong>實施方法</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">在 Ticket 驗收條件中明確測試要求：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">範例：
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">## Ticket #X: 實作 Rating Value Object
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">### 驗收條件
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> Rating 類別實作完整
</span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="k">- [ ]</span> 單元測試 100% 通過（至少 3 個測試）
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  <span class="k">-</span> 測試 1：建立有效評分
</span></span><span class="line"><span class="ln">10</span><span class="cl">  <span class="k">-</span> 測試 2：評分過低拋出異常
</span></span><span class="line"><span class="ln">11</span><span class="cl">  <span class="k">-</span> 測試 3：評分過高拋出異常
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">- [ ]</span> 測試覆蓋率 &gt; 90%
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">- [ ]</span> dart analyze 0 錯誤
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">例外情況（測試獨立 Ticket）：
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">-</span> 測試用例 &gt; 10 個（測試複雜度 Level 4）
</span></span><span class="line"><span class="ln">18</span><span class="cl"><span class="k">-</span> 補充現有程式碼的測試（非新功能）
</span></span><span class="line"><span class="ln">19</span><span class="cl">- 整合測試（跨多層驗證）</span></span></code></pre></div><hr>
<h4 id="實踐-4明確標記層級和策略">實踐 4：明確標記層級和策略</h4>
<p><strong>原則</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">每個 Ticket 標題應包含：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="k">1.</span> [Layer X] 標籤（標示架構層級）
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="k">2.</span> 策略類型（Interface / 實作 / 整合）
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">格式：
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="gu">## Ticket #NNN: [Layer X] {動詞} {目標}
</span></span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">範例：
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">好的標題：
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="k">-</span> [Layer 4] 定義 IBookRepository 介面
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="k">-</span> [Layer 5] 實作 SQLiteBookRepository
</span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="k">-</span> [Layer 3] 實作 GetBookUseCase
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">不好的標題：
</span></span><span class="line"><span class="ln">16</span><span class="cl">
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">-</span> 書籍資料存取功能（沒有層級、目標不明確）
</span></span><span class="line"><span class="ln">18</span><span class="cl">- 實作 Repository（沒有層級、範圍不清楚）</span></span></code></pre></div><p><strong>實施方法</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">在 Ticket 範本中包含：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">### 層級：Layer X (層級名稱)
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu">### 策略：策略 N（策略名稱）
</span></span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">範例：
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="gu">## Ticket #101: [Layer 4] 定義 IBookRepository 介面
</span></span></span><span class="line"><span class="ln"> 8</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">### 層級：Layer 4 (Domain Interfaces)
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu">### 策略：策略 1（Interface 定義）
</span></span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu">### 目標
</span></span></span><span class="line"><span class="ln">13</span><span class="cl"><span class="gu"></span>建立 <span class="sb">`IBookRepository`</span> 介面，定義書籍資料存取的契約
</span></span><span class="line"><span class="ln">14</span><span class="cl">
</span></span><span class="line"><span class="ln">15</span><span class="cl">這樣可以：
</span></span><span class="line"><span class="ln">16</span><span class="cl">快速識別 Ticket 的架構位置
</span></span><span class="line"><span class="ln">17</span><span class="cl">理解 Ticket 的目的（定義 / 實作 / 整合）
</span></span><span class="line"><span class="ln">18</span><span class="cl">追蹤依賴關係（內層 → 外層）</span></span></code></pre></div><hr>
<h2 id="附錄-a術語表">附錄 A：術語表</h2>
<table>
  <thead>
      <tr>
          <th>術語</th>
          <th>英文</th>
          <th>定義</th>
          <th>範例</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td><strong>職責</strong></td>
          <td>Responsibility</td>
          <td>Ticket 需要完成的獨立功能點或邊界條件</td>
          <td>定義介面、實作方法、處理異常</td>
      </tr>
      <tr>
          <td><strong>複雜度等級</strong></td>
          <td>Complexity Level</td>
          <td>基於 4 個量化指標計算的任務複雜度（Level 1-4）</td>
          <td>Level 2（中等）</td>
      </tr>
      <tr>
          <td><strong>God Ticket</strong></td>
          <td>God Ticket</td>
          <td>範圍過大、無法管理的任務（Level 4）</td>
          <td>包含 8 個檔案、300 行程式碼的任務</td>
      </tr>
      <tr>
          <td><strong>單層修改原則</strong></td>
          <td>Single Layer Modification</td>
          <td>每個 Ticket 應只修改單一架構層級</td>
          <td>Ticket 只修改 Domain 層</td>
      </tr>
      <tr>
          <td><strong>依賴規則</strong></td>
          <td>Dependency Rule</td>
          <td>Clean Architecture 的依賴方向規則（外層→內層）</td>
          <td>UseCase 依賴 Repository Interface</td>
      </tr>
      <tr>
          <td><strong>最小可交付單元</strong></td>
          <td>Minimum Deliverable Unit</td>
          <td>可獨立完成、測試、交付的最小功能單元</td>
          <td>實作單一 Value Object</td>
      </tr>
      <tr>
          <td><strong>指標整合評估</strong></td>
          <td>Integrated Indicator Assessment</td>
          <td>取 4 個指標中最高的複雜度等級</td>
          <td>max(Level 2, Level 3, Level 1, Level 2) = Level 3</td>
      </tr>
      <tr>
          <td><strong>拆分策略</strong></td>
          <td>Splitting Strategy</td>
          <td>將大任務拆分為小任務的標準方法</td>
          <td>按架構分層拆分</td>
      </tr>
      <tr>
          <td><strong>Phase</strong></td>
          <td>Phase</td>
          <td>依賴順序的執行階段</td>
          <td>Phase 1（Domain 層）→ Phase 2（Repository 層）</td>
      </tr>
  </tbody>
</table>
<hr>
<h2 id="附錄-b拆分決策模板">附錄 B：拆分決策模板</h2>
<p><strong>模板用途</strong>：用於記錄 Ticket 拆分的決策過程</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl"><span class="gh"># Ticket 拆分決策記錄
</span></span></span><span class="line"><span class="ln"> 2</span><span class="cl"><span class="gh"></span>
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="gu">## 基本資訊
</span></span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="gu"></span><span class="k">-</span> **原始任務**：[任務描述]
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> **業務需求**：[需求編號]
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> **評估日期**：YYYY-MM-DD
</span></span><span class="line"><span class="ln"> 7</span><span class="cl"><span class="k">-</span> **評估人員**：[姓名]
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">
</span></span><span class="line"><span class="ln"> 9</span><span class="cl"><span class="gu">## 指標評估
</span></span></span><span class="line"><span class="ln">10</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">11</span><span class="cl"><span class="gu">### 職責數量
</span></span></span><span class="line"><span class="ln">12</span><span class="cl"><span class="gu"></span><span class="k">-</span> **職責列表**：
</span></span><span class="line"><span class="ln">13</span><span class="cl">  <span class="k">1.</span> [職責 1]
</span></span><span class="line"><span class="ln">14</span><span class="cl">  <span class="k">2.</span> [職責 2]
</span></span><span class="line"><span class="ln">15</span><span class="cl">  ...
</span></span><span class="line"><span class="ln">16</span><span class="cl"><span class="k">-</span> **總計**：X 個
</span></span><span class="line"><span class="ln">17</span><span class="cl"><span class="k">-</span> **等級**：Level X
</span></span><span class="line"><span class="ln">18</span><span class="cl">
</span></span><span class="line"><span class="ln">19</span><span class="cl"><span class="gu">### 程式碼行數
</span></span></span><span class="line"><span class="ln">20</span><span class="cl"><span class="gu"></span><span class="k">-</span> **預估行數**：X 行
</span></span><span class="line"><span class="ln">21</span><span class="cl"><span class="k">-</span> **依據**：[參考類似任務或經驗估算]
</span></span><span class="line"><span class="ln">22</span><span class="cl"><span class="k">-</span> **等級**：Level X
</span></span><span class="line"><span class="ln">23</span><span class="cl">
</span></span><span class="line"><span class="ln">24</span><span class="cl"><span class="gu">### 涉及檔案
</span></span></span><span class="line"><span class="ln">25</span><span class="cl"><span class="gu"></span><span class="k">-</span> **檔案列表**：
</span></span><span class="line"><span class="ln">26</span><span class="cl">  <span class="k">1.</span> [檔案路徑 1]
</span></span><span class="line"><span class="ln">27</span><span class="cl">  <span class="k">2.</span> [檔案路徑 2]
</span></span><span class="line"><span class="ln">28</span><span class="cl">  ...
</span></span><span class="line"><span class="ln">29</span><span class="cl"><span class="k">-</span> **總計**：X 個
</span></span><span class="line"><span class="ln">30</span><span class="cl"><span class="k">-</span> **等級**：Level X
</span></span><span class="line"><span class="ln">31</span><span class="cl">
</span></span><span class="line"><span class="ln">32</span><span class="cl"><span class="gu">### 測試用例數
</span></span></span><span class="line"><span class="ln">33</span><span class="cl"><span class="gu"></span><span class="k">-</span> **測試列表**：
</span></span><span class="line"><span class="ln">34</span><span class="cl">  <span class="k">1.</span> [測試案例 1]
</span></span><span class="line"><span class="ln">35</span><span class="cl">  <span class="k">2.</span> [測試案例 2]
</span></span><span class="line"><span class="ln">36</span><span class="cl">  ...
</span></span><span class="line"><span class="ln">37</span><span class="cl"><span class="k">-</span> **總計**：X 個
</span></span><span class="line"><span class="ln">38</span><span class="cl"><span class="k">-</span> **等級**：Level X
</span></span><span class="line"><span class="ln">39</span><span class="cl">
</span></span><span class="line"><span class="ln">40</span><span class="cl"><span class="gu">## 複雜度結論
</span></span></span><span class="line"><span class="ln">41</span><span class="cl"><span class="gu"></span><span class="k">-</span> **最高等級**：Level X
</span></span><span class="line"><span class="ln">42</span><span class="cl"><span class="k">-</span> **最終判定**：[簡單 / 中等 / 複雜 / 必須拆分]
</span></span><span class="line"><span class="ln">43</span><span class="cl">
</span></span><span class="line"><span class="ln">44</span><span class="cl"><span class="gu">## 拆分決策
</span></span></span><span class="line"><span class="ln">45</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">46</span><span class="cl"><span class="gu">### 決策結果
</span></span></span><span class="line"><span class="ln">47</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> 不拆分（Level 1-2）
</span></span><span class="line"><span class="ln">48</span><span class="cl"><span class="k">- [ ]</span> 評估拆分（Level 3）
</span></span><span class="line"><span class="ln">49</span><span class="cl"><span class="k">- [ ]</span> 強制拆分（Level 4）
</span></span><span class="line"><span class="ln">50</span><span class="cl">
</span></span><span class="line"><span class="ln">51</span><span class="cl"><span class="gu">### 拆分原因（如適用）
</span></span></span><span class="line"><span class="ln">52</span><span class="cl"><span class="gu"></span>[說明為什麼需要拆分]
</span></span><span class="line"><span class="ln">53</span><span class="cl">
</span></span><span class="line"><span class="ln">54</span><span class="cl"><span class="gu">### 拆分策略（如適用）
</span></span></span><span class="line"><span class="ln">55</span><span class="cl"><span class="gu"></span><span class="k">- [ ]</span> 按架構分層拆分（優先）
</span></span><span class="line"><span class="ln">56</span><span class="cl"><span class="k">- [ ]</span> 按職責拆分（次之）
</span></span><span class="line"><span class="ln">57</span><span class="cl"><span class="k">- [ ]</span> 按檔案拆分（最後）
</span></span><span class="line"><span class="ln">58</span><span class="cl">
</span></span><span class="line"><span class="ln">59</span><span class="cl"><span class="gu">## 拆分方案（如適用）
</span></span></span><span class="line"><span class="ln">60</span><span class="cl"><span class="gu"></span>
</span></span><span class="line"><span class="ln">61</span><span class="cl"><span class="gu">### 子 Ticket 列表
</span></span></span><span class="line"><span class="ln">62</span><span class="cl"><span class="gu"></span><span class="k">1.</span> <span class="gs">**Ticket A**</span>：[標題]
</span></span><span class="line"><span class="ln">63</span><span class="cl">   <span class="k">-</span> 層級：Layer X
</span></span><span class="line"><span class="ln">64</span><span class="cl">   <span class="k">-</span> 指標：職責 X、行數 X、檔案 X、測試 X
</span></span><span class="line"><span class="ln">65</span><span class="cl">   <span class="k">-</span> 等級：Level X
</span></span><span class="line"><span class="ln">66</span><span class="cl">
</span></span><span class="line"><span class="ln">67</span><span class="cl"><span class="k">2.</span> <span class="gs">**Ticket B**</span>：[標題]
</span></span><span class="line"><span class="ln">68</span><span class="cl">   <span class="k">-</span> 層級：Layer X
</span></span><span class="line"><span class="ln">69</span><span class="cl">   <span class="k">-</span> 指標：職責 X、行數 X、檔案 X、測試 X
</span></span><span class="line"><span class="ln">70</span><span class="cl">   <span class="k">-</span> 等級：Level X
</span></span><span class="line"><span class="ln">71</span><span class="cl">
</span></span><span class="line"><span class="ln">72</span><span class="cl"><span class="gu">### 依賴關係
</span></span></span><span class="line"><span class="ln">73</span><span class="cl"><span class="gu"></span>```text
</span></span><span class="line"><span class="ln">74</span><span class="cl">[依賴關係圖或順序說明]</span></span></code></pre></div><h3 id="執行順序">執行順序</h3>
<ul>
<li>Phase 1：[Ticket A, Ticket B]</li>
<li>Phase 2：[Ticket C]</li>
<li>&hellip;</li>
</ul>
<h2 id="驗證清單">驗證清單</h2>
<h3 id="拆分前檢查">拆分前檢查</h3>
<ul>
<li><input disabled="" type="checkbox"> 已計算所有 4 個指標</li>
<li><input disabled="" type="checkbox"> 已確定複雜度等級</li>
<li><input disabled="" type="checkbox"> 已確定是否拆分</li>
</ul>
<h3 id="拆分後檢查如適用">拆分後檢查（如適用）</h3>
<ul>
<li><input disabled="" type="checkbox"> 所有子 Ticket 已設計</li>
<li><input disabled="" type="checkbox"> 所有子 Ticket ≤ Level 3</li>
<li><input disabled="" type="checkbox"> 依賴關係明確</li>
<li><input disabled="" type="checkbox"> 功能完整性確認</li>
</ul>
<h2 id="備註">備註</h2>
<p>[其他需要記錄的資訊]</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-text" data-lang="text"><span class="line"><span class="ln"> 1</span><span class="cl">
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">---
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">## 附錄 C：與其他方法論的整合指引
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">### C.1 與 TDD 四階段方法論整合
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">**整合點**：
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">
</span></span><span class="line"><span class="ln">10</span><span class="cl">```markdown
</span></span><span class="line"><span class="ln">11</span><span class="cl">本方法論位於 TDD Phase 1（設計階段）
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">TDD 流程整合：
</span></span><span class="line"><span class="ln">14</span><span class="cl">Phase 1: Ticket 設計
</span></span><span class="line"><span class="ln">15</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">16</span><span class="cl">  使用本方法論評估 Ticket 複雜度
</span></span><span class="line"><span class="ln">17</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">18</span><span class="cl">  如為 Level 3-4，執行拆分
</span></span><span class="line"><span class="ln">19</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">20</span><span class="cl">  所有 Ticket 確認為 Level 1-2
</span></span><span class="line"><span class="ln">21</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">22</span><span class="cl">Phase 2: 測試設計（sage-test-architect）
</span></span><span class="line"><span class="ln">23</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">24</span><span class="cl">Phase 3: 實作（pepper → parsley）
</span></span><span class="line"><span class="ln">25</span><span class="cl">  ↓
</span></span><span class="line"><span class="ln">26</span><span class="cl">Phase 4: 重構（cinnamon-refactor-owl）</span></span></code></pre></div><p><strong>協作方式</strong>：</p>
<ul>
<li>Phase 1 完成時，所有 Ticket 都應該 ≤ Level 3</li>
<li>理想狀態：所有 Ticket 都是 Level 1-2</li>
<li>如有 Level 3 Ticket，應標記為「需要額外 Review」</li>
</ul>
<hr>
<h3 id="c2-與層級隔離派工方法論整合">C.2 與層級隔離派工方法論整合</h3>
<p><strong>整合點</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">本方法論提供「拆分標準」
</span></span><span class="line"><span class="ln">2</span><span class="cl">層級隔離派工方法論提供「派工策略」
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">協作流程：
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">1.</span> 使用本方法論拆分 Ticket（按架構分層）
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="k">2.</span> 使用層級隔離派工方法論決定執行順序
</span></span><span class="line"><span class="ln">7</span><span class="cl">   <span class="k">-</span> 優先派發內層 Ticket（Layer 5）
</span></span><span class="line"><span class="ln">8</span><span class="cl">   <span class="k">-</span> 逐步派發外層 Ticket（Layer 1）
</span></span><span class="line"><span class="ln">9</span><span class="cl">3. 確保依賴順序符合 Clean Architecture 規則</span></span></code></pre></div><p><strong>範例</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">拆分結果（本方法論）：
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">
</span></span><span class="line"><span class="ln"> 3</span><span class="cl"><span class="k">-</span> Ticket 1: Layer 5 Domain
</span></span><span class="line"><span class="ln"> 4</span><span class="cl"><span class="k">-</span> Ticket 2: Layer 4-5 Repository
</span></span><span class="line"><span class="ln"> 5</span><span class="cl"><span class="k">-</span> Ticket 3: Layer 3 UseCase
</span></span><span class="line"><span class="ln"> 6</span><span class="cl"><span class="k">-</span> Ticket 4: Layer 1-2 Presentation
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">派工順序（層級隔離派工方法論）：
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">Week 1:
</span></span><span class="line"><span class="ln">10</span><span class="cl">  ├─ 派發 Ticket 1（Layer 5）給 Developer A
</span></span><span class="line"><span class="ln">11</span><span class="cl">  ├─ Ticket 1 完成後，派發 Ticket 2（Layer 4-5）給 Developer A
</span></span><span class="line"><span class="ln">12</span><span class="cl">
</span></span><span class="line"><span class="ln">13</span><span class="cl">Week 2:
</span></span><span class="line"><span class="ln">14</span><span class="cl">  ├─ Ticket 2 完成後，派發 Ticket 3（Layer 3）給 Developer B
</span></span><span class="line"><span class="ln">15</span><span class="cl">  └─ 可同時派發 Ticket 4（Layer 1-2）給 Developer C（部分並行）</span></span></code></pre></div><hr>
<h3 id="c3-與-code-smell-品質閘門檢測方法論整合">C.3 與 Code Smell 品質閘門檢測方法論整合</h3>
<p><strong>整合點</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln"> 1</span><span class="cl">本方法論在 Ticket 設計階段執行（Design Time）
</span></span><span class="line"><span class="ln"> 2</span><span class="cl">Code Smell 品質閘門在 Ticket 執行後檢測（Runtime）
</span></span><span class="line"><span class="ln"> 3</span><span class="cl">
</span></span><span class="line"><span class="ln"> 4</span><span class="cl">協作流程：
</span></span><span class="line"><span class="ln"> 5</span><span class="cl">設計階段（本方法論）：
</span></span><span class="line"><span class="ln"> 6</span><span class="cl">  ├─ 計算 4 個指標
</span></span><span class="line"><span class="ln"> 7</span><span class="cl">  ├─ 評估複雜度等級
</span></span><span class="line"><span class="ln"> 8</span><span class="cl">  ├─ 決定是否拆分
</span></span><span class="line"><span class="ln"> 9</span><span class="cl">  └─ 確保 Ticket ≤ Level 3
</span></span><span class="line"><span class="ln">10</span><span class="cl">
</span></span><span class="line"><span class="ln">11</span><span class="cl">執行階段（Code Smell 檢測）：
</span></span><span class="line"><span class="ln">12</span><span class="cl">  ├─ C1 檢測：God Ticket（檔案數、層級跨度）
</span></span><span class="line"><span class="ln">13</span><span class="cl">  ├─ C2 檢測：Incomplete Ticket（缺失元素）
</span></span><span class="line"><span class="ln">14</span><span class="cl">  └─ C3 檢測：Ambiguous Responsibility（職責不明）
</span></span><span class="line"><span class="ln">15</span><span class="cl">
</span></span><span class="line"><span class="ln">16</span><span class="cl">如果 Code Smell 檢測失敗：
</span></span><span class="line"><span class="ln">17</span><span class="cl">  ├─ C1 失敗 → 返回本方法論重新拆分
</span></span><span class="line"><span class="ln">18</span><span class="cl">  ├─ C2 失敗 → 補充缺失元素
</span></span><span class="line"><span class="ln">19</span><span class="cl">  └─ C3 失敗 → 明確職責定義</span></span></code></pre></div><p><strong>防範措施</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">如果在設計階段使用本方法論：
</span></span><span class="line"><span class="ln">2</span><span class="cl">C1 God Ticket 失敗率應該降至 0%
</span></span><span class="line"><span class="ln">3</span><span class="cl">C3 Ambiguous Responsibility 失敗率應該降至接近 0%
</span></span><span class="line"><span class="ln">4</span><span class="cl">C2 Incomplete Ticket 仍需要 Code Smell 檢測補強</span></span></code></pre></div><hr>
<h3 id="c4-與-clean-architecture-實作方法論整合">C.4 與 Clean Architecture 實作方法論整合</h3>
<p><strong>整合點</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">本方法論的「架構分層拆分策略」（第三章）
</span></span><span class="line"><span class="ln">2</span><span class="cl">完全基於 Clean Architecture 實作方法論的五層架構。
</span></span><span class="line"><span class="ln">3</span><span class="cl">
</span></span><span class="line"><span class="ln">4</span><span class="cl">依賴關係：
</span></span><span class="line"><span class="ln">5</span><span class="cl">本方法論 → 依賴 Clean Architecture 實作方法論
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="k">-</span> 採用相同的五層架構定義
</span></span><span class="line"><span class="ln">7</span><span class="cl"><span class="k">-</span> 遵循相同的依賴規則
</span></span><span class="line"><span class="ln">8</span><span class="cl">- 使用相同的檔案路徑規範</span></span></code></pre></div><p><strong>參考章節對應</strong>：</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl">本方法論第三章「Clean Architecture 分層拆分策略」
</span></span><span class="line"><span class="ln">2</span><span class="cl">↓ 引用自
</span></span><span class="line"><span class="ln">3</span><span class="cl">Clean Architecture 實作方法論：
</span></span><span class="line"><span class="ln">4</span><span class="cl">
</span></span><span class="line"><span class="ln">5</span><span class="cl"><span class="k">-</span> 第一章：五層架構定義
</span></span><span class="line"><span class="ln">6</span><span class="cl"><span class="k">-</span> 第二章：依賴規則
</span></span><span class="line"><span class="ln">7</span><span class="cl">- 第三章：檔案組織規範</span></span></code></pre></div><hr>
<h2 id="總結">總結</h2>
<h3 id="方法論核心價值">方法論核心價值</h3>
<p>本方法論提供了<strong>量化、客觀、可執行</strong>的 Ticket 拆分標準，解決了傳統拆分方法的主觀性和不一致性問題。</p>
<h3 id="快速開始指引">快速開始指引</h3>
<p><strong>第一步</strong>：評估 Ticket 複雜度</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">1.</span> 計算 4 個指標（職責、行數、檔案、測試）
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="k">2.</span> 取最高複雜度等級
</span></span><span class="line"><span class="ln">3</span><span class="cl">3. 判斷是否需要拆分</span></span></code></pre></div><p><strong>第二步</strong>：執行拆分（如需要）</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">1.</span> 選擇拆分策略（優先：架構分層）
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="k">2.</span> 設計子 Ticket
</span></span><span class="line"><span class="ln">3</span><span class="cl"><span class="k">3.</span> 重新評估每個子 Ticket
</span></span><span class="line"><span class="ln">4</span><span class="cl">4. 確認所有子 Ticket ≤ Level 3</span></span></code></pre></div><p><strong>第三步</strong>：驗證和記錄</p>





<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="ln">1</span><span class="cl"><span class="k">1.</span> 使用檢查清單驗證（第六章）
</span></span><span class="line"><span class="ln">2</span><span class="cl"><span class="k">2.</span> 記錄決策過程（附錄 B 模板）
</span></span><span class="line"><span class="ln">3</span><span class="cl">3. 進入 TDD Phase 2（測試設計）</span></span></code></pre></div><h3 id="相關方法論引用">相關方法論引用</h3>
<p>完整的 Ticket 設計派工流程請參考：</p>
<ul>
<li><a href="/blog/record/ticket-%E8%A8%AD%E8%A8%88%E6%B4%BE%E5%B7%A5%E6%96%B9%E6%B3%95%E8%AB%96/" data-link-title="Ticket 設計派工方法論" data-link-desc="我們如何用 Ticket 機制解決大型開發任務的協作困境：從工作日誌臃腫到積極派發的實踐歷程。">Ticket 設計派工方法論</a> - 主方法論</li>
<li><a href="/blog/record/clean-architecture-%E5%AF%A6%E4%BD%9C%E6%8C%87%E5%BC%95/" data-link-title="Clean Architecture 實作指引" data-link-desc="我們在 AI 協作開發中引入 Clean Architecture 作為任務分派的核心判斷框架。這篇文章整理了四層架構的設計順序、實作順序，以及我們實際執行時的關鍵檢查點。">Clean Architecture 實作方法論</a> - 架構基礎</li>
<li><a href="/blog/record/%E5%B1%A4%E7%B4%9A%E9%9A%94%E9%9B%A2%E8%AE%93%E6%AF%8F%E5%BC%B5-ticket-%E5%8F%AA%E5%81%9A%E4%B8%80%E4%BB%B6%E5%B1%A4%E7%B4%9A%E7%9A%84%E4%BA%8B/" data-link-title="層級隔離：讓每張 Ticket 只做一件層級的事" data-link-desc="我們在實際開發中整理出一套方法論，讓 Clean Architecture 五層架構與 Ticket 拆分真正結合——每張 Ticket 只修改一個架構層，不多也不少。">層級隔離派工方法論</a> - 派工策略</li>
<li>TDD 四階段方法論 - 開發流程</li>
</ul>
<hr>
]]></content:encoded></item></channel></rss>