# 後端API架構分離計劃

**文件版本**: 1.0  
**建立日期**: 2025-09-10  
**更新日期**: 2025-09-10  
**負責人**: Drama Ling 開發團隊

## 📋 概述

由於Drama Ling需要同時支援移動端App和Web端應用，現有的單一後端API架構將面臨以下挑戰：
- 移動端和Web端資料需求差異
- 認證方式和安全要求不同  
- 效能優化需求各異
- 維護和擴展複雜度增加

本文件提出後端API分離的架構方案和實施計劃。

## 🎯 目標

### 主要目標
1. **API專業化**: 為移動端和Web端提供專門優化的API
2. **提升效能**: 減少不必要的資料傳輸，提升回應速度
3. **簡化維護**: 降低不同端點間的耦合度
4. **增強安全**: 針對不同平台實施適當的安全策略
5. **支援擴展**: 為未來微服務架構奠定基礎

### 成功指標
- API回應時間減少30%以上
- 移動端資料傳輸量減少50%
- 代碼維護複雜度降低
- 支援獨立部署和擴展

## 🏗 架構方案

### 方案一: API Gateway + 微服務分離 (推薦)

```mermaid
graph TB
    MA[Mobile App] --> AG[API Gateway]
    WA[Web App] --> AG
    
    AG --> AUTH[Authentication Service]
    AG --> USER[User Service]
    AG --> VOCAB[Vocabulary Service]
    AG --> LEARN[Learning Service]
    AG --> PROG[Progress Service]
    
    AUTH --> DB1[(Auth DB)]
    USER --> DB2[(User DB)]
    VOCAB --> DB3[(Vocabulary DB)]
    LEARN --> DB4[(Learning DB)]
    PROG --> DB5[(Progress DB)]
```

#### 優勢
- 🎯 **高度專業化**: 每個服務專注特定功能
- 🚀 **獨立擴展**: 可根據負載獨立擴展服務
- 🔒 **安全隔離**: 服務間隔離，降低安全風險
- 🛠 **技術選型靈活**: 不同服務可選用不同技術
- 👥 **團隊分工**: 支援多團隊並行開發

#### 挑戰
- 複雜度較高，需要服務發現和配置管理
- 分散式系統的一致性問題
- 運維複雜度增加

### 方案二: 單體 + 多端點適配 (階段性)

```mermaid
graph TB
    MA[Mobile App] --> ME[/api/v1/mobile]
    WA[Web App] --> WE[/api/v1/web]
    
    ME --> BS[Backend Service]
    WE --> BS
    
    BS --> SL[Shared Logic Layer]
    BS --> MH[Mobile Handler]
    BS --> WH[Web Handler]
    
    SL --> DB[(Database)]
```

#### 優勢
- 🏃‍♂️ **快速實施**: 在現有架構基礎上調整
- 🔧 **維護簡單**: 單一部署單位
- 💰 **成本較低**: 無需額外的基礎設施
- 🧪 **風險可控**: 漸進式改進

#### 挑戰
- 單體應用的擴展限制
- 不同端點間仍有耦合
- 長期維護複雜度仍然較高

## 📊 API差異化設計

### 移動端API特點

```json
{
  "endpoint": "/api/v1/mobile/vocabulary/{id}",
  "response": {
    "word": "confidence",
    "phonetic": "/ˈkɒnfɪdəns/",
    "definition": "信心",
    "audio_url": "https://cdn.dramaling.com/audio/confidence.mp3",
    "last_reviewed": "2025-09-10T10:30:00Z"
  },
  "features": [
    "精簡資料結構",
    "支援離線緩存",
    "增量同步",
    "推播通知",
    "JWT認證"
  ]
}
```

### Web端API特點

```json
{
  "endpoint": "/api/v1/web/vocabulary/{id}",
  "response": {
    "word": "confidence",
    "phonetic": "/ˈkɒnfɪdəns/",
    "definitions": {
      "primary": "信心；自信心；把握",
      "secondary": ["確信", "秘密", "信賴"]
    },
    "examples": [
      {
        "sentence": "She spoke with great confidence during the presentation.",
        "translation": "她在簡報中表現出很大的自信。"
      }
    ],
    "synonyms": ["assurance", "self-assurance", "poise"],
    "etymology": "來自拉丁語 confidentia",
    "usage_frequency": 0.85,
    "difficulty_level": "intermediate",
    "related_words": ["confident", "confidential"],
    "learning_analytics": {
      "total_reviews": 15,
      "success_rate": 0.87,
      "avg_response_time": 2.3
    }
  },
  "features": [
    "完整資料結構",
    "即時互動",
    "豐富的學習分析",
    "SEO友好",
    "Session認證"
  ]
}
```

