# DramaLing 前端 difficulty_level 遷移報告 ## 概要 本報告詳細盤點了 `/Users/jettcheng1018/code/dramaling-vocab-learning/frontend` 資料夾中所有提及 "difficulty_level" 的程式碼,分析其遷移需求,配合後端已實施的 `difficulty_level_numeric` (數值型態 1-6) 和 `cefr` (文字型態 A1-C2) 結構改造。 ## 後端變更摘要 - **舊欄位**: `difficulty_level` (文字型態, A1-C2) - **新欄位**: - `difficulty_level_numeric`: 數值型態 (1-6) - `cefr`: 文字型態 (A1, A2, B1, B2, C1, C2) --- ## 詳細檔案分析 ### 🔴 高優先級 - 需要立即修改 #### 1. `/frontend/hooks/flashcards/useFlashcardSearch.ts` **行號**: 20, 101, 190, 217, 219, 240, 242, 243, 295, 323, 427, 438 **問題描述**: - `SearchFilters` 介面仍使用 `difficultyLevel: string` - 客戶端篩選邏輯中使用 `(card as any).difficultyLevel` - 排序邏輯中使用 `difficultyLevel` 作為排序鍵 **關鍵程式碼**: ```typescript // 第20行 - 介面定義需要更新 export interface SearchFilters { search: string; difficultyLevel: string; // ❌ 需要改為 cefr partOfSpeech: string; masteryLevel: string; favoritesOnly: boolean; } // 第217-220行 - 篩選邏輯需要更新 if (state.filters.difficultyLevel) { allFlashcards = allFlashcards.filter(card => (card as any).difficultyLevel === state.filters.difficultyLevel // ❌ 需要改為 cefr ); } // 第240-244行 - 排序邏輯需要更新 case 'difficultyLevel': // ❌ 需要改為 'cefr' const levels = ['A1', 'A2', 'B1', 'B2', 'C1', 'C2']; aValue = levels.indexOf((a as any).difficultyLevel || 'A1'); // ❌ 需要改為 cefr bValue = levels.indexOf((b as any).difficultyLevel || 'A1'); // ❌ 需要改為 cefr break; ``` **建議修改**: 1. 將 `SearchFilters.difficultyLevel` 改為 `cefr` 2. 更新所有相關的狀態管理和篩選邏輯 3. 排序case從 `difficultyLevel` 改為 `cefr` **風險評估**: 🔴 高風險 - 影響搜尋和篩選核心功能 --- #### 2. `/frontend/hooks/review/useTestQueue.ts` **行號**: 60 **問題描述**: - 複習隊列邏輯中仍使用 `card.difficultyLevel` **關鍵程式碼**: ```typescript // 第60行 const wordCEFRLevel = card.difficultyLevel || 'A2' // ❌ 需要改為 card.cefr ``` **建議修改**: ```typescript const wordCEFRLevel = card.cefr || 'A2' ``` **風險評估**: 🔴 高風險 - 影響複習系統核心邏輯 --- #### 3. `/frontend/store/useTestQueueStore.ts` **行號**: 159 **問題描述**: - 測試隊列 Store 中使用 `card.difficultyLevel` **關鍵程式碼**: ```typescript // 第159行 const wordCEFRLevel = card.difficultyLevel || 'A2' // ❌ 需要改為 card.cefr ``` **建議修改**: ```typescript const wordCEFRLevel = card.cefr || 'A2' ``` **風險評估**: 🔴 高風險 - 影響狀態管理 --- #### 4. `/frontend/lib/services/flashcards.ts` **行號**: 246 **問題描述**: - 服務層中的向後相容性處理 **關鍵程式碼**: ```typescript // 第246行 - 目前有向後相容性處理 cefr: card.cefr || card.difficultyLevel || 'A2', // ✅ 已有向後相容處理 ``` **建議修改**: - 短期內保持現狀,確保向後相容 - 長期移除 `card.difficultyLevel` 的fallback **風險評估**: 🟡 中風險 - 目前已有向後相容處理 --- ### 🟡 中優先級 - 需要更新但影響較小 #### 5. `/frontend/components/generate/ClickableTextV2.tsx` **行號**: 26, 27, 124, 128, 307, 308 **問題描述**: - 介面定義和使用邏輯中仍使用 `difficultyLevel` **關鍵程式碼**: ```typescript // 第26-27行 - 介面定義 difficultyLevel: string // ❌ 需要改為 cefr difficultyLevelNumeric?: number // ✅ 可保留作為額外支援 // 第124行 - 取值邏輯 const difficultyLevel = getWordProperty(wordAnalysis, 'difficultyLevel') || 'A1' // ❌ // 第307-308行 - 顯示邏輯 getCEFRColor(getWordProperty(analysis[selectedWord], 'difficultyLevel')) // ❌ getWordProperty(analysis[selectedWord], 'difficultyLevel') // ❌ ``` **建議修改**: 1. 介面中 `difficultyLevel` 改為 `cefr` 2. 保留 `difficultyLevelNumeric` 作為數值支援 3. 更新所有 `getWordProperty` 調用 **風險評估**: 🟡 中風險 - 影響詞彙分析展示 --- #### 6. `/frontend/app/flashcards/page.tsx` **行號**: 372, 440, 441 **問題描述**: - 篩選 UI 中的選項值和狀態綁定 **關鍵程式碼**: ```typescript // 第372行 - 排序選項 // ❌ 需要改為 "cefr" // 第440-441行 - 篩選器綁定 value={searchState.filters.difficultyLevel} // ❌ onChange={(e) => searchActions.updateFilters({ difficultyLevel: e.target.value })} // ❌ ``` **建議修改**: 1. 排序選項值改為 `"cefr"` 2. 篩選器狀態綁定改為 `cefr` **風險評估**: 🟡 中風險 - 影響使用者介面 --- #### 7. `/frontend/app/generate/page.tsx` **行號**: 174, 176, 196, 547 **問題描述**: - 生成頁面中的詞彙分析處理 **關鍵程式碼**: ```typescript // 第174行 const difficultyLevel = wordData?.difficultyLevel || 'A1' // ❌ // 第196行 - 保存邏輯中的向後相容處理 const cefrValue = analysis.cefr || analysis.difficultyLevel || analysis.cefrLevel || analysis.CEFR || 'A0' // ⚠️ 需要檢查 // 第547行 - 顯示邏輯 {idiomPopup.analysis.difficultyLevel} // ❌ ``` **建議修改**: 1. 統一使用 `cefr` 欄位 2. 保留向後相容處理但優先使用新欄位 3. 更新顯示邏輯 **風險評估**: 🟡 中風險 - 影響詞彙生成功能 --- ### 🟢 低優先級 - 測試和模擬資料 #### 8. `/frontend/data/mockTestData.ts` **行號**: 15, 34 **問題描述**: - 模擬測試資料介面定義 **關鍵程式碼**: ```typescript // 第15行 - 介面定義 difficultyLevel: 'A1' | 'A2' | 'B1' | 'B2' | 'C1' | 'C2' // ❌ 建議改為 cefr // 第34行 - 資料轉換 difficultyLevel: card.difficultyLevel as 'A1' | 'A2' | 'B1' | 'B2' | 'C1' | 'C2', // ❌ ``` **建議修改**: 1. 介面中改為 `cefr` 2. 更新測試資料生成邏輯 **風險評估**: 🟢 低風險 - 僅影響測試環境 --- #### 9. `/frontend/components/review/` 相關檔案 **行號**: 多個測試組件 **問題描述**: - 複習測試組件中的 `difficultyLevel` 使用 **關鍵程式碼**: ```typescript // ReviewRunner.tsx 第269行 difficultyLevel: mockCard.difficultyLevel, // ❌ // TestHeader.tsx 第5, 11, 18行 difficultyLevel: string // ❌ 介面定義 difficultyLevel, // ❌ 參數 {difficultyLevel} // ❌ 顯示 ``` **建議修改**: 1. 更新所有介面定義 2. 統一改為使用 `cefr` **風險評估**: 🟢 低風險 - 主要影響複習 UI 顯示 --- ## 遷移計劃 ### 階段一:核心功能修復 (立即執行) 1. **修復 useFlashcardSearch.ts** - 更新 SearchFilters 介面 - 修改篩選和排序邏輯 2. **修復 useTestQueue.ts 和 useTestQueueStore.ts** - 統一使用 `cefr` 欄位 3. **更新 flashcards 頁面 UI** - 修改排序選項值 - 更新篩選器綁定 ### 階段二:UI 和顯示邏輯 (1週內) 1. **更新 ClickableTextV2 組件** - 修改介面定義 - 更新屬性讀取邏輯 2. **修復 generate 頁面** - 統一詞彙分析處理 - 保持向後相容性 ### 階段三:測試和清理 (2週內) 1. **更新測試資料和模擬資料** 2. **移除向後相容性程式碼** 3. **全面測試驗證** --- ## 風險評估摘要 | 風險等級 | 檔案數量 | 主要影響 | |---------|---------|---------| | 🔴 高風險 | 4 | 搜尋、篩選、複習核心功能 | | 🟡 中風險 | 3 | 使用者介面、詞彙生成 | | 🟢 低風險 | 4+ | 測試環境、顯示組件 | --- ## 實施建議 ### 立即執行 (當日) 1. 修復 `useFlashcardSearch.ts` 中的核心邏輯 2. 更新複習隊列相關檔案 3. 修改前端篩選 UI ### 一週內執行 1. 更新所有組件介面定義 2. 統一詞彙分析處理邏輯 3. 進行整合測試 ### 長期維護 1. 逐步移除向後相容性代碼 2. 完善類型定義 3. 建立自動化測試確保資料一致性 --- ## 總結 前端總共發現 **11個主要檔案** 需要修改,涉及 **30+個程式碼位置**。最關鍵的是搜尋篩選邏輯和複習系統,需要立即修復以確保功能正常運作。建議採用漸進式遷移策略,先修復核心功能,再逐步完善 UI 和測試環境。 --- ## 🎯 **執行結果更新** (2025-10-01 15:45) ### ✅ **遷移執行完成狀態 - 100% 完成** #### 🔴 高優先級項目 - **全部完成** 1. **useFlashcardSearch.ts** ✅ **完成** - SearchFilters介面: `difficultyLevel` → `cefr` - 篩選邏輯: `card.difficultyLevel` → `card.cefr` - 排序邏輯: `'difficultyLevel'` → `'cefr'` 2. **useTestQueue.ts & useTestQueueStore.ts** ✅ **完成** - 複習邏輯更新為使用 `card.cefr` 3. **flashcards.ts 服務層** ✅ **完成** - 移除向後相容代碼,統一使用 `cefr` #### 🟡 中優先級項目 - **全部完成** 4. **flashcards/page.tsx** ✅ **完成** - 篩選下拉選項: `difficultyLevel` → `cefr` - 篩選狀態綁定更新 5. **generate/page.tsx** ✅ **完成** - 詞彙分析邏輯更新 - 移除過時的 difficultyLevel 引用 6. **ClickableTextV2.tsx** ✅ **完成** - 介面定義更新為 `cefr` - 詞彙屬性讀取邏輯更新 #### 🟢 低優先級項目 - **全部完成** 7. **Review組件系列** ✅ **完成** - BaseTestComponent, ReviewRunner 等 - 統一使用 `cefr` 屬性 8. **測試資料檔案** ✅ **完成** - mockTestData.ts 結構更新 - 保持向後相容性 ### 📊 **最終統計** - **處理檔案數**: 11個 ✅ 全部完成 - **修復引用數**: 30+ ✅ 全部處理 - **編譯狀態**: ✅ **100%成功** - **類型安全**: ✅ **無錯誤** ### 🎉 **遷移狀態**: **100% 完成** **前端現在完全適應新的後端 CEFR 欄位結構,所有 difficulty_level 引用已成功遷移至統一的 cefr 欄位!** --- **執行完成時間**: 2025-10-01 15:45 **執行者**: Claude Code