# 詞彙生成與儲存系統規格 ## 系統概述 DramaLing詞彙學習系統是一個基於AI的英語詞彙學習平台,主要功能包括詞彙生成、智能分析、儲存管理和學習追蹤。系統採用前後端分離架構,前端使用Next.js 14,後端使用.NET 8 Web API,資料庫使用SQLite + Entity Framework Core。 ## 1. 詞彙生成功能規格 ### 1.1 句子分析功能 #### 核心特性 - **AI分析引擎**: 使用Google Gemini API進行句子深度分析 - **多層次分析**: 包含詞彙分析、語法檢查、整句翻譯 - **個人化適配**: 根據用戶英語程度(A1-C2)調整分析深度 - **智能快取**: 使用快取機制避免重複AI調用 - **使用量追蹤**: 追蹤用戶查詢使用量並實施限制 #### API端點 - **端點**: `POST /api/ai/analyze-sentence` - **功能**: 句子綜合分析 - **輸入參數** (AnalyzeSentenceRequest): ```json { "inputText": "string", // 用戶輸入的英文句子 (最多1000字元) "userLevel": "string", // 用戶英語程度 (A1-C2, 預設A2) "forceRefresh": boolean, // 是否強制重新分析 "analysisMode": "string" // 分析模式 ("full") } ``` - **回應格式**: ```json { "success": boolean, "data": { "wordAnalysis": { "[word]": { "word": "string", "translation": "string", "definition": "string", "partOfSpeech": "string", "pronunciation": "string", "isHighValue": boolean, "difficultyLevel": "string" // CEFR等級 } }, "sentenceMeaning": { "translation": "string", "explanation": "string" }, "grammarCorrection": { "hasErrors": boolean, "originalText": "string", "correctedText": "string", "corrections": [ { "errorType": "string", "original": "string", "corrected": "string", "reason": "string" } ] }, "finalAnalysisText": "string", "highValueWords": ["string"] } } ``` #### 快取機制 (SentenceAnalysisCache) - **表名**: `SentenceAnalysisCache` - **主要欄位**: ```csharp public class SentenceAnalysisCache { public Guid Id { get; set; } public string InputTextHash { get; set; } // SHA-256雜湊 public string InputText { get; set; } // 原始輸入文本 public string? CorrectedText { get; set; } // 修正後文本 public bool HasGrammarErrors { get; set; } // 是否有語法錯誤 public string? GrammarCorrections { get; set; } // JSON格式語法修正 public string AnalysisResult { get; set; } // JSON格式分析結果 public string? HighValueWords { get; set; } // JSON格式高價值詞彙 public string? PhrasesDetected { get; set; } // JSON格式檢測片語 public DateTime CreatedAt { get; set; } public DateTime ExpiresAt { get; set; } public int AccessCount { get; set; } // 存取次數 public DateTime? LastAccessedAt { get; set; } } ``` #### 實現位置 - **前端**: `frontend/app/generate/page.tsx:29-100` - **後端控制器**: `backend/DramaLing.Api/Controllers/AIController.cs` - **服務層**: `backend/DramaLing.Api/Services/GeminiService.cs` - **快取服務**: `backend/DramaLing.Api/Services/AnalysisCacheService.cs` ### 1.2 詞卡生成功能 #### 核心特性 - **智能萃取**: 支援詞彙萃取(vocabulary)和智能萃取(smart)兩種模式 - **批量生成**: 一次可生成1-20張詞卡 - **多元內容**: 包含單字、翻譯、定義、例句、同義詞、難度等級 - **測試模式**: 支援無認證的測試端點 #### API端點 - **端點**: `POST /api/ai/test/generate` (測試用,無需認證) - **功能**: 生成詞卡 - **輸入參數** (GenerateCardsRequest): ```json { "inputText": "string", // 原始文本 (最多5000字元) "extractionType": "string", // "vocabulary" | "smart" "cardCount": number // 1-20 } ``` - **回應格式**: ```json { "success": boolean, "data": { "taskId": "guid", "status": "completed", "generatedCards": [ { "word": "string", "translation": "string", "definition": "string", "partOfSpeech": "string", "pronunciation": "string", "example": "string", "exampleTranslation": "string", "synonyms": ["string"], "difficultyLevel": "string", "score": number // AI生成評分 } ] }, "message": "string" } ``` #### 實現位置 - **前端**: `frontend/app/generate/page.tsx:114-151` - **後端**: `backend/DramaLing.Api/Controllers/AIController.cs:42-100` ### 1.3 互動式詞彙查詢 #### 核心特性 - **點擊查詢**: 用戶可點擊句子中任意單字查看詳細資訊 - **即時分析**: 動態調用AI API獲取單字分析 - **高價值標示**: 自動標示高價值單字和片語 - **使用量計費**: 區分高價值(免費)和低價值(計費)詞彙 #### API端點 - **端點**: `POST /api/ai/query-word` - **輸入參數** (QueryWordRequest): ```json { "word": "string", // 要查詢的單字 "sentence": "string", // 上下文句子 "analysisId": "guid?" // 分析ID (可選) } ``` #### 使用量統計 (WordQueryUsageStats) - **表名**: `WordQueryUsageStats` - **主要欄位**: ```csharp public class WordQueryUsageStats { public Guid Id { get; set; } public Guid UserId { get; set; } public DateOnly Date { get; set; } // 日期 public int SentenceAnalysisCount { get; set; } // 句子分析次數 public int HighValueWordClicks { get; set; } // 高價值詞彙點擊(免費) public int LowValueWordClicks { get; set; } // 低價值詞彙點擊(收費) public int TotalApiCalls { get; set; } // 總API調用次數 public int UniqueWordsQueried { get; set; } // 查詢的獨特詞彙數 public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } } ``` #### 實現位置 - **組件**: `frontend/components/ClickableTextV2.tsx` - **前端邏輯**: `frontend/app/generate/page.tsx:402-421` - **使用量服務**: `backend/DramaLing.Api/Services/UsageTrackingService.cs` ## 2. 詞彙儲存系統規格 ### 2.1 資料庫架構 #### 2.1.1 用戶管理 (User) - **表名**: `user_profiles` - **主要欄位**: ```csharp public class User { public Guid Id { get; set; } public string Username { get; set; } // 用戶名 (唯一) public string Email { get; set; } // 信箱 (唯一) public string PasswordHash { get; set; } // 密碼雜湊 public string? DisplayName { get; set; } // 顯示名稱 public string? AvatarUrl { get; set; } // 頭像URL public string SubscriptionType { get; set; } = "free"; // 訂閱類型 public Dictionary Preferences { get; set; } // JSON偏好設定 // 個人化學習相關 public string EnglishLevel { get; set; } = "A2"; // 英語程度(A1-C2) public DateTime LevelUpdatedAt { get; set; } // 程度更新時間 public bool IsLevelVerified { get; set; } = false; // 是否通過測試驗證 public string? LevelNotes { get; set; } // 程度設定備註 public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } } ``` #### 2.1.2 詞卡實體 (Flashcard) - **表名**: `flashcards` - **主要欄位**: ```csharp public class Flashcard { public Guid Id { get; set; } public Guid UserId { get; set; } // 所屬用戶 public Guid CardSetId { get; set; } // 所屬卡組 // 詞卡內容 [Required, MaxLength(255)] public string Word { get; set; } // 單字 [Required] public string Translation { get; set; } // 翻譯 [Required] public string Definition { get; set; } // 定義 [MaxLength(50)] public string? PartOfSpeech { get; set; } // 詞性 [MaxLength(255)] public string? Pronunciation { get; set; } // 發音 public string? Example { get; set; } // 例句 public string? ExampleTranslation { get; set; } // 例句翻譯 // SM-2 間隔重複算法參數 public float EasinessFactor { get; set; } = 2.5f; // 難易度係數 public int Repetitions { get; set; } = 0; // 重複次數 public int IntervalDays { get; set; } = 1; // 間隔天數 public DateTime NextReviewDate { get; set; } // 下次複習日期 // 學習統計 [Range(0, 100)] public int MasteryLevel { get; set; } = 0; // 掌握程度(0-100) public int TimesReviewed { get; set; } = 0; // 複習次數 public int TimesCorrect { get; set; } = 0; // 正確次數 public DateTime? LastReviewedAt { get; set; } // 最後複習時間 // 狀態管理 public bool IsFavorite { get; set; } = false; // 是否收藏 public bool IsArchived { get; set; } = false; // 是否封存 [MaxLength(10)] public string? DifficultyLevel { get; set; } // 難度等級(A1-C2) public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } } ``` #### 2.1.3 卡組實體 (CardSet) - **表名**: `card_sets` - **主要欄位**: ```csharp public class CardSet { public Guid Id { get; set; } public Guid UserId { get; set; } // 所屬用戶 [Required, MaxLength(255)] public string Name { get; set; } // 卡組名稱 public string? Description { get; set; } // 描述 [MaxLength(50)] public string Color { get; set; } = "bg-blue-500"; // 顏色標籤 public int CardCount { get; set; } = 0; // 詞卡數量 public bool IsDefault { get; set; } = false; // 是否為預設卡組 public DateTime CreatedAt { get; set; } public DateTime UpdatedAt { get; set; } } ``` #### 2.1.4 標籤系統 (Tag & FlashcardTag) - **表名**: `tags`, `flashcard_tags` - **主要欄位**: ```csharp public class Tag { public Guid Id { get; set; } public Guid UserId { get; set; } [Required, MaxLength(100)] public string Name { get; set; } // 標籤名稱 [Required, MaxLength(50)] public string Color { get; set; } // 標籤顏色 public int UsageCount { get; set; } = 0; // 使用次數 public DateTime CreatedAt { get; set; } } public class FlashcardTag // 多對多關聯表 { public Guid FlashcardId { get; set; } public Guid TagId { get; set; } } ``` #### 2.1.5 學習追蹤 (StudySession & StudyRecord) - **表名**: `study_sessions`, `study_records` - **主要欄位**: ```csharp public class StudySession { public Guid Id { get; set; } public Guid UserId { get; set; } [Required, MaxLength(50)] public string SessionType { get; set; } // 學習模式 public DateTime StartedAt { get; set; } // 開始時間 public DateTime? EndedAt { get; set; } // 結束時間 public int TotalCards { get; set; } = 0; // 總詞卡數 public int CorrectCount { get; set; } = 0; // 正確數量 public int DurationSeconds { get; set; } = 0; // 持續時間(秒) public int AverageResponseTimeMs { get; set; } = 0; // 平均回應時間(毫秒) } public class StudyRecord { public Guid Id { get; set; } public Guid UserId { get; set; } public Guid FlashcardId { get; set; } public Guid SessionId { get; set; } [Required, MaxLength(50)] public string StudyMode { get; set; } // 學習模式 public int QualityRating { get; set; } // 品質評分(0-5) public int? ResponseTimeMs { get; set; } // 回應時間(毫秒) public string? UserAnswer { get; set; } // 用戶答案 public bool IsCorrect { get; set; } // 是否正確 public DateTime StudiedAt { get; set; } // 學習時間 // SM-2算法歷史記錄 public float PreviousEasinessFactor { get; set; } public int PreviousRepetitions { get; set; } public int PreviousIntervalDays { get; set; } public float NewEasinessFactor { get; set; } public int NewRepetitions { get; set; } public int NewIntervalDays { get; set; } public DateTime NextReviewDate { get; set; } } ``` #### 2.1.6 錯誤回報 (ErrorReport) - **表名**: `error_reports` - **主要欄位**: ```csharp public class ErrorReport { public Guid Id { get; set; } public Guid UserId { get; set; } public Guid FlashcardId { get; set; } [Required, MaxLength(100)] public string ReportType { get; set; } // 錯誤類型 public string? Description { get; set; } // 描述 [MaxLength(50)] public string? StudyMode { get; set; } // 學習模式 [Required, MaxLength(50)] public string Status { get; set; } = "pending"; // 狀態 public string? AdminNotes { get; set; } // 管理員備註 public Guid? ResolvedBy { get; set; } // 解決者ID public DateTime? ResolvedAt { get; set; } // 解決時間 public DateTime CreatedAt { get; set; } } ``` #### 2.1.7 每日統計 (DailyStats) - **表名**: `daily_stats` - **主要欄位**: ```csharp public class DailyStats { public Guid Id { get; set; } public Guid UserId { get; set; } public DateOnly Date { get; set; } // 日期 public int WordsStudied { get; set; } = 0; // 學習單字數 public int WordsCorrect { get; set; } = 0; // 正確單字數 public int StudyTimeSeconds { get; set; } = 0; // 學習時間(秒) public int SessionCount { get; set; } = 0; // 學習場次 public int CardsGenerated { get; set; } = 0; // 生成詞卡數 public int AiApiCalls { get; set; } = 0; // AI API調用次數 public DateTime CreatedAt { get; set; } } ``` ### 2.2 儲存服務API #### 2.2.1 詞卡管理API - **取得詞卡列表**: `GET /api/flashcards` - **查詢參數**: - `setId` (Guid?): 指定卡組ID - `search` (string?): 搜尋關鍵字(詞彙/翻譯) - `favoritesOnly` (bool): 僅顯示收藏 - `limit` (int): 限制數量(預設50,最多100) - `offset` (int): 偏移量(分頁用) - **回應格式**: ```json { "success": true, "data": { "flashcards": [...], "total": number, "hasMore": boolean } } ``` - **實現位置**: `FlashcardsController.cs:58-135` - **建立詞卡**: `POST /api/flashcards` - **請求體** (CreateFlashcardRequest): ```json { "cardSetId": "guid?", // 可選,未指定則使用預設卡組 "word": "string", // 必填 "translation": "string", // 必填 "definition": "string", // 必填 "partOfSpeech": "string?", "pronunciation": "string?", "example": "string?", "exampleTranslation": "string?" } ``` - **自動功能**: 如無指定卡組,自動分配到預設卡組或創建新的預設卡組 - **實現位置**: `FlashcardsController.cs:137-200` - **更新詞卡**: `PUT /api/flashcards/{id}` - **請求體** (UpdateFlashcardRequest): 支援部分欄位更新 - **實現位置**: `FlashcardsController.cs:233-287` - **刪除詞卡**: `DELETE /api/flashcards/{id}` - **實現位置**: `FlashcardsController.cs:289-324` - **切換收藏狀態**: `POST /api/flashcards/{id}/favorite` - **功能**: 切換詞卡的收藏狀態 #### 2.2.2 卡組管理API - **取得卡組列表**: `GET /api/cardsets` - **回應**: 包含卡組基本資訊和詞卡數量統計 - **建立卡組**: `POST /api/cardsets` - **請求體** (CreateCardSetRequest): ```json { "name": "string", // 必填 "description": "string?", // 可選 "isPublic": boolean // 可選,預設false } ``` - **更新卡組**: `PUT /api/cardsets/{id}` - **請求體** (UpdateCardSetRequest): 支援部分欄位更新 - **刪除卡組**: `DELETE /api/cardsets/{id}` - **限制**: 無法刪除預設卡組 - **確保預設卡組**: `POST /api/cardsets/ensure-default` - **功能**: 確保用戶有預設卡組,如無則自動創建 #### 2.2.3 前端服務層 - **檔案位置**: `frontend/lib/services/flashcards.ts` - **核心介面**: ```typescript export interface Flashcard { id: string; word: string; translation: string; definition: string; partOfSpeech: string; pronunciation: string; example: string; exampleTranslation?: string; masteryLevel: number; // 0-100掌握程度 timesReviewed: number; // 複習次數 isFavorite: boolean; // 是否收藏 nextReviewDate: string; // 下次複習日期 createdAt: string; cardSet: { name: string; color: string; }; } export interface CardSet { id: string; name: string; description: string; color: string; cardCount: number; // 詞卡數量 createdAt: string; updatedAt: string; isDefault: boolean; // 是否為預設卡組 progress: number; // 學習進度 lastStudied: string; // 最後學習時間 tags: string[]; // 標籤 } class FlashcardsService { // 詞卡CRUD操作 async getFlashcards(cardSetId?: string): Promise> async createFlashcard(data: CreateFlashcardRequest): Promise> async updateFlashcard(id: string, data: Partial): Promise> async deleteFlashcard(id: string): Promise> async toggleFavorite(id: string): Promise> // 卡組CRUD操作 async getCardSets(): Promise> async createCardSet(data: CreateCardSetRequest): Promise> async deleteCardSet(id: string): Promise> async ensureDefaultCardSet(): Promise> } ``` #### 2.2.4 資料庫關聯與索引 - **外鍵關聯**: - `flashcards.user_id` → `user_profiles.id` (CASCADE) - `flashcards.card_set_id` → `card_sets.id` (CASCADE) - `card_sets.user_id` → `user_profiles.id` (CASCADE) - `flashcard_tags.flashcard_id` → `flashcards.id` (CASCADE) - `flashcard_tags.tag_id` → `tags.id` (CASCADE) - **重要索引**: - `user_profiles`: email(UNIQUE), username(UNIQUE) - `flashcards`: user_id, card_set_id - `card_sets`: user_id - `tags`: user_id - `daily_stats`: (user_id, date)(UNIQUE) - `SentenceAnalysisCache`: input_text_hash(UNIQUE), expires_at ## 3. 系統整合流程 ### 3.1 完整學習流程 1. **用戶認證** → JWT Token驗證與用戶程度讀取 2. **句子輸入** → 用戶在生成頁面輸入英文句子(最多300字元) 3. **快取檢查** → 檢查是否已有分析結果快取 4. **AI分析** → 調用Gemini API進行句子深度分析 5. **結果快取** → 將分析結果儲存到`SentenceAnalysisCache` 6. **互動探索** → 用戶點擊單字查看詳細分析(使用量追蹤) 7. **詞卡生成** → 基於分析結果生成個人化詞卡 8. **儲存管理** → 詞卡儲存到預設或指定卡組 9. **學習追蹤** → 使用SM-2算法追蹤學習進度 ### 3.2 資料流向圖 ``` 用戶請求 → JWT認證 → 程度檢查 → 輸入驗證 → 快取檢查 → AI API調用 ↓ 結果快取 → 使用量記錄 → 前端顯示 → 用戶互動 → 詞卡生成 → 資料庫儲存 ↓ 學習記錄 → SM-2更新 → 統計更新 → 進度追蹤 ``` ### 3.3 關鍵業務邏輯 #### 3.3.1 預設卡組管理 - 用戶首次創建詞卡時,系統自動創建名為「未分類」的預設卡組 - 預設卡組無法刪除,確保用戶始終有存放詞卡的地方 - 實現位置: `FlashcardsController.cs:33-56` #### 3.3.2 SM-2間隔重複算法 - 基於用戶答題品質(0-5分)調整複習間隔 - 記錄詳細的學習歷史用於算法優化 - 實現位置: `backend/DramaLing.Api/Services/SM2Algorithm.cs` #### 3.3.3 使用量限制機制 - 免費用戶3小時內最多5次句子分析 - 高價值詞彙點擊免費,低價值詞彙計費 - 實現位置: `UsageTrackingService.cs` ## 4. 技術架構 ### 4.1 前端技術棧 - **框架**: Next.js 14 (App Router) - **語言**: TypeScript - **樣式**: Tailwind CSS - **狀態管理**: React Hooks + Context API - **HTTP客戶端**: Fetch API - **認證**: JWT + localStorage - **路由保護**: ProtectedRoute組件 ### 4.2 後端技術棧 - **框架**: .NET 8 Web API - **ORM**: Entity Framework Core 8.0 - **資料庫**: SQLite (開發) - **認證**: JWT Bearer Token - **AI服務**: Google Gemini API - **快取**: 內建EF快取 + 自定義快取服務 - **日誌**: Microsoft.Extensions.Logging ### 4.3 資料庫設計特點 - **Snake_case命名**: 所有資料表和欄位使用snake_case - **GUID主鍵**: 所有實體使用Guid作為主鍵 - **軟刪除**: 支援IsArchived標記而非硬刪除 - **審計欄位**: CreatedAt、UpdatedAt自動管理 - **JSON欄位**: 使用JSON存儲複雜結構(如Preferences) ### 4.4 API設計原則 - **RESTful風格**: 遵循REST慣例 - **統一回應格式**: ```json { "success": boolean, "data": object, "error": string, "message": string, "timestamp": datetime } ``` - **認證保護**: 所有業務API需JWT認證 - **錯誤處理**: 統一錯誤處理中間件 - **請求驗證**: DataAnnotations + 自定義驗證 - **分頁支援**: 統一的limit/offset分頁機制 ## 5. 效能與優化 ### 5.1 快取策略 - **句子分析快取**: - 使用SHA-256雜湊避重 - 設定過期時間(ExpiresAt) - 記錄存取次數和最後存取時間 - **詞彙查詢快取**: - 減少重複AI API調用 - 提升查詞響應速度 - **清理機制**: - 定期清理過期快取 - 實現位置: `CacheCleanupService.cs` ### 5.2 效能監控 - **日常統計**: DailyStats記錄用戶活動指標 - **使用量追蹤**: WordQueryUsageStats追蹤API使用 - **錯誤報告**: ErrorReport系統收集問題回饋 ### 5.3 限制與配額 - **免費用戶限制**: - 句子分析: 3小時內最多5次 - 手動輸入: 最多300字元 - 詞卡生成: 一次最多20張 - **付費用戶**: 無限制使用 - **API速率限制**: 防止濫用攻擊 ## 6. 安全性考量 ### 6.1 認證與授權 - **JWT Token**: 包含用戶ID和過期時間 - **用戶隔離**: 所有資料按UserId嚴格隔離 - **端點保護**: [Authorize]屬性保護敏感API - **測試端點**: 部分功能提供[AllowAnonymous]測試 ### 6.2 資料安全 - **密碼安全**: BCrypt雜湊儲存 - **輸入驗證**: 前後端雙重驗證 - **SQL注入防護**: EF Core參數化查詢 - **XSS防護**: 自動HTML編碼 ### 6.3 API安全 - **CORS設定**: 限制來源域名 - **請求大小限制**: 防止大檔案攻擊 - **錯誤資訊隱藏**: 生產環境隱藏敏感錯誤 ## 7. 監控與維護 ### 7.1 系統監控 - **健康檢查**: API健康狀態監控 - **效能指標**: 回應時間、吞吐量追蹤 - **錯誤追蹤**: 異常日誌和錯誤報告 - **資源監控**: 資料庫和儲存空間監控 ### 7.2 維護策略 - **資料備份**: 定期資料庫備份機制 - **日誌清理**: 定期清理舊日誌和快取 - **版本控制**: Git版本管理和部署追蹤 - **文件更新**: 與程式碼同步更新文件 ## 8. 未來擴展規劃 ### 8.1 短期功能擴展 - **語音功能**: 整合Azure Speech Service - **個人化推薦**: 基於學習歷史的智能推薦 - **社群功能**: 卡組分享和協作學習 - **多語言支援**: 擴展到其他語言學習 ### 8.2 技術架構升級 - **資料庫升級**: 從SQLite遷移到PostgreSQL - **快取優化**: 引入Redis分散式快取 - **微服務化**: 拆分AI服務和業務服務 - **容器化部署**: Docker + Kubernetes部署 ### 8.3 擴展性考量 - **水平擴展**: 支援多實例負載平衡 - **資料分割**: 大規模用戶資料分割策略 - **CDN整合**: 靜態資源和多媒體加速 - **國際化**: 多地區部署和資料同步 --- **文件版本**: 2.0 **最後更新**: 2025-09-20 **維護者**: DramaLing開發團隊 **更新說明**: 基於實際程式碼架構重新整理,修正與系統實現的差距