### 認證策略差異

#### 移動端認證
```csharp
[ApiController]
[Route("api/v1/mobile/[controller]")]
[Authorize(AuthenticationSchemes = "JwtBearer")]
public class MobileVocabularyController : ControllerBase
{
    // JWT Token + Refresh Token
    // 生物識別支援
    // OAuth2.0 整合
}
```

#### Web端認證
```csharp
[ApiController]
[Route("api/v1/web/[controller]")]
[Authorize(AuthenticationSchemes = "Cookie,OpenIdConnect")]
public class WebVocabularyController : ControllerBase
{
    // Session + Cookie
    // Social Login (Google, Facebook)
    // CSRF Protection
}
```

## 🚀 實施計劃

### Phase 1: 基礎分離 (4週)

**目標**: 建立移動端和Web端分離的API端點

#### Week 1: 路由分離
- [ ] 建立 `/api/v1/mobile/*` 路由結構
- [ ] 建立 `/api/v1/web/*` 路由結構  
- [ ] 實現路由中介軟體和版本控制
- [ ] 測試基本路由功能

#### Week 2: 控制器分離
- [ ] 複製現有控制器為Mobile和Web版本
- [ ] 實現MobileBaseController和WebBaseController
- [ ] 調整回應格式和資料結構
- [ ] 單元測試覆蓋

#### Week 3: 資料模型差異化
- [ ] 建立MobileDto和WebDto資料傳輸物件
- [ ] 實現AutoMapper配置
- [ ] 調整序列化設定
- [ ] API文件生成

#### Week 4: 認證系統調整
- [ ] 實現JWT認證for移動端
- [ ] 保持Session認證for Web端
- [ ] 測試認證流程
- [ ] 效能基準測試

### Phase 2: 功能優化 (6週)

**目標**: 針對不同平台優化API功能

#### Week 5-6: 移動端優化
- [ ] 實現離線支援和增量同步
- [ ] 優化資料傳輸量和壓縮
- [ ] 推播通知整合
- [ ] 移動端特有功能開發

#### Week 7-8: Web端優化  
- [ ] 實現即時互動功能
- [ ] 豐富學習分析資料
- [ ] SEO優化和Open Graph支援
- [ ] Web端專屬功能開發

#### Week 9-10: 效能和安全優化
- [ ] API快取策略實施
- [ ] 安全性強化(CORS, CSRF, Rate Limiting)
- [ ] 監控和日誌系統
- [ ] 負載測試和調優

### Phase 3: 微服務準備 (8週)

**目標**: 為未來微服務架構做準備

#### Week 11-12: 服務邊界定義
- [ ] 識別和定義服務邊界
- [ ] 資料庫分離規劃
- [ ] API Gateway選型和POC
- [ ] 服務發現機制設計

#### Week 13-16: 核心服務提取
- [ ] 提取User Service
- [ ] 提取Vocabulary Service  
- [ ] 提取Learning Service
- [ ] 服務間通信機制

#### Week 17-18: 整合和測試
- [ ] API Gateway整合
- [ ] 端到端測試
- [ ] 效能測試和調優
- [ ] 生產環境部署準備

## 🛠 技術實現

### .NET Core 實現範例

#### 1. 路由結構

```csharp
// Program.cs
app.MapControllerRoute(
    name: "mobile-api",
    pattern: "api/v1/mobile/{controller}/{action=Index}/{id?}");

app.MapControllerRoute(
    name: "web-api", 
    pattern: "api/v1/web/{controller}/{action=Index}/{id?}");
```

#### 2. 基礎控制器

