# 共同API規格 ## 📋 概述 **文檔名稱**: 跨平台API規格定義 **建立日期**: 2025-09-09 **適用平台**: Mobile App / Web App **API版本**: v1 **基礎URL**: `https://api.dramaling.com/api/v1` 本文檔定義了Drama Ling系統中所有平台通用的API接口規格。 ## 🔧 通用設計原則 ### RESTful 設計 - 使用標準HTTP方法 (GET, POST, PUT, DELETE) - 資源導向的URL設計 - 統一的狀態碼使用 - JSON格式的請求和回應 ### 認證機制 - JWT Bearer Token認證 - 訪問令牌有效期: 1小時 - 刷新令牌有效期: 30天 - 自動令牌刷新機制 ### 錯誤處理 - 統一的錯誤回應格式 - 多語言錯誤訊息支援 - 詳細的錯誤碼系統 ### 回應格式 ```typescript interface APIResponse { success: boolean; data?: T; error?: APIError; message: string; meta: { timestamp: string; requestId: string; version: string; }; } interface APIError { code: string; message: string; details?: any; } ``` ## 🔐 認證相關API ### 用戶註冊 ```http POST /auth/register Content-Type: application/json { "email": "user@example.com", "password": "securePassword123", "username": "learner123", "nativeLanguage": "zh-TW", "learningLanguages": ["en"] } ``` **回應**: ```typescript interface RegisterResponse { userId: string; username: string; email: string; accessToken: string; refreshToken: string; expiresIn: number; userRole: string; } ``` ### 用戶登入 ```http POST /auth/login Content-Type: application/json { "email": "user@example.com", "password": "securePassword123", "platform": "mobile" | "web", "rememberMe": boolean } ``` ### Token刷新 ```http POST /auth/refresh Authorization: Bearer ``` ### 第三方登入 ```http POST /auth/social Content-Type: application/json { "provider": "google" | "apple" | "facebook", "token": "social_provider_token", "platform": "mobile" | "web" } ``` ## 👤 用戶資料API ### 獲取用戶資料 ```http GET /users/profile Authorization: Bearer ``` ### 更新用戶資料 ```http PUT /users/profile Authorization: Bearer Content-Type: application/json { "username": "newUsername", "nativeLanguage": "zh-TW", "learningLanguages": ["en", "ja"], "profile": { "firstName": "John", "lastName": "Doe", "bio": "Language learning enthusiast" } } ``` ### 獲取學習進度 ```http GET /users/progress Authorization: Bearer Query Parameters: - skill: string (optional) - vocabulary|dialogue|pronunciation - timeframe: string (optional) - day|week|month|all ``` **回應**: ```typescript interface ProgressResponse { overallProgress: number; skillProgress: { vocabulary: SkillProgress; dialogue: SkillProgress; pronunciation: SkillProgress; }; recentAchievements: Achievement[]; nextGoals: Goal[]; } ``` ### 獲取遊戲統計 ```http GET /users/game-stats Authorization: Bearer ``` ## 📚 學習內容API ### 獲取階段列表 ```http GET /stages Authorization: Bearer Query Parameters: - language: string (required) - 語言代碼 - includeProgress: boolean (optional) - 是否包含進度資訊 ``` **回應**: ```typescript interface StagesList { stages: Array<{ stageId: string; stageName: string; description: string; order: number; totalScripts: number; unlockedScripts: number; completedScripts: number; isUnlocked: boolean; progress: { percentage: number; starsEarned: number; totalStars: number; }; }>; userProgress: { currentStageId: string; overallProgress: number; totalStarsEarned: number; }; } ``` ### 獲取劇本列表 ```http GET /scripts Authorization: Bearer Query Parameters: - stageId: string (required) - 階段ID - includeProgress: boolean (optional) ``` **回應**: ```typescript interface ScriptsList { scripts: Array<{ scriptId: string; scriptName: string; sceneDescription: { english: string; chinese: string; }; plotOutline: string; difficulty: number; estimatedTime: number; levels: { vocabulary: LevelStatus; mastery: LevelStatus; speaking?: LevelStatus; // 可選關卡 dialogue: LevelStatus; }; isUnlocked: boolean; requiredVocabulary: string[]; // 詞彙預覽 }>; } interface LevelStatus { isUnlocked: boolean; isCompleted: boolean; stars: number; bestScore?: number; } ``` ### 獲取劇本詳情 ```http GET /scripts/{scriptId} Authorization: Bearer ``` **回應**: ```typescript interface ScriptDetail { scriptId: string; scriptName: string; sceneDescription: { english: string; chinese: string; }; plotOutline: string; openingDialogue: Array<{ character: string; english: string; chinese: string; userRole: boolean; }>; plotTasks: Array<{ taskDescription: string; exampleEnglish: string; exampleChinese: string; }>; requiredVocabulary: VocabularyDetail[]; levels: { vocabulary: DetailedLevelInfo; mastery: DetailedLevelInfo; speaking?: DetailedLevelInfo; dialogue: DetailedLevelInfo; }; } interface DetailedLevelInfo { levelType: string; isUnlocked: boolean; isCompleted: boolean; stars: number; lifePointsCost: number; diamondsCost?: number; // 僅口說練習關卡 description: string; estimatedTime: number; prerequisites: string[]; rewards: { xp: number; diamonds?: number; items?: string[]; }; } ``` ### 獲取詞彙列表 ```http GET /vocabulary Authorization: Bearer Query Parameters: - language: string (required) - 語言代碼 - level: string (optional) - CEFR等級 (A1/A2/B1/B2/C1/C2) - category: string (optional) - 詞彙分類 - stageId: string (optional) - 關卡ID (用於獲取特定關卡的詞彙) - limit: number (optional) - 返回數量限制 (預設5) - offset: number (optional) - 偏移量 ``` ### 獲取詞彙詳情 ```http GET /vocabulary/{vocabularyId} Authorization: Bearer ``` **回應**: ```typescript interface VocabularyDetail { id: string; word: string; // 詞彙本體 (原形) level: string; // CEFR等級 (A1/A2/B1/B2/C1/C2) phonetic: string; // IPA音標 definition: string; // 英文定義 originalSentence: string; // Source句子 (學習者遇到的真實語境) originalHighlight: string; // Source句子中要標註的詞 exampleSentence: string; // Example句子 (教學例句) exampleHighlight: string; // Example句子中要標註的詞 audioFiles: { word: string; // 詞彙發音音檔URL example: string; // Example句子音檔URL }; imageUrl?: string; // Example句子配圖URL userProgress?: { masteryLevel: number; lastStudied: string; studyCount: number; completed: boolean; // 是否已完成瀏覽 }; } ``` ### 獲取對話列表 ```http GET /dialogues Authorization: Bearer Query Parameters: - difficulty: number (optional) - scenario: string (optional) - completed: boolean (optional) ``` ### 獲取對話詳情 ```http GET /dialogues/{dialogueId} Authorization: Bearer ``` ### 搜索學習內容 ```http GET /content/search Authorization: Bearer Query Parameters: - query: string (required) - 搜索關鍵詞 - type: string (optional) - vocabulary|dialogue|all - language: string (required) ``` ## 🎯 學習活動API ### 開始學習會話 ```http POST /learning/sessions Authorization: Bearer Content-Type: application/json { "type": "vocabulary" | "dialogue" | "review", "contentId": "content_uuid", "stageId": "stage_uuid", // 關卡ID (適用於詞彙學習) "settings": { "difficulty": number, "timeLimit": number, "hints": boolean, "autoPlay": boolean // 自動播放音檔設定 } } ``` **回應**: ```typescript interface SessionResponse { sessionId: string; content: LearningContent; vocabularyList?: VocabularyDetail[]; // 詞彙學習專用 questions: Question[]; // 對話學習專用 timeLimit: number; lifePointsCost: number; totalItems: number; // 總項目數 currentIndex: number; // 當前項目索引 } ``` ### 記錄詞彙瀏覽進度 ```http POST /learning/vocabulary/{vocabularyId}/viewed Authorization: Bearer Content-Type: application/json { "sessionId": "session_uuid", "timeSpent": number, // 瀏覽時間(秒) "audioPlayed": { "word": boolean, // 是否播放詞彙音檔 "example": boolean // 是否播放例句音檔 } } ``` **回應**: ```typescript interface VocabularyViewResponse { viewed: boolean; progress: { current: number; // 當前進度 total: number; // 總項目數 percentage: number; // 完成百分比 }; nextVocabularyId?: string; // 下一個詞彙ID stageCompleted: boolean; // 是否完成關卡 } ``` ### 提交答案 (對話學習專用) ```http POST /learning/sessions/{sessionId}/answers Authorization: Bearer Content-Type: application/json { "questionId": "question_uuid", "answer": any, "responseTime": number, "hintsUsed": number } ``` **回應**: ```typescript interface AnswerResponse { correct: boolean; correctAnswer?: any; explanation?: string; scoreGained: number; lifePointsLost: number; nextQuestion?: Question; } ``` ### 完成學習會話 ```http POST /learning/sessions/{sessionId}/complete Authorization: Bearer Content-Type: application/json { "completedItems": string[], // 已完成的詞彙ID列表 "totalTimeSpent": number, // 總學習時間(秒) "sessionType": "vocabulary" | "dialogue" | "review" } ``` **回應**: ```typescript interface SessionCompleteResponse { finalScore: number; accuracy: number; xpGained: number; diamondsGained: number; starsEarned: number; // 獲得星星數 (詞彙學習固定3星) vocabulariesMastered: number; // 掌握的詞彙數量 achievementsUnlocked: Achievement[]; nextRecommendations: Recommendation[]; stageCompleted: boolean; // 是否完成關卡 nextStageId?: string; // 下一關卡ID } ``` ### 獲取複習內容 ```http GET /learning/review Authorization: Bearer Query Parameters: - type: string (optional) - vocabulary|dialogue|all - limit: number (optional) ``` ## 🏆 遊戲化系統API ### 獲取成就列表 ```http GET /achievements Authorization: Bearer Query Parameters: - category: string (optional) - completed: boolean (optional) ``` ### 獲取用戶道具 ```http GET /inventory Authorization: Bearer ``` ### 使用道具 ```http POST /inventory/use Authorization: Bearer Content-Type: application/json { "itemId": "item_uuid", "quantity": number, "context": { "sessionId": "session_uuid" } } ``` ### 購買道具 ```http POST /store/purchase Authorization: Bearer Content-Type: application/json { "itemId": "item_uuid", "quantity": number, "paymentMethod": "diamonds" | "learning_coins" | "real_money" } ``` ### 獲取排行榜 ```http GET /leaderboard Authorization: Bearer Query Parameters: - type: string - xp|vocabulary|dialogue|streak - timeframe: string - day|week|month|all - limit: number (optional) ``` ### 使用時光卷 ```http POST /items/time-warp/use Authorization: Bearer Content-Type: application/json { "itemId": "time_warp_scroll_uuid", "preferredStages": string[] // 用戶偏好的階段ID (可選) } ``` **回應**: ```typescript interface TimeWarpChallengeResponse { challengeId: string; selectedScript: { scriptId: string; scriptName: string; stageId: string; stageName: string; isFromPreviousStage: boolean; }; challenge: { type: "dialogue"; // 目前固定為對話訓練 timeLimit: number; // 挑戰時間限制(秒) specialRewards: { bonus_xp: number; bonus_diamonds: number; vocabulary_review: boolean; // 詞彙加入複習清單 }; }; sessionData: any; // 關卡具體數據 } ``` ## 📺 廣告系統API ### 請求觀看廣告 ```http POST /ads/request Authorization: Bearer Content-Type: application/json { "adType": "life_points_restore" | "bonus_rewards" | "unlock_content", "context": { "currentLifePoints": number, "maxLifePoints": number, "sessionId"?: string, "itemType"?: string // 額外獎勵的道具類型 } } ``` **回應**: ```typescript interface AdRequestResponse { adAvailable: boolean; adId?: string; adProvider: "google_admob" | "unity_ads" | "facebook_ads"; estimatedDuration: number; // 預估廣告時長(秒) rewards: { lifePoints?: number; // 恢復的命條數量 diamonds?: number; // 獲得鑽石 xp?: number; // 額外經驗值 items?: string[]; // 獲得道具ID列表 }; cooldownTime?: number; // 下次可觀看時間(秒) dailyLimit: { watched: number; maximum: number; }; } ``` ### 完成廣告觀看 ```http POST /ads/complete Authorization: Bearer Content-Type: application/json { "adId": string, "adProvider": string, "watchDuration": number, // 實際觀看時長(秒) "completed": boolean, // 是否完整觀看 "rewardClaimed": boolean // 是否領取獎勵 } ``` **回應**: ```typescript interface AdCompleteResponse { success: boolean; rewardsGranted: { lifePoints?: number; diamonds?: number; xp?: number; items?: Array<{ itemId: string; quantity: number; name: string; }>; }; updatedUserStats: { currentLifePoints: number; totalDiamonds: number; totalXP: number; }; nextAdAvailableAt?: string; // ISO timestamp } ``` ### 獲取廣告狀態 ```http GET /ads/status Authorization: Bearer Query Parameters: - adType: string (optional) ``` **回應**: ```typescript interface AdStatusResponse { dailyStats: { adsWatched: number; maxAdsPerDay: number; resetTime: string; // ISO timestamp }; availableAdTypes: Array<{ type: string; available: boolean; cooldownEndsAt?: string; // ISO timestamp estimatedReward: any; }>; userPreferences: { adsEnabled: boolean; preferredProviders: string[]; }; } ``` ## 📊 分析與報告API ### 獲取學習分析 ```http GET /analytics/learning Authorization: Bearer Query Parameters: - startDate: string (YYYY-MM-DD) - endDate: string (YYYY-MM-DD) - granularity: string - day|week|month ``` **回應**: ```typescript interface LearningAnalytics { timeRange: { start: string; end: string; }; summary: { totalStudyTime: number; wordsLearned: number; dialoguesCompleted: number; overallAccuracy: number; streakDays: number; }; skillBreakdown: SkillAnalytics[]; progressTrend: DataPoint[]; weakAreas: WeakArea[]; recommendations: string[]; } ``` ### 導出學習數據 ```http GET /analytics/export Authorization: Bearer Query Parameters: - format: string - json|csv|pdf - startDate: string - endDate: string - includePersonal: boolean ``` ## 🗣️ 口說評分系統API ### 提交語音進行評分 ```http POST /speaking/evaluate Authorization: Bearer Content-Type: multipart/form-data { "audioFile": File, // 語音文件 (wav/mp3) "sessionId": "session_uuid", // 學習會話ID "contentType": "vocabulary" | "dialogue" | "pronunciation", "targetText": string, // 預期文本內容 "language": "en" | "zh-TW", "evaluationType": "five_dimension" | "basic" } ``` **回應**: ```typescript interface SpeakingEvaluation { sessionId: string; overallScore: number; // 0-100 總分 dimensions: { pronunciation: number; // 發音評分 completeness: number; // 完整度評分 fluency: number; // 流暢度評分 prosody: number; // 韻律評分 accuracy: number; // 準確度評分 }; detailedFeedback: { problemWords: Array<{ word: string; issues: string[]; // 發音問題描述 phonemes: string[]; // 問題音素 }>; suggestions: string[]; // 改善建議 strengths: string[]; // 優點反饋 }; rewards?: { diamonds: number; xp: number; items?: string[]; // 獲得道具 (如時光卷) }; } ``` ### 獲取口說評分歷史 ```http GET /speaking/history Authorization: Bearer Query Parameters: - contentType: string (optional) - limit: number (optional) - offset: number (optional) ``` ## 🎭 語用分析系統API ### 對話語用分析 ```http POST /dialogue/pragmatic-analysis Authorization: Bearer Content-Type: application/json { "sessionId": "session_uuid", "userMessage": string, "dialogueContext": { "scenario": string, "previousTurns": Array<{ "speaker": "user" | "ai", "message": string, "timestamp": string }>, "intents": string[] // 預期完成的意圖任務 } } ``` **回應**: ```typescript interface PragmaticAnalysis { sessionId: string; analysisId: string; dimensions: { smallTalk: { present: boolean; examples?: string[]; suggestions?: string[]; }; indirectness: { level: "direct" | "moderately_indirect" | "highly_indirect"; examples?: string[]; culturalNotes?: string[]; }; fillers: { count: number; types: string[]; appropriateness: "natural" | "excessive" | "insufficient"; }; backchanneling: { present: boolean; effectiveness: "good" | "adequate" | "needs_improvement"; examples?: string[]; }; hedging: { level: "confident" | "appropriately_cautious" | "overly_cautious"; examples?: string[]; }; idioms: { used: Array<{ idiom: string; appropriateness: "perfect" | "good" | "awkward"; culturalFit: boolean; }>; suggestions?: string[]; }; }; overallAssessment: { communicativeEffectiveness: "excellent" | "good" | "adequate" | "needs_work"; culturalApproppriateness: "excellent" | "good" | "adequate" | "needs_work"; suggestions: string[]; strengths: string[]; }; intentCompletion: { completedIntents: string[]; partialIntents: string[]; missedIntents: string[]; completionRate: number; // 0-100 }; } ``` ### 獲取語用分析建議 ```http GET /dialogue/pragmatic-suggestions Authorization: Bearer Query Parameters: - scenario: string - userLevel: string (optional) - beginner|intermediate|advanced ``` ## 🔄 實時功能API ### WebSocket連接 (適用於Web端) ``` WSS /ws/learning Authorization: Bearer ``` **支援事件**: - `session_start` - 學習會話開始 - `question_answered` - 回答題目 - `achievement_unlocked` - 解鎖成就 - `life_point_restored` - 命條恢復 - `friend_activity` - 好友活動通知 ### 推送通知API (適用於Mobile端) ```http POST /notifications/register Authorization: Bearer Content-Type: application/json { "deviceToken": "fcm_device_token", "platform": "ios" | "android", "preferences": { "studyReminders": boolean, "achievements": boolean, "friends": boolean } } ``` ## 🌐 多語言支援API ### 獲取語言包 ```http GET /localization/{languageCode} Query Parameters: - version: string (optional) - 語言包版本號 ``` ### 獲取支援語言列表 ```http GET /localization/languages ``` ## 🛡️ 資料保護API ### 請求數據導出 ```http POST /privacy/export-request Authorization: Bearer ``` ### 請求帳戶刪除 ```http POST /privacy/delete-request Authorization: Bearer Content-Type: application/json { "reason": string, "confirmPassword": string } ``` ### 更新隱私設定 ```http PUT /privacy/settings Authorization: Bearer Content-Type: application/json { "dataCollection": boolean, "analytics": boolean, "marketing": boolean, "thirdPartySharing": boolean } ``` ## 📈 API限流規則 ### 頻率限制 | 端點類別 | 限制 | 時間窗口 | |---------|------|----------| | 認證相關 | 5次 | 每分鐘 | | 學習內容 | 100次 | 每分鐘 | | 學習活動 | 50次 | 每分鐘 | | 分析報告 | 10次 | 每分鐘 | | 通用查詢 | 200次 | 每分鐘 | ### 限流回應 ```http HTTP/1.1 429 Too Many Requests Retry-After: 60 { "success": false, "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Request rate limit exceeded" } } ``` ## 🔍 錯誤碼參考 ### 認證錯誤 (4xx) - `INVALID_CREDENTIALS` (401) - 登入憑證錯誤 - `TOKEN_EXPIRED` (401) - Token已過期 - `TOKEN_INVALID` (401) - Token格式錯誤 - `INSUFFICIENT_PERMISSIONS` (403) - 權限不足 ### 業務邏輯錯誤 (4xx) - `INSUFFICIENT_LIFE_POINTS` (402) - 命條不足 - `CONTENT_NOT_FOUND` (404) - 學習內容不存在 - `SESSION_EXPIRED` (410) - 學習會話已過期 - `INVALID_ANSWER_FORMAT` (422) - 答案格式錯誤 ### 系統錯誤 (5xx) - `INTERNAL_SERVER_ERROR` (500) - 內部伺服器錯誤 - `DATABASE_ERROR` (503) - 資料庫連接錯誤 - `THIRD_PARTY_SERVICE_ERROR` (503) - 第三方服務錯誤 ## 📋 API測試 ### 測試端點 ``` 開發環境: https://dev-api.dramaling.com/api/v1 測試環境: https://test-api.dramaling.com/api/v1 生產環境: https://api.dramaling.com/api/v1 ``` ### 測試帳號 ``` 測試用戶: test@dramaling.com 測試密碼: TestUser123456 測試Token: 開發環境提供長效測試Token ``` ### Postman Collection - 完整API集合下載: `/docs/api/postman-collection.json` - 環境變數設定: `/docs/api/postman-environment.json` --- **文檔狀態**: 🟢 已完成 **最後更新**: 2025-09-12 **版本**: v2.0 - 新增口說評分、語用分析、階段系統、廣告系統API **相關文檔**: - `business-rules.md` - 業務邏輯規則 - `data-models.md` - 數據結構定義 - `progressive-stage-system.md` - 線性闖關學習系統 - `speaking-evaluation-specs.md` - 口說評分系統規格 - `pragmatic-analysis-specs.md` - 語用分析系統規格 - `../mobile/` - 移動端功能規格 - `../web/` - Web端功能規格 - `/swagger-ui.html` - 互動式API文檔