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