```csharp
// MobileBaseController.cs
[ApiController]
[Route("api/v1/mobile/[controller]")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public abstract class MobileBaseController : ControllerBase
{
    protected readonly ILogger Logger;
    protected readonly IMapper Mapper;

    protected MobileBaseController(ILogger logger, IMapper mapper)
    {
        Logger = logger;
        Mapper = mapper;
    }

    protected IActionResult MobileSuccess<T>(T data, string message = null)
    {
        return Ok(new MobileApiResponse<T>
        {
            Data = data,
            Message = message,
            Timestamp = DateTimeOffset.UtcNow,
            Success = true
        });
    }
}

// WebBaseController.cs
[ApiController]
[Route("api/v1/web/[controller]")]
[Authorize(AuthenticationSchemes = CookieAuthenticationDefaults.AuthenticationScheme)]
public abstract class WebBaseController : ControllerBase
{
    protected readonly ILogger Logger;
    protected readonly IMapper Mapper;

    protected WebBaseController(ILogger logger, IMapper mapper)
    {
        Logger = logger;
        Mapper = mapper;
    }

    protected IActionResult WebSuccess<T>(T data, object meta = null)
    {
        return Ok(new WebApiResponse<T>
        {
            Data = data,
            Meta = meta,
            Links = GenerateHATEOASLinks(),
            Timestamp = DateTimeOffset.UtcNow
        });
    }
}
```

#### 3. 專業化控制器

```csharp
// Mobile Vocabulary Controller
public class MobileVocabularyController : MobileBaseController
{
    private readonly IVocabularyService _vocabularyService;

    public MobileVocabularyController(
        ILogger<MobileVocabularyController> logger,
        IMapper mapper,
        IVocabularyService vocabularyService) 
        : base(logger, mapper)
    {
        _vocabularyService = vocabularyService;
    }

    [HttpGet("{id}")]
    public async Task<IActionResult> GetVocabulary(int id)
    {
        var vocabulary = await _vocabularyService.GetByIdAsync(id);
        var mobileDto = Mapper.Map<MobileVocabularyDto>(vocabulary);
        return MobileSuccess(mobileDto);
    }

    [HttpGet("sync")]
    public async Task<IActionResult> SyncVocabulary([FromQuery] DateTime? lastSync)
    {
        var changes = await _vocabularyService.GetChangesAsync(lastSync);
        var mobileDtos = Mapper.Map<List<MobileVocabularyDto>>(changes);
        
        return MobileSuccess(new
        {
            Vocabularies = mobileDtos,
            LastSyncTime = DateTimeOffset.UtcNow,
            HasMore = changes.Count >= 50
        });
    }
}

// Web Vocabulary Controller  
public class WebVocabularyController : WebBaseController
{
    private readonly IVocabularyService _vocabularyService;
    private readonly ILearningAnalyticsService _analyticsService;

    public WebVocabularyController(
        ILogger<WebVocabularyController> logger,
        IMapper mapper,
        IVocabularyService vocabularyService,
        ILearningAnalyticsService analyticsService) 
        : base(logger, mapper)
    {
        _vocabularyService = vocabularyService;
        _analyticsService = analyticsService;
    }

    [HttpGet("{id}")]
    public async Task<IActionResult> GetVocabulary(int id)
    {
        var vocabulary = await _vocabularyService.GetByIdAsync(id);
        var analytics = await _analyticsService.GetVocabularyAnalyticsAsync(id);
        
        var webDto = Mapper.Map<WebVocabularyDto>(vocabulary);
        webDto.LearningAnalytics = Mapper.Map<LearningAnalyticsDto>(analytics);
        
        return WebSuccess(webDto, new { 
            Related = await _vocabularyService.GetRelatedWordsAsync(id),
            Recommendations = await _vocabularyService.GetRecommendationsAsync(id)
        });
    }

    [HttpGet("search")]
    public async Task<IActionResult> SearchVocabulary(
        [FromQuery] string query,
        [FromQuery] int page = 1,
        [FromQuery] int size = 20,
        [FromQuery] string[] filters = null)
    {
        var result = await _vocabularyService.SearchAsync(query, page, size, filters);
        var webDtos = Mapper.Map<List<WebVocabularyDto>>(result.Items);
        
        return WebSuccess(webDtos, new
        {
            Pagination = new
            {
                Page = page,
                Size = size,
                Total = result.Total,
                Pages = (int)Math.Ceiling((double)result.Total / size)
            },
            Filters = await _vocabularyService.GetAvailableFiltersAsync(),
            Aggregations = result.Aggregations
        });
    }
}
```

