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