dramaling-vocab-learning/note/spec/AI_VOCABULARY_API_DOCUMENTA...

27 KiB
Raw Blame History

🤖 DramaLing AI 功能 - 後端 API 完整文檔

專案: DramaLing 英語學習平台 功能: AI 智能分析與詞卡生成系統 文檔版本: v1.1 最後更新: 2025-01-18


📋 功能概述

DramaLing AI 功能包含兩大核心系統:

  1. 句子分析系統: 提供整句翻譯、語法修正和詞彙分析
  2. 詞卡生成系統: 透過 AI 分析文本自動生成學習詞卡

兩系統都整合 Google Gemini AI提供高品質的英語學習分析。

🎯 主要特點

  • 智能分析: 使用 Google Gemini AI 進行文本分析
  • 雙重模式: 支援基本詞彙和智能萃取
  • 完整資訊: 包含音標、例句、同義詞、CEFR等級
  • 安全驗證: JWT認證和輸入驗證
  • 錯誤處理: 完善的例外處理和回退機制
  • 批量操作: 支援一次生成多張詞卡

📁 核心檔案架構

backend/DramaLing.Api/
├── Controllers/
│   └── AIController.cs           # API 端點控制器
├── Services/
│   └── GeminiService.cs          # AI 服務整合
├── Models/
│   └── Entities/
│       ├── Flashcard.cs          # 詞卡資料模型
│       └── CardSet.cs            # 詞卡集合模型
└── Data/
    └── DramaLingDbContext.cs     # 資料庫上下文

🔗 API 端點列表

🎯 A. 句子分析系統

1. 📝 句子分析 (整句意思生成) [AllowAnonymous]

POST /api/ai/analyze-sentence
Content-Type: application/json

{
  "inputText": "Hello world",
  "forceRefresh": false,
  "analysisMode": "full"
}

功能:

  • 整句翻譯: 自然流暢的繁體中文翻譯
  • 詳細解釋: 語法結構、詞彙特點、使用場景分析
  • 語法修正: 檢測並修正語法錯誤
  • 詞彙分析: 每個單字的詳細資訊
  • 高價值標記: 標記學習價值高的詞彙

回應範例:

{
  "success": true,
  "data": {
    "analysisId": "a063fb12-b28f-4df8-af4f-eeb2d43fd9c4",
    "inputText": "Hello world",
    "grammarCorrection": {
      "hasErrors": false,
      "originalText": "Hello world",
      "correctedText": "",
      "corrections": []
    },
    "sentenceMeaning": {
      "translation": "你好,世界",
      "explanation": "這個句子是程式設計中最經典的入門程式碼,也是學習任何程式語言的第一個練習。語法結構非常簡單,主語是隱含的,謂語是 'Hello',賓語是 'world'。"
    },
    "finalAnalysisText": "Hello world",
    "wordAnalysis": {
      "Hello": {
        "word": "Hello",
        "translation": "你好",
        "definition": "used as a greeting or to begin a phone conversation",
        "partOfSpeech": "interjection",
        "pronunciation": "/həˈloʊ/",
        "isHighValue": true,
        "difficultyLevel": "A1"
      },
      "world": {
        "word": "world",
        "translation": "世界",
        "definition": "the earth, together with all of its countries and peoples",
        "partOfSpeech": "noun",
        "pronunciation": "/wɜːrld/",
        "isHighValue": true,
        "difficultyLevel": "A1"
      }
    },
    "highValueWords": ["Hello", "world"],
    "phrasesDetected": []
  },
  "message": "AI句子分析完成",
  "cached": false,
  "cacheHit": false,
  "usingAI": true
}

特點:

  • 🔄 智能快取: 24小時快取機制提升回應速度
  • 🛡️ 回退機制: AI 失敗時使用本地分析
  • 📊 使用統計: 記錄分析次數(目前已暫時關閉限制)

2. 🔍 互動式單字查詢 [AllowAnonymous]