#### 4. 資料傳輸物件 (DTOs)

```csharp
// Mobile DTOs - 精簡結構
public class MobileVocabularyDto
{
    public int Id { get; set; }
    public string Word { get; set; }
    public string Phonetic { get; set; }
    public string Definition { get; set; }
    public string AudioUrl { get; set; }
    public DateTimeOffset LastReviewed { get; set; }
    public int ReviewCount { get; set; }
    public double MasteryLevel { get; set; }
}

public class MobileApiResponse<T>
{
    public T Data { get; set; }
    public string Message { get; set; }
    public bool Success { get; set; }
    public DateTimeOffset Timestamp { get; set; }
}

// Web DTOs - 豐富結構
public class WebVocabularyDto
{
    public int Id { get; set; }
    public string Word { get; set; }
    public string Phonetic { get; set; }
    public DefinitionDto Definitions { get; set; }
    public List<ExampleDto> Examples { get; set; }
    public List<string> Synonyms { get; set; }
    public List<string> Antonyms { get; set; }
    public string Etymology { get; set; }
    public double UsageFrequency { get; set; }
    public string DifficultyLevel { get; set; }
    public List<string> RelatedWords { get; set; }
    public LearningAnalyticsDto LearningAnalytics { get; set; }
    public DateTimeOffset CreatedAt { get; set; }
    public DateTimeOffset UpdatedAt { get; set; }
}

public class WebApiResponse<T>
{
    public T Data { get; set; }
    public object Meta { get; set; }
    public Dictionary<string, string> Links { get; set; }
    public DateTimeOffset Timestamp { get; set; }
}
```

## 📈 效能考量

### 移動端優化策略
1. **資料壓縮**: 使用Gzip/Brotli壓縮
2. **增量同步**: 僅傳輸變更資料
3. **快取策略**: 積極的客戶端快取
4. **分頁載入**: 小批次資料載入
5. **連接複用**: HTTP/2 多工處理

### Web端優化策略  
1. **快取分層**: Redis + Memory + CDN
2. **資料預載**: 相關資料預先載入
3. **即時更新**: WebSocket/SignalR
4. **搜尋優化**: ElasticSearch整合
5. **圖片優化**: WebP格式和響應式圖片

## 🔒 安全性設計

### 共同安全措施
- HTTPS強制執行
- API版本控制
- 輸入驗證和清理
- 輸出編碼
- 安全標頭設定

### 移動端專屬
- JWT Token安全存儲
- Certificate Pinning
- Root Detection
- API密鑰混淆
- 生物識別整合

### Web端專屬
- CSRF保護
- XSS防護
- Content Security Policy
- Session管理
- Same-Site Cookie

## 📊 監控和分析

### 關鍵指標 (KPIs)
1. **效能指標**
   - API回應時間 (P95 < 200ms)
   - 錯誤率 (< 0.1%)
   - 吞吐量 (TPS)
   
2. **使用者體驗**
   - 移動端資料傳輸量
   - Web端頁面載入時間
   - 離線功能可用性

3. **業務指標**
   - API使用率
   - 功能採用率
   - 使用者滿意度

### 監控工具
- **Application Insights**: .NET應用監控
- **Prometheus + Grafana**: 指標收集和視覺化
- **ELK Stack**: 日誌分析
- **Postman/Newman**: API測試自動化

## 🚦 風險管理

### 技術風險
| 風險 | 機率 | 影響 | 緩解措施 |
|------|------|------|----------|
| 服務間通信複雜度 | 中 | 高 | 使用成熟的API Gateway解決方案 |
| 資料一致性問題 | 中 | 高 | 實施Saga模式和補償事務 |
| 效能退化 | 低 | 中 | 充分的效能測試和監控 |
| 安全漏洞 | 低 | 高 | 安全掃描和滲透測試 |

### 業務風險
| 風險 | 機率 | 影響 | 緩解措施 |
|------|------|------|----------|
| 開發時程延遲 | 中 | 中 | 分階段實施，降低每階段風險 |
| 使用者體驗下降 | 低 | 高 | 充分的使用者測試 |
| 維護成本增加 | 中 | 中 | 自動化部署和監控 |

## 📝 後續步驟

