7.1 KiB
7.1 KiB
移除冗餘UserLevel/WordLevel欄位和程式碼計劃
🎯 目標
徹底移除冗餘的數值欄位,簡化資料庫結構,實現純CEFR字符串架構,消除資料重複問題。
📊 現況分析
重複資料確認
-- 用戶程度重複存儲 ❌
users.english_level: "A2" (主要,標準CEFR)
flashcards.UserLevel: 50 (冗餘,數值緩存)
-- 詞彙難度重複存儲 ❌
flashcards.difficulty_level: "A2" (主要,標準CEFR)
flashcards.WordLevel: 35 (冗餘,數值緩存)
冗餘程度評估
- 智能選擇: ✅ 已改為即時CEFR轉換,不使用存儲數值
- 四情境判斷: ✅ 使用即時轉換的數值進行運算
- API回應: ⚠️ 仍包含數值欄位(僅為前端相容)
- 舊資料處理: ⚠️ 防止數值為0的初始化邏輯
📋 詳細移除計劃
Phase 1: 後端資料庫和模型清理 ⏱️ 1天
1.1 創建資料庫遷移
cd backend/DramaLing.Api
dotnet ef migrations add RemoveRedundantLevelFields
Migration內容:
ALTER TABLE flashcards DROP COLUMN UserLevel;
ALTER TABLE flashcards DROP COLUMN WordLevel;
1.2 更新Flashcard模型
檔案: Models/Entities/Flashcard.cs
// 移除這兩個屬性:
// [Range(1, 100)]
// public int UserLevel { get; set; } = 50;
//
// [Range(1, 100)]
// public int WordLevel { get; set; } = 50;
1.3 清理配置選項
檔案: appsettings.json
{
"SpacedRepetition": {
// 移除 "DefaultUserLevel": 50
}
}
檔案: Models/Configuration/SpacedRepetitionOptions.cs
// 移除 DefaultUserLevel 屬性
Phase 2: 後端API和服務清理 ⏱️ 1天
2.1 清理FlashcardsController
檔案: Controllers/FlashcardsController.cs
移除數值欄位初始化:
// 移除 lines 508-512:
// if (nextCard.UserLevel == 0)
// nextCard.UserLevel = CEFRMappingService.GetDefaultUserLevel();
// if (nextCard.WordLevel == 0)
// nextCard.WordLevel = CEFRMappingService.GetWordLevel(nextCard.DifficultyLevel);
簡化API回應:
var response = new
{
// 移除 nextCard.UserLevel, nextCard.WordLevel
// 保留 nextCard.DifficultyLevel (CEFR字符串)
};
2.2 清理SpacedRepetitionService
檔案: Services/SpacedRepetitionService.cs
移除批量初始化邏輯:
// 移除 lines 141-149:
// foreach (var card in dueCards.Where(c => c.WordLevel == 0))
// {
// card.WordLevel = CEFRMappingService.GetWordLevel(card.DifficultyLevel);
// if (card.UserLevel == 0)
// card.UserLevel = _options.DefaultUserLevel;
// }
2.3 清理QuestionGeneratorService
檔案: Services/QuestionGeneratorService.cs
移除數值版本的方法 (如果存在):
// 檢查並移除任何直接使用數值參數的方法
Phase 3: 前端適配調整 ⏱️ 0.5天
3.1 更新前端API服務
檔案: frontend/lib/services/flashcards.ts
移除數值欄位映射:
const flashcards = response.data.map((card: any) => ({
// 移除這兩行:
// userLevel: card.userLevel || 50,
// wordLevel: card.wordLevel || 50,
}));
3.2 更新前端接口定義
檔案: frontend/app/learn/page.tsx
簡化ExtendedFlashcard:
interface ExtendedFlashcard extends Omit<Flashcard, 'nextReviewDate'> {
// 移除:
// userLevel?: number;
// wordLevel?: number;
nextReviewDate?: string;
// ...其他實際需要的欄位
}
3.3 更新前端顯示邏輯
全部改為CEFR字符串邏輯:
// 不再使用 currentCard.userLevel, currentCard.wordLevel
// 改為:
const userCEFR = localStorage.getItem('userEnglishLevel') || 'A2';
const wordCEFR = currentCard.difficultyLevel || 'A2';
Phase 4: API接口純化 ⏱️ 0.5天
4.1 移除API回應中的數值欄位
所有相關API端點:
GET /flashcards/dueGET /flashcards/next-reviewGET /flashcards/{id}
移除回應中的:
{
// 移除 "userLevel": 50,
// 移除 "wordLevel": 35,
"difficultyLevel": "A2" // 保留CEFR字符串
}
4.2 更新API文檔
- 移除數值欄位的相關描述
- 更新為純CEFR架構文檔
Phase 5: 測試和驗證 ⏱️ 0.5天
5.1 功能測試清單
- 智能複習選擇功能正常
- 四情境判斷邏輯正確
- 前端顯示完全正常
- CEFR等級轉換準確
- 新詞卡創建和更新正常
5.2 性能測試
- API回應時間無明顯變化
- 智能選擇速度正常
- 前端載入速度正常
5.3 回歸測試
- 學習頁面完整流程
- 詞卡管理功能正常
- 所有播放按鈕正常
🗂️ 檔案修改清單
後端檔案 (5個主要檔案)
Models/Entities/Flashcard.cs- 移除數值屬性Controllers/FlashcardsController.cs- 移除初始化和回應邏輯Services/SpacedRepetitionService.cs- 移除批量初始化Models/Configuration/SpacedRepetitionOptions.cs- 移除配置appsettings.json- 移除配置項
前端檔案 (3個主要檔案)
lib/services/flashcards.ts- 移除數值映射app/learn/page.tsx- 更新接口和邏輯components/review/ReviewTypeIndicator.tsx- 移除數值依賴
資料庫遷移 (1個檔案)
- 新的migration檔案 - DROP COLUMN指令
📈 預期效益
資料庫優化
- ✅ 移除2個冗餘INT欄位
- ✅ 消除資料同步負擔
- ✅ 減少儲存空間使用
- ✅ 簡化資料庫結構
程式碼簡化
- ✅ 移除~50行冗餘程式碼
- ✅ 消除資料同步邏輯
- ✅ 統一CEFR處理流程
- ✅ 提升程式碼可讀性
架構純化
- ✅ 純CEFR標準架構
- ✅ 符合資料庫正規化原則
- ✅ 消除資料重複問題
- ✅ 降低維護複雜度
⚠️ 風險管理
風險等級: 🟢 低風險
- CEFR轉換邏輯已穩定運行
- 即時轉換性能優異
- 不影響用戶體驗
緩解措施
- 保留migration回滾腳本
- 分階段實施,逐步驗證
- 保持完整測試覆蓋
- 監控性能指標
回滾計劃
如有問題可快速回滾:
-- 回滾migration恢復欄位
dotnet ef database update PreviousMigration
🚀 實施建議
推薦立即實施
- 技術債務清理: 消除設計上的冗餘
- 標準化架構: 完全符合CEFR國際標準
- 長期維護: 降低未來開發和維護成本
- 代碼品質: 提升整體架構清潔度
實施順序
- 後端清理 → 前端適配 → 測試驗證
- 可隨時暫停,每個階段都有明確的檢查點
- 出現問題立即回滾,影響可控
建議:開始實施此清理計劃,徹底解決資料重複問題! 🎯