POST /api/ai/query-word
Content-Type: application/json

{
  "word": "beautiful",
  "sentence": "The weather is beautiful today"
}

功能: 在句子語境中分析特定單字 回應: 包含詞彙詳細資訊和語境分析


🎯 B. 詞卡生成系統

3. 🧪 測試生成詞卡 [AllowAnonymous]

POST /api/ai/test/generate
Content-Type: application/json

{
  "inputText": "要分析的英文文本",
  "extractionType": "vocabulary",
  "cardCount": 10
}

特點:

  • 無需用戶認證
  • 開發測試專用
  • API Key 未配置時返回模擬資料

2. 🚀 正式生成詞卡 [Authorize]

POST /api/ai/generate
Authorization: Bearer {jwt-token}
Content-Type: application/json

{
  "inputText": "The weather is beautiful today, and I'm planning to go hiking in the mountains.",
  "extractionType": "vocabulary",
  "cardCount": 5
}

回應範例:

{
  "success": true,
  "data": {
    "taskId": "123e4567-e89b-12d3-a456-426614174000",
    "status": "completed",
    "generatedCards": [
      {
        "word": "beautiful",
        "partOfSpeech": "adj.",
        "pronunciation": "/ˈbjuːtɪfl/",
        "translation": "美麗的",
        "definition": "pleasing the senses or mind aesthetically",
        "synonyms": ["lovely", "gorgeous"],
        "example": "The weather is beautiful today",
        "exampleTranslation": "今天天氣很美",
        "difficultyLevel": "A2"
      },
      {
        "word": "hiking",
        "partOfSpeech": "n.",
        "pronunciation": "/ˈhaɪkɪŋ/",
        "translation": "登山健行",
        "definition": "the activity of going for long walks in the countryside",
        "synonyms": ["trekking", "walking"],
        "example": "I'm planning to go hiking in the mountains",
        "exampleTranslation": "我計劃去山裡健行",
        "difficultyLevel": "B1"
      }
    ]
  },
  "message": "Successfully generated 5 cards"
}

3. 💾 保存生成的詞卡 [Authorize]

POST /api/ai/generate/{taskId}/save
Authorization: Bearer {jwt-token}
Content-Type: application/json

{
  "cardSetId": "456e7890-e89b-12d3-a456-426614174111",
  "selectedCards": [
    {
      "word": "beautiful",
      "translation": "美麗的",
      "definition": "pleasing the senses or mind aesthetically",
      "partOfSpeech": "adj.",
      "pronunciation": "/ˈbjuːtɪfl/",
      "example": "The weather is beautiful today",
      "exampleTranslation": "今天天氣很美",
      "difficultyLevel": "A2"
    }
  ]
}

回應範例:

{
  "success": true,
  "data": {
    "savedCount": 1,
    "cardSetId": "456e7890-e89b-12d3-a456-426614174111",
    "cardSetName": "我的詞卡集合",
    "cards": [
      {
        "id": "789e1234-e89b-12d3-a456-426614174222",
        "word": "beautiful",
        "translation": "美麗的",
        "definition": "pleasing the senses or mind aesthetically"
      }
    ]
  },
  "message": "Successfully saved 1 cards to deck '我的詞卡集合'"
}

4. 💾 快速保存詞卡(測試用) [AllowAnonymous]

POST /api/ai/test/generate/save
Content-Type: application/json

{
  "selectedCards": [
    {
      "word": "example",
      "translation": "例子",
      "definition": "a thing characteristic of its kind",
      "partOfSpeech": "n.",
      "pronunciation": "/ɪɡˈzɑːmpl/",
      "example": "This is an example sentence",
      "exampleTranslation": "這是一個例句",
      "difficultyLevel": "B1"
    }
  ]
}

特點:

  • 自動創建預設詞卡集合
  • 測試環境專用
  • 無需指定 CardSetId

5. 驗證詞卡內容 [Authorize]