### 立即行動項目
1. [ ] **技術評估**: 評估現有程式碼庫分離可行性
2. [ ] **團隊培訓**: 微服務架構和API設計最佳實踐
3. [ ] **工具準備**: 開發、測試、部署工具鏈建立
4. [ ] **原型開發**: 建立MVP驗證架構可行性

### 決策點
1. **Week 4**: Phase 1完成度評估，決定是否進入Phase 2
2. **Week 10**: 效能和安全性評估，決定微服務遷移時機
3. **Week 18**: 全面評估，決定生產環境部署策略

## 📚 詞彙學習系統API實施計畫

### 階段一：核心詞彙API開發 (Week 1-3)

#### 1.1 資料庫架構建立
```sql
-- 詞彙基礎表設計 (基於database-schema.md)
CREATE TABLE vocabulary_bank (
    vocab_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    word VARCHAR(100) NOT NULL,
    phonetic VARCHAR(200),
    part_of_speech VARCHAR(50),
    definition_en TEXT,
    definition_native JSONB,
    category VARCHAR(50),
    difficulty_level VARCHAR(10),
    frequency_rank INTEGER,
    audio_url TEXT,
    example_sentences JSONB,
    synonyms JSONB,
    antonyms JSONB,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW(),
    UNIQUE(word, part_of_speech)
);

-- 用戶詞彙進度表
CREATE TABLE user_vocabulary_progress (
    progress_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID REFERENCES users(user_id) ON DELETE CASCADE,
    vocab_id UUID REFERENCES vocabulary_bank(vocab_id) ON DELETE CASCADE,
    mastery_level VARCHAR(20) DEFAULT 'learning',
    mastery_score INTEGER DEFAULT 0,
    review_count INTEGER DEFAULT 0,
    correct_count INTEGER DEFAULT 0,
    ease_factor DECIMAL(4,2) DEFAULT 2.50,
    interval_days INTEGER DEFAULT 1,
    next_review_date DATE,
    first_encountered TIMESTAMPTZ DEFAULT NOW(),
    last_reviewed TIMESTAMPTZ,
    UNIQUE(user_id, vocab_id)
);
```

#### 1.2 核心服務層實現
```csharp
// IVocabularyService 介面設計
public interface IVocabularyService
{
    // 基本詞彙CRUD
    Task<VocabularyDto> GetByIdAsync(Guid vocabId);
    Task<PagedResult<VocabularyDto>> GetVocabularyListAsync(VocabularyFilter filter);
    Task<List<VocabularyDto>> SearchVocabularyAsync(string query, int limit = 20);
    
    // 用戶學習進度
    Task<UserVocabularyProgressDto> GetUserProgressAsync(Guid userId, Guid vocabId);
    Task UpdateProgressAsync(Guid userId, UpdateProgressRequest request);
    Task<List<VocabularyDto>> GetDueForReviewAsync(Guid userId);
    
    // 間隔重複演算法
    Task<SpacedRepetitionResult> ProcessReviewResultAsync(
        Guid userId, Guid vocabId, ReviewQuality quality);
    
    // 學習分析
    Task<LearningAnalyticsDto> GetLearningAnalyticsAsync(Guid userId);
}

// 間隔重複演算法實現
public class SpacedRepetitionService : ISpacedRepetitionService
{
    public SpacedRepetitionResult CalculateNextReview(
        double easeFactor, int interval, ReviewQuality quality)
    {
        // SuperMemo SM-2 算法實現
        var newEaseFactor = Math.Max(1.3, easeFactor + 
            (0.1 - (5 - (int)quality) * (0.08 + (5 - (int)quality) * 0.02)));
            
        int newInterval = quality switch
        {
            ReviewQuality.Again => 1,
            ReviewQuality.Hard => (int)(interval * 1.2),
            ReviewQuality.Good => (int)(interval * newEaseFactor),
            ReviewQuality.Easy => (int)(interval * newEaseFactor * 1.3),
            _ => 1
        };
        
        return new SpacedRepetitionResult
        {
            NextInterval = newInterval,
            NewEaseFactor = newEaseFactor,
            NextReviewDate = DateTime.UtcNow.AddDays(newInterval)
        };
    }
}
```

