6.0 KiB
6.0 KiB
智能複習系統 - 技術規格書 (TSD)
目標讀者: 後端開發工程師、系統架構師 版本: 1.0 日期: 2025-09-25
🏗️ 系統架構
核心服務
┌─────────────────────┐
│ 復習記錄 API │
└─────────┬───────────┘
│
┌─────▼─────┐
│ 輸入驗證層 │
└─────┬─────┘
│
┌───────▼────────┐
│ SpacedRepetition │
│ Service │
│ ┌─────────────┐ │
│ │ 逾期檢測 │ │
│ │ 間隔計算 │ │
│ │ 熟悉度更新 │ │
│ └─────────────┘ │
└───────┬────────┘
│
┌─────▼─────┐
│ 數據持久化 │
└───────────┘
關鍵類別設計
SpacedRepetitionService
public class SpacedRepetitionService
{
public ReviewResult ProcessReview(ReviewRequest request)
{
// 1. 計算逾期天數 (明確時間基準)
var actualReviewDate = DateTime.Now.Date; // 復習行為當日
var overdueDays = (actualReviewDate - request.NextReviewDate.Date).Days;
// 2. 應用記憶衰減
var adjustedMastery = ApplyMemoryDecay(request.CurrentMastery, overdueDays);
// 3. 計算新間隔
var newInterval = CalculateNewInterval(
request.CurrentInterval,
request.IsCorrect,
request.ConfidenceLevel,
overdueDays
);
// 4. 更新熟悉程度
var newMastery = CalculateMasteryLevel(
request.TimesCorrect + (request.IsCorrect ? 1 : 0),
request.TotalReviews + 1,
newInterval
);
return new ReviewResult
{
NewInterval = newInterval,
NextReviewDate = actualReviewDate.AddDays(newInterval), // 以復習當日為基準
MasteryLevel = newMastery,
IsOverdue = overdueDays > 0,
OverdueDays = Math.Max(0, overdueDays)
};
}
}
🔌 API 設計
POST /api/flashcards/{id}/review
請求格式
{
"isCorrect": boolean,
"confidenceLevel": number, // 1-5, 翻卡題必須
"questionType": "flipcard" | "multiple_choice" | "fill_blank"
}
響應格式
{
"success": true,
"data": {
"newInterval": 15,
"nextReviewDate": "2025-10-10",
"masteryLevel": 65,
"isOverdue": false,
"overdueDays": 0
}
}
錯誤響應
{
"success": false,
"error": {
"code": "VALUE_OUT_OF_RANGE",
"message": "信心程度必須在 1-5 範圍內",
"field": "confidenceLevel"
}
}
🛡️ 安全與驗證
輸入驗證規則
public class ReviewRequestValidator : AbstractValidator<ReviewRequest>
{
public ReviewRequestValidator()
{
RuleFor(x => x.IsCorrect).NotNull();
RuleFor(x => x.ConfidenceLevel)
.InclusiveBetween(1, 5)
.When(x => x.QuestionType == "flipcard");
RuleFor(x => x.QuestionType)
.Must(BeValidQuestionType)
.WithMessage("questionType 必須是 flipcard, multiple_choice 或 fill_blank");
}
}
錯誤處理策略
- 4xx 錯誤: 客戶端輸入錯誤,返回詳細錯誤訊息
- 5xx 錯誤: 服務器錯誤,記錄日誌並返回通用錯誤訊息
- 資料庫錯誤: 重試機制,最多3次重試
💾 資料庫設計
資料表更新
-- 現有 Flashcards 表需要的欄位
ALTER TABLE Flashcards ADD COLUMN
LastReviewDate DATETIME, -- 上次實際復習日期
OverdueCount INT DEFAULT 0, -- 逾期次數統計
ConsecutiveOverdue INT DEFAULT 0; -- 連續逾期次數
索引優化
-- 提升查詢到期詞卡的性能
CREATE INDEX IX_Flashcards_NextReviewDate
ON Flashcards(NextReviewDate, UserId);
-- 提升逾期統計查詢性能
CREATE INDEX IX_Flashcards_OverdueStats
ON Flashcards(LastReviewDate, NextReviewDate);
⚙️ 配置管理
appsettings.json 配置
{
"SpacedRepetition": {
"GrowthFactors": {
"ShortTerm": 1.8,
"MediumTerm": 1.4,
"LongTerm": 1.2,
"VeryLongTerm": 1.1
},
"OverduePenalties": {
"Light": 0.9, // 1-3天
"Medium": 0.75, // 4-7天
"Heavy": 0.5, // 8-30天
"Extreme": 0.3 // >30天
},
"MemoryDecayRate": 0.05, // 每天5%衰減
"MaxInterval": 365
}
}
🔍 監控與日誌
關鍵指標監控
public class ReviewMetrics
{
[Counter("reviews_processed_total")]
public static readonly Counter ReviewsProcessed;
[Histogram("review_calculation_duration_ms")]
public static readonly Histogram CalculationDuration;
[Gauge("overdue_reviews_current")]
public static readonly Gauge OverdueReviews;
}
日誌記錄
- INFO: 正常復習記錄
- WARN: 逾期復習、異常參數
- ERROR: 計算失敗、資料庫錯誤
🚀 部署需求
性能要求
- API 響應時間: P95 < 100ms
- 並發處理: 支援 1000+ 同時用戶
- 資料庫連線: 連線池最大 50 連線
環境配置
- .NET 8+ 運行環境
- SQLite/PostgreSQL 資料庫
- Memory/Redis 緩存 (可選)
部署檢查清單
- 資料庫遷移腳本執行
- 配置文件更新
- 監控指標接入
- 日誌收集配置
- 性能測試通過
實施時間: 2-3個工作日 測試時間: 1個工作日 上線影響: 零停機時間部署