POST /api/ai/validate-card
Authorization: Bearer {jwt-token}
Content-Type: application/json

{
  "flashcardId": "789e1234-e89b-12d3-a456-426614174222"
}

用途: 驗證已保存詞卡的內容準確性


📋 請求參數詳細說明

GenerateCardsRequest 參數

參數 類型 必填 限制 說明
inputText string ≤ 5000 字元 要分析的英文文本
extractionType string "vocabulary" 或 "smart" 萃取模式
cardCount int 1-20 要生成的詞卡數量

萃取模式說明

  • "vocabulary": 基本詞彙萃取

    • 重點:常用單字、動詞、形容詞等
    • 適合:基礎學習者
  • "smart": 智能萃取

    • 重點:片語、俚語、慣用語、搭配
    • 適合:進階學習者

SaveCardsRequest 參數

參數 類型 必填 說明
cardSetId Guid 目標詞卡集合 ID
selectedCards Array 要保存的詞卡陣列

GeneratedCard 結構

interface GeneratedCard {
  word: string;                    // 單字原型
  partOfSpeech: string;           // 詞性 (n./v./adj./adv.等)
  pronunciation: string;          // IPA 音標
  translation: string;            // 繁體中文翻譯
  definition: string;             // 英文定義
  synonyms?: string[];            // 同義詞 (最多2個)
  example: string;                // 例句
  exampleTranslation: string;     // 例句中文翻譯
  difficultyLevel: string;        // CEFR 等級 (A1/A2/B1/B2/C1/C2)
}

🛡️ 安全與驗證機制

輸入驗證

// 文本長度驗證
if (request.InputText.Length > 5000) {
    return BadRequest("Input text must be less than 5000 characters");
}

// 萃取類型驗證
if (!new[] { "vocabulary", "smart" }.Contains(request.ExtractionType)) {
    return BadRequest("Invalid extraction type");
}

// 詞卡數量驗證
if (request.CardCount < 1 || request.CardCount > 20) {
    return BadRequest("Card count must be between 1 and 20");
}

認證機制

var userId = await _authService.GetUserIdFromTokenAsync(Request.Headers.Authorization);
if (userId == null) {
    return Unauthorized(new { Success = false, Error = "Invalid token" });
}

使用限制

  • 🔄 目前狀態: 使用限制已暫時關閉 (isPremium: true)
  • 📊 配額檢查: 支援每日配額限制(可配置)
  • 🏷️ 用戶追蹤: 基於 JWT token 識別用戶身份

🔄 完整工作流程

sequenceDiagram
    participant F as 前端
    participant A as AIController
    participant G as GeminiService
    participant D as Database

    F->>A: POST /api/ai/generate
    A->>A: 驗證輸入參數
    A->>A: 檢查用戶認證
    A->>A: 檢查使用配額
    A->>G: GenerateCardsAsync()
    G->>G: 構建 AI Prompt
    G->>G: 呼叫 Gemini API
    G->>G: 解析 JSON 回應
    G->>A: 返回生成的詞卡
    A->>F: 返回詞卡結果

    F->>A: POST /api/ai/generate/{taskId}/save
    A->>A: 驗證用戶認證
    A->>D: 檢查詞卡集合存在
    A->>D: 批量保存詞卡
    A->>D: 更新集合統計
    A->>F: 返回保存結果

🤖 AI 服務整合詳解

句子分析 Prompt 模板

// 位置: GeminiService.cs AnalyzeSentenceAsync() 方法
var prompt = $@"
請分析以下英文句子,提供完整的分析:

句子:{inputText}

請按照以下JSON格式回應不要包含任何其他文字