#### 1.3 API控制器實現
```csharp
// 移動端詞彙API控制器
[ApiController]
[Route("api/v1/mobile/vocabulary")]
[Authorize(AuthenticationSchemes = JwtBearerDefaults.AuthenticationScheme)]
public class MobileVocabularyController : MobileBaseController
{
    private readonly IVocabularyService _vocabularyService;
    
    [HttpGet("daily-review")]
    public async Task<ActionResult<MobileApiResponse<List<MobileVocabularyDto>>>> GetDailyReview()
    {
        var userId = GetCurrentUserId();
        var vocabularyList = await _vocabularyService.GetDueForReviewAsync(userId);
        var mobileDtos = Mapper.Map<List<MobileVocabularyDto>>(vocabularyList);
        
        return MobileSuccess(mobileDtos);
    }
    
    [HttpPost("{vocabId}/review")]
    public async Task<ActionResult<MobileApiResponse<ReviewResultDto>>> SubmitReview(
        Guid vocabId, [FromBody] SubmitReviewRequest request)
    {
        var userId = GetCurrentUserId();
        var result = await _vocabularyService.ProcessReviewResultAsync(
            userId, vocabId, request.Quality);
            
        return MobileSuccess(new ReviewResultDto
        {
            NextReviewDate = result.NextReviewDate,
            MasteryLevelChange = result.MasteryLevelChange,
            PointsEarned = result.PointsEarned
        });
    }
    
    [HttpGet("search")]
    public async Task<ActionResult<MobileApiResponse<List<MobileVocabularyDto>>>> Search(
        [FromQuery] string query, [FromQuery] int limit = 10)
    {
        var results = await _vocabularyService.SearchVocabularyAsync(query, limit);
        var mobileDtos = Mapper.Map<List<MobileVocabularyDto>>(results);
        
        return MobileSuccess(mobileDtos);
    }
}

// Web端詞彙API控制器
[ApiController]
[Route("api/v1/web/vocabulary")]
[Authorize]
public class WebVocabularyController : WebBaseController
{
    [HttpGet("{id}")]
    public async Task<ActionResult<WebApiResponse<WebVocabularyDto>>> GetVocabulary(Guid id)
    {
        var vocabulary = await _vocabularyService.GetByIdAsync(id);
        var webDto = Mapper.Map<WebVocabularyDto>(vocabulary);
        
        return WebSuccess(webDto, new {
            RelatedWords = await _vocabularyService.GetRelatedWordsAsync(id),
            LearningTips = await _vocabularyService.GetLearningTipsAsync(id),
            UsageExamples = await _vocabularyService.GetUsageExamplesAsync(id)
        });
    }
    
    [HttpGet("analytics")]
    public async Task<ActionResult<WebApiResponse<LearningAnalyticsDto>>> GetAnalytics(
        [FromQuery] DateTime? from, [FromQuery] DateTime? to)
    {
        var userId = GetCurrentUserId();
        var analytics = await _vocabularyService.GetLearningAnalyticsAsync(
            userId, from, to);
            
        return WebSuccess(analytics);
    }
}
```

### 階段二：智能學習功能 (Week 4-6)

#### 2.1 AI驅動的詞彙推薦系統
```csharp
public interface IVocabularyRecommendationService
{
    Task<List<VocabularyDto>> GetPersonalizedRecommendationsAsync(
        Guid userId, int count = 10);
    Task<List<VocabularyDto>> GetContextualVocabularyAsync(
        string context, DifficultyLevel level);
    Task<List<VocabularyDto>> GetRelatedVocabularyAsync(Guid vocabId);
}

public class AIVocabularyRecommendationService : IVocabularyRecommendationService
{
    private readonly IOpenAIService _openAiService;
    private readonly IVocabularyRepository _vocabularyRepo;
    
    public async Task<List<VocabularyDto>> GetPersonalizedRecommendationsAsync(
        Guid userId, int count = 10)
    {
        // 獲取用戶學習歷史和偏好
        var userProfile = await GetUserLearningProfileAsync(userId);
        
        // 使用GPT-4o-mini分析用戶需求
        var prompt = $@"
            Based on user learning profile:
            - Current level: {userProfile.Level}
            - Weak categories: {string.Join(',', userProfile.WeakCategories)}
            - Interests: {string.Join(',', userProfile.Interests)}
            
            Recommend 10 vocabulary words that would be most beneficial 
            for this learner's progression.";
            
        var aiResponse = await _openAiService.GetCompletionAsync(prompt);
        
        // 解析AI回應並匹配資料庫詞彙
        return await MatchWordsFromDatabase(aiResponse, count);
    }
}
```