{
  ""translation"": ""自然流暢的繁體中文翻譯"",
  ""explanation"": ""詳細解釋句子的語法結構、詞彙特點、使用場景和學習要點"",
  ""grammarCorrection"": {
    ""hasErrors"": false,
    ""originalText"": ""{inputText}"",
    ""correctedText"": null,
    ""corrections"": []
  },
  ""highValueWords"": [""重要詞彙1"", ""重要詞彙2""],
  ""wordAnalysis"": {
    ""單字"": {
      ""translation"": ""中文翻譯"",
      ""definition"": ""英文定義"",
      ""partOfSpeech"": ""詞性"",
      ""pronunciation"": ""音標"",
      ""isHighValue"": true,
      ""difficultyLevel"": ""CEFR等級""
    }
  }
}

要求:
1. 翻譯要自然流暢,符合中文語法
2. 解釋要具體有用,不要空泛
3. 標記B1以上詞彙為高價值
4. 如有語法錯誤請指出並修正
5. 確保JSON格式正確
";

關鍵欄位解釋:

  • translation: 這就是前端顯示的「整句翻譯」
  • explanation: 這就是前端顯示的「詳細解釋」部分
  • 前端組合: translation + ' ' + explanation = 完整的「整句意思」

詞卡生成 Prompt 模板

private const string VocabularyExtractionPrompt = @"
從以下英文文本中萃取 {cardCount} 個最重要的詞彙,為每個詞彙生成詞卡資料。

輸入文本:
{inputText}

請按照以下 JSON 格式回應,不要包含任何其他文字或代碼塊標記:

{
  ""cards"": [
    {
      ""word"": ""單字原型"",
      ""part_of_speech"": ""詞性(n./v./adj./adv.等)"",
      ""pronunciation"": ""IPA音標"",
      ""translation"": ""繁體中文翻譯"",
      ""definition"": ""英文定義(保持A1-A2程度)"",
      ""synonyms"": [""同義詞1"", ""同義詞2""],
      ""example"": ""例句(使用原文中的句子或生成新句子)"",
      ""example_translation"": ""例句中文翻譯"",
      ""difficulty_level"": ""CEFR等級(A1/A2/B1/B2/C1/C2)""
    }
  ]
}

要求:
1. 選擇最有學習價值的詞彙
2. 定義要簡單易懂,適合英語學習者
3. 例句要實用且符合語境
4. 確保 JSON 格式正確
5. 同義詞最多2個選擇常用的";

智能萃取 Prompt

private const string SmartExtractionPrompt = @"
分析以下英文文本,識別片語、俚語和常用表達,生成 {cardCount} 個學習卡片:

輸入文本:
{inputText}

重點關注:
1. 片語和俚語
2. 文化相關表達
3. 語境特定用法
4. 慣用語和搭配

請按照相同的 JSON 格式回應...";

錯誤處理與回退機制

try {
    var generatedCards = await _geminiService.GenerateCardsAsync(
        request.InputText,
        request.ExtractionType,
        request.CardCount
    );
    return Ok(successResponse);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("API key")) {
    _logger.LogWarning("Gemini API key not configured, using mock data");

    // 返回模擬資料
    var mockCards = GenerateMockCards(request.CardCount);
    return Ok(mockResponse);
}
catch (Exception ex) {
    _logger.LogError(ex, "Error in AI card generation");
    return StatusCode(500, errorResponse);
}

💾 資料庫設計

Flashcard 資料表結構

CREATE TABLE Flashcards (
    Id UNIQUEIDENTIFIER PRIMARY KEY,
    UserId UNIQUEIDENTIFIER NOT NULL,
    CardSetId UNIQUEIDENTIFIER NOT NULL,
    Word NVARCHAR(100) NOT NULL,
    Translation NVARCHAR(200) NOT NULL,
    Definition NVARCHAR(500),
    PartOfSpeech NVARCHAR(50),
    Pronunciation NVARCHAR(100),
    Example NVARCHAR(500),
    ExampleTranslation NVARCHAR(500),
    DifficultyLevel NVARCHAR(10),
    CreatedAt DATETIME2 NOT NULL,
    UpdatedAt DATETIME2 NOT NULL,

    FOREIGN KEY (UserId) REFERENCES Users(Id),
    FOREIGN KEY (CardSetId) REFERENCES CardSets(Id)
);

CardSet 資料表結構

CREATE TABLE CardSets (
    Id UNIQUEIDENTIFIER PRIMARY KEY,
    UserId UNIQUEIDENTIFIER NOT NULL,
    Name NVARCHAR(100) NOT NULL,
    Description NVARCHAR(500),
    Color NVARCHAR(20),
    CardCount INT DEFAULT 0,
    IsDefault BIT DEFAULT 0,
    CreatedAt DATETIME2 NOT NULL,
    UpdatedAt DATETIME2 NOT NULL,

    FOREIGN KEY (UserId) REFERENCES Users(Id)
);

自動建立預設詞卡集合

var defaultCardSet = await _context.CardSets
    .FirstOrDefaultAsync(cs => cs.IsDefault);

if (defaultCardSet == null) {
    defaultCardSet = new CardSet {
        Id = Guid.NewGuid(),
        UserId = userId.Value,
        Name = "AI 生成詞卡",
        Description = "通過 AI 智能生成的詞卡集合",
        Color = "#3B82F6",
        IsDefault = true,
        CreatedAt = DateTime.UtcNow,
        UpdatedAt = DateTime.UtcNow
    };
    _context.CardSets.Add(defaultCardSet);
}

📊 錯誤處理與狀態碼

HTTP 狀態碼說明

狀態碼 情境 說明
200 OK 成功 詞卡生成/保存成功
400 Bad Request 輸入錯誤 參數驗證失敗
401 Unauthorized 認證失敗 JWT Token 無效或過期
404 Not Found 資源不存在 詞卡集合或詞卡不存在
429 Too Many Requests 配額超限 超過每日生成限制
500 Internal Server Error 服務錯誤 AI 服務或資料庫錯誤

標準錯誤回應格式

{
  "success": false,
  "error": "Input text is required",
  "details": "The inputText field cannot be null or empty",
  "timestamp": "2025-01-18T15:54:00Z",
  "errorCode": "VALIDATION_ERROR"
}

常見錯誤類型

// 輸入驗證錯誤
return BadRequest(new {
    Success = false,
    Error = "Input text must be less than 5000 characters",
    ErrorCode = "INPUT_TOO_LONG"
});

// 認證錯誤
return Unauthorized(new {
    Success = false,
    Error = "Invalid token",
    ErrorCode = "AUTH_FAILED"
});

// 配額超限
return StatusCode(429, new {
    Success = false,
    Error = "Daily generation limit exceeded",
    ErrorCode = "QUOTA_EXCEEDED",
    ResetTime = DateTime.UtcNow.AddDays(1)
});

// AI 服務錯誤
return StatusCode(500, new {
    Success = false,
    Error = "AI service temporarily unavailable",
    ErrorCode = "AI_SERVICE_ERROR"
});

🔧 環境配置

必要環境變數

# AI 服務配置
export DRAMALING_GEMINI_API_KEY="your-gemini-api-key-here"

# 資料庫配置
export DRAMALING_DB_CONNECTION="Host=localhost;Database=dramaling;Username=postgres;Password=your-password"

# JWT 配置
export DRAMALING_JWT_SECRET="your-jwt-secret-key"
export DRAMALING_JWT_ISSUER="dramaling-api"
export DRAMALING_JWT_AUDIENCE="dramaling-frontend"

appsettings.json 配置範例

{
  "ConnectionStrings": {
    "DefaultConnection": "Data Source=dramaling_test.db"
  },
  "JwtSettings": {
    "SecretKey": "${DRAMALING_JWT_SECRET}",
    "Issuer": "${DRAMALING_JWT_ISSUER}",
    "Audience": "${DRAMALING_JWT_AUDIENCE}",
    "ExpirationMinutes": 60
  },
  "GeminiSettings": {
    "ApiKey": "${DRAMALING_GEMINI_API_KEY}",
    "Model": "gemini-pro",
    "MaxTokens": 2048,
    "Temperature": 0.7
  },
  "UsageLimits": {
    "FreeUserDailyLimit": 10,
    "PremiumUserDailyLimit": 100,
    "MaxTextLength": 5000,
    "MaxCardCount": 20
  }
}