#### 2.2 自適應複習系統
```csharp
public class AdaptiveReviewService : IAdaptiveReviewService
{
    public async Task<AdaptiveReviewSession> CreateReviewSessionAsync(Guid userId)
    {
        var dueWords = await _vocabularyService.GetDueForReviewAsync(userId);
        var userStats = await GetUserStatisticsAsync(userId);
        
        // 根據用戶表現調整複習策略
        var strategy = DetermineReviewStrategy(userStats);
        
        // 智能排序複習詞彙
        var optimizedOrder = OptimizeReviewOrder(dueWords, strategy);
        
        return new AdaptiveReviewSession
        {
            SessionId = Guid.NewGuid(),
            UserId = userId,
            Words = optimizedOrder,
            Strategy = strategy,
            EstimatedDuration = CalculateEstimatedDuration(optimizedOrder.Count)
        };
    }
    
    private ReviewStrategy DetermineReviewStrategy(UserStatistics stats)
    {
        // 基於用戶統計數據選擇最佳複習策略
        if (stats.AccuracyRate < 0.7)
            return ReviewStrategy.Reinforcement; // 加強練習
        else if (stats.ReviewStreak > 7)
            return ReviewStrategy.Challenging; // 挑戰模式
        else
            return ReviewStrategy.Balanced; // 平衡模式
    }
}
```

### 階段三：高級分析與遊戲化 (Week 7-9)

#### 3.1 學習分析API
```csharp
[ApiController]
[Route("api/v1/mobile/vocabulary/analytics")]
public class MobileVocabularyAnalyticsController : MobileBaseController
{
    [HttpGet("dashboard")]
    public async Task<ActionResult<MobileApiResponse<DashboardData>>> GetDashboard()
    {
        var userId = GetCurrentUserId();
        var data = new DashboardData
        {
            TodayProgress = await _analyticsService.GetTodayProgressAsync(userId),
            WeeklyStreak = await _analyticsService.GetWeeklyStreakAsync(userId),
            MasteryDistribution = await _analyticsService.GetMasteryDistributionAsync(userId),
            RecentAchievements = await _analyticsService.GetRecentAchievementsAsync(userId)
        };
        
        return MobileSuccess(data);
    }
    
    [HttpGet("progress-chart")]
    public async Task<ActionResult<MobileApiResponse<ProgressChartData>>> GetProgressChart(
        [FromQuery] ChartPeriod period = ChartPeriod.Month)
    {
        var userId = GetCurrentUserId();
        var chartData = await _analyticsService.GetProgressChartDataAsync(userId, period);
        
        return MobileSuccess(chartData);
    }
}
```

#### 3.2 遊戲化系統整合
```csharp
public interface IVocabularyGamificationService
{
    Task<AchievementResult> CheckAchievementsAsync(Guid userId, LearningActivity activity);
    Task<List<BadgeDto>> GetUserBadgesAsync(Guid userId);
    Task<LeaderboardPosition> GetLeaderboardPositionAsync(Guid userId);
    Task<int> CalculateExperiencePointsAsync(ReviewResult result);
}

public class VocabularyGamificationService : IVocabularyGamificationService
{
    public async Task<int> CalculateExperiencePointsAsync(ReviewResult result)
    {
        var basePoints = result.Quality switch
        {
            ReviewQuality.Again => 1,
            ReviewQuality.Hard => 3,
            ReviewQuality.Good => 5,
            ReviewQuality.Easy => 8,
            _ => 0
        };
        
        // 連續正確答案加成
        var streakMultiplier = Math.Min(result.StreakCount / 5.0 + 1, 2.0);
        
        // 詞彙難度加成
        var difficultyMultiplier = result.Difficulty switch
        {
            "A1" => 1.0,
            "A2" => 1.2,
            "B1" => 1.5,
            "B2" => 1.8,
            "C1" => 2.0,
            "C2" => 2.5,
            _ => 1.0
        };
        
        return (int)(basePoints * streakMultiplier * difficultyMultiplier);
    }
}
```