🧪 測試範例

使用 cURL 測試

A. 句子分析功能測試

# 1. 測試句子分析 (整句意思生成) - 無需認證
curl -X POST http://localhost:5000/api/ai/analyze-sentence \
  -H "Content-Type: application/json" \
  -d '{
    "inputText": "The weather is beautiful today and I am planning to go hiking.",
    "forceRefresh": false,
    "analysisMode": "full"
  }' | jq '.data.sentenceMeaning'

# 2. 測試互動式單字查詢
curl -X POST http://localhost:5000/api/ai/query-word \
  -H "Content-Type: application/json" \
  -d '{
    "word": "beautiful",
    "sentence": "The weather is beautiful today"
  }'

B. 詞卡生成功能測試

# 1. 測試生成詞卡 (無需認證)
curl -X POST http://localhost:5000/api/ai/test/generate \
  -H "Content-Type: application/json" \
  -d '{
    "inputText": "The weather is beautiful today and I am planning to go hiking in the mountains.",
    "extractionType": "vocabulary",
    "cardCount": 5
  }'

# 2. 正式生成詞卡 (需要認證)
curl -X POST http://localhost:5000/api/ai/generate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer your-jwt-token-here" \
  -d '{
    "inputText": "Learning English through movies and TV shows is an effective method.",
    "extractionType": "smart",
    "cardCount": 8
  }'

# 3. 保存詞卡
curl -X POST http://localhost:5000/api/ai/test/generate/save \
  -H "Content-Type: application/json" \
  -d '{
    "selectedCards": [
      {
        "word": "effective",
        "translation": "有效的",
        "definition": "successful in producing a desired result",
        "partOfSpeech": "adj.",
        "pronunciation": "/ɪˈfektɪv/",
        "example": "This is an effective method",
        "exampleTranslation": "這是一個有效的方法",
        "difficultyLevel": "B2"
      }
    ]
  }'

前端 JavaScript 整合範例

A. 句子分析功能

// 分析句子獲得整句意思
async function analyzeSentence(text, forceRefresh = false) {
  try {
    const response = await fetch('/api/ai/analyze-sentence', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        inputText: text,
        forceRefresh: forceRefresh,
        analysisMode: 'full'
      })
    });

    const result = await response.json();

    if (result.success) {
      // 取得整句意思
      const sentenceMeaning = result.data.sentenceMeaning;
      console.log('翻譯:', sentenceMeaning.translation);
      console.log('解釋:', sentenceMeaning.explanation);

      // 取得詞彙分析
      console.log('詞彙分析:', result.data.wordAnalysis);
      console.log('高價值詞彙:', result.data.highValueWords);

      return result.data;
    } else {
      throw new Error(result.error);
    }
  } catch (error) {
    console.error('Error analyzing sentence:', error);
    throw error;
  }
}

// 查詢特定單字
async function queryWord(word, sentence) {
  try {
    const response = await fetch('/api/ai/query-word', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        word: word,
        sentence: sentence
      })
    });

    const result = await response.json();
    return result.data;
  } catch (error) {
    console.error('Error querying word:', error);
    throw error;
  }
}

B. 詞卡生成功能