### 階段四：效能優化與快取 (Week 10-12)

#### 4.1 Redis快取策略
```csharp
public class CachedVocabularyService : IVocabularyService
{
    private readonly IVocabularyService _baseService;
    private readonly IRedisCache _cache;
    
    public async Task<VocabularyDto> GetByIdAsync(Guid vocabId)
    {
        var cacheKey = $"vocabulary:{vocabId}";
        var cached = await _cache.GetAsync<VocabularyDto>(cacheKey);
        
        if (cached != null)
            return cached;
            
        var vocabulary = await _baseService.GetByIdAsync(vocabId);
        await _cache.SetAsync(cacheKey, vocabulary, TimeSpan.FromHours(6));
        
        return vocabulary;
    }
    
    public async Task<List<VocabularyDto>> GetDueForReviewAsync(Guid userId)
    {
        var cacheKey = $"user:{userId}:due-review";
        var cached = await _cache.GetAsync<List<VocabularyDto>>(cacheKey);
        
        if (cached != null)
            return cached;
            
        var dueWords = await _baseService.GetDueForReviewAsync(userId);
        await _cache.SetAsync(cacheKey, dueWords, TimeSpan.FromMinutes(15));
        
        return dueWords;
    }
}
```

#### 4.2 資料庫查詢優化
```sql
-- 高效能索引設計
CREATE INDEX CONCURRENTLY idx_user_vocab_due_review 
ON user_vocabulary_progress(user_id, next_review_date) 
WHERE next_review_date <= CURRENT_DATE;

CREATE INDEX CONCURRENTLY idx_vocabulary_search 
ON vocabulary_bank USING gin(to_tsvector('english', word || ' ' || definition_en));

-- 用戶學習統計物化視圖
CREATE MATERIALIZED VIEW user_vocabulary_stats AS
SELECT 
    user_id,
    COUNT(*) as total_words,
    COUNT(*) FILTER (WHERE mastery_level = 'mastered') as mastered_count,
    AVG(mastery_score) as average_mastery,
    COUNT(*) FILTER (WHERE last_reviewed >= CURRENT_DATE - INTERVAL '7 days') as weekly_reviews
FROM user_vocabulary_progress
GROUP BY user_id;

CREATE UNIQUE INDEX ON user_vocabulary_stats(user_id);
```

### 詞彙學習API端點總結

#### 移動端API端點
| 端點 | 方法 | 描述 | 快取策略 |
|------|------|------|----------|
| `/api/v1/mobile/vocabulary/daily-review` | GET | 獲取每日複習詞彙 | 15分鐘 |
| `/api/v1/mobile/vocabulary/{id}/review` | POST | 提交複習結果 | 無快取 |
| `/api/v1/mobile/vocabulary/search` | GET | 詞彙搜尋 | 30分鐘 |
| `/api/v1/mobile/vocabulary/recommendations` | GET | 個人化推薦 | 1小時 |
| `/api/v1/mobile/vocabulary/analytics/dashboard` | GET | 學習儀表板 | 10分鐘 |

#### Web端API端點
| 端點 | 方法 | 描述 | 快取策略 |
|------|------|------|----------|
| `/api/v1/web/vocabulary/{id}` | GET | 詞彙詳細資訊 | 6小時 |
| `/api/v1/web/vocabulary/analytics` | GET | 學習分析報告 | 30分鐘 |
| `/api/v1/web/vocabulary/batch` | GET | 批量詞彙資料 | 1小時 |
| `/api/v1/web/vocabulary/export` | POST | 匯出學習資料 | 無快取 |

### 實施優先級

#### 高優先級 (Week 1-6)
1. 基礎詞彙CRUD API
2. 用戶學習進度追蹤
3. 間隔重複演算法
4. 移動端基礎API

#### 中優先級 (Week 7-9)  
1. AI推薦系統
2. 學習分析功能
3. 遊戲化元素
4. Web端豐富功能

#### 低優先級 (Week 10-12)
1. 效能優化
2. 進階快取策略
3. 資料匯出功能
4. 管理後台API

---

**最後更新**: 2025-09-10  
**版本**: 1.1 - 新增詞彙學習系統實施計畫  
**維護者**: Drama Ling 開發團隊