// 生成詞卡
async function generateCards(text, type = 'vocabulary', count = 10) {
  try {
    const response = await fetch('/api/ai/generate', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${localStorage.getItem('token')}`
      },
      body: JSON.stringify({
        inputText: text,
        extractionType: type,
        cardCount: count
      })
    });

    const result = await response.json();

    if (result.success) {
      console.log('Generated cards:', result.data.generatedCards);
      return result.data;
    } else {
      throw new Error(result.error);
    }
  } catch (error) {
    console.error('Error generating cards:', error);
    throw error;
  }
}

// 保存詞卡
async function saveCards(taskId, cardSetId, selectedCards) {
  try {
    const response = await fetch(`/api/ai/generate/${taskId}/save`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Bearer ${localStorage.getItem('token')}`
      },
      body: JSON.stringify({
        cardSetId: cardSetId,
        selectedCards: selectedCards
      })
    });

    const result = await response.json();

    if (result.success) {
      console.log('Cards saved successfully:', result.data);
      return result.data;
    } else {
      throw new Error(result.error);
    }
  } catch (error) {
    console.error('Error saving cards:', error);
    throw error;
  }
}

// 使用範例
(async () => {
  try {
    // 生成詞卡
    const generateResult = await generateCards(
      "Artificial intelligence is transforming the way we learn languages.",
      "smart",
      6
    );

    // 保存選中的詞卡
    const selectedCards = generateResult.generatedCards.slice(0, 3); // 選前3張
    await saveCards(
      generateResult.taskId,
      'your-card-set-id',
      selectedCards
    );

    console.log('Process completed successfully!');
  } catch (error) {
    console.error('Process failed:', error);
  }
})();

📈 效能與最佳實踐

效能考量

  • 🚀 快取策略: 相同文本的分析結果可以快取
  • 非同步處理: 長文本分析採用背景處理
  • 🔄 批量操作: 一次保存多張詞卡減少資料庫操作
  • 📊 資源限制: 限制同時處理的請求數量

最佳實踐

// 1. 使用交易確保資料一致性
using var transaction = await _context.Database.BeginTransactionAsync();
try {
    _context.Flashcards.AddRange(flashcardsToSave);
    defaultCardSet.CardCount += flashcardsToSave.Count;
    await _context.SaveChangesAsync();
    await transaction.CommitAsync();
} catch {
    await transaction.RollbackAsync();
    throw;
}

// 2. 分頁處理大量結果
var cards = await _context.Flashcards
    .Where(f => f.UserId == userId)
    .OrderBy(f => f.CreatedAt)
    .Skip(pageIndex * pageSize)
    .Take(pageSize)
    .ToListAsync();

// 3. 使用索引優化查詢
[Index(nameof(UserId), nameof(CreatedAt))]
public class Flashcard { /* ... */ }

🚀 部署注意事項

生產環境配置

  1. 安全性:

    • 使用 HTTPS 通訊
    • 定期輪換 JWT Secret
    • 實施 Rate Limiting
    • 加密敏感資料
  2. 監控:

    • API 回應時間監控
    • 錯誤率追蹤
    • 使用量統計
    • AI 服務可用性監控
  3. 擴展性:

    • 考慮使用佇列系統處理大量請求
    • 資料庫連接池配置
    • 負載平衡配置
    • CDN 快取靜態資源

部署檢查清單

  • 環境變數正確設定
  • 資料庫遷移完成
  • AI API 金鑰有效
  • JWT 配置正確
  • CORS 設定完成
  • 監控系統運行
  • 備份策略實施
  • 日誌記錄配置

📞 支援與維護

常見問題

  1. Q: AI 生成的詞卡質量如何保證? A: 使用精心設計的 Prompt 模板,並提供詞卡驗證功能

  2. Q: 如何處理 AI 服務不可用的情況? A: 實施回退機制,返回預設模擬資料確保服務可用性

  3. Q: 支援哪些語言和難度等級? A: 目前專注於英語學習,支援 CEFR A1-C2 等級

技術支援

  • 📧 開發團隊: dev@dramaling.com
  • 📚 文檔庫: /docs/api/
  • 🐛 問題回報: GitHub Issues
  • 💬 即時支援: Slack #dramaling-dev

© 2025 DramaLing Team. All rights reserved.