998 lines
23 KiB
Markdown
998 lines
23 KiB
Markdown
# API 規格文檔
|
||
|
||
## 概述
|
||
定義 Drama Ling 應用的完整 RESTful API 規格,基於 `system_structure_design.json` 中定義的14個功能特性和9個數據源設計。
|
||
|
||
## API 設計原則
|
||
|
||
### RESTful 設計標準
|
||
- [ ] **資源導向**: API端點基於資源設計而非動作
|
||
- [ ] **HTTP動詞**: 正確使用GET、POST、PUT、DELETE、PATCH
|
||
- [ ] **狀態碼**: 使用標準HTTP狀態碼表示結果
|
||
- [ ] **無狀態**: API設計為無狀態,不依賴server端session
|
||
- [ ] **版本控制**: API版本控制策略 (如 `/api/v1/`)
|
||
|
||
### API 安全原則
|
||
- [ ] **身份驗證**: JWT Token認證機制
|
||
- [ ] **授權控制**: Role-based權限控制
|
||
- [ ] **資料驗證**: 嚴格的輸入資料驗證
|
||
- [ ] **速率限制**: 防止API濫用的速率控制
|
||
- [ ] **HTTPS強制**: 所有API強制使用HTTPS
|
||
|
||
### 回應格式標準
|
||
```json
|
||
{
|
||
"success": boolean,
|
||
"data": object | array | null,
|
||
"message": string,
|
||
"error": {
|
||
"code": string,
|
||
"message": string,
|
||
"details": object
|
||
},
|
||
"meta": {
|
||
"timestamp": "ISO8601",
|
||
"request_id": "string",
|
||
"pagination": object
|
||
}
|
||
}
|
||
```
|
||
|
||
## 認證與授權 API
|
||
|
||
### 用戶認證
|
||
```http
|
||
POST /api/v1/auth/register
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"email": "user@example.com",
|
||
"password": "securePassword123",
|
||
"username": "dramatic_learner",
|
||
"preferredLanguage": "en",
|
||
"nativeLanguage": "zh-TW"
|
||
}
|
||
```
|
||
|
||
```http
|
||
Response 201 Created
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"userId": "550e8400-e29b-41d4-a716-446655440000",
|
||
"username": "dramatic_learner",
|
||
"email": "user@example.com",
|
||
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||
"refreshToken": "550e8400-e29b-41d4-a716-446655440001",
|
||
"expiresIn": 3600
|
||
},
|
||
"message": "User registered successfully",
|
||
"meta": {
|
||
"timestamp": "2024-09-05T15:30:00Z",
|
||
"requestId": "550e8400-e29b-41d4-a716-446655440002"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 登入驗證
|
||
```http
|
||
POST /api/v1/auth/login
|
||
{
|
||
"email": "user@example.com",
|
||
"password": "securePassword123"
|
||
}
|
||
```
|
||
|
||
### Token 更新
|
||
```http
|
||
POST /api/v1/auth/refresh
|
||
Authorization: Bearer <refresh_token>
|
||
```
|
||
|
||
### 登出
|
||
```http
|
||
POST /api/v1/auth/logout
|
||
Authorization: Bearer <access_token>
|
||
```
|
||
|
||
## 用戶資料管理 API
|
||
|
||
### 用戶資料 (UserProfile)
|
||
|
||
#### 獲取用戶資料
|
||
```http
|
||
GET /api/v1/users/profile
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"user_id": "USR_12345",
|
||
"username": "dramatic_learner",
|
||
"email": "user@example.com",
|
||
"avatar_url": "https://cdn.example.com/avatars/12345.jpg",
|
||
"level": "B1",
|
||
"total_score": 15680,
|
||
"streak_days": 15,
|
||
"joined_date": "2024-01-15T08:00:00Z",
|
||
"last_active": "2024-09-05T14:30:00Z",
|
||
"preferences": {
|
||
"target_language": "en",
|
||
"native_language": "zh-TW",
|
||
"difficulty_preference": "adaptive",
|
||
"daily_goal_minutes": 30,
|
||
"notifications_enabled": true,
|
||
"theme": "light"
|
||
},
|
||
"subscription": {
|
||
"plan": "premium",
|
||
"status": "active",
|
||
"expires_at": "2025-01-15T08:00:00Z"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 更新用戶資料
|
||
```http
|
||
PUT /api/v1/users/profile
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"username": "new_username",
|
||
"avatar_url": "https://cdn.example.com/avatars/new_avatar.jpg",
|
||
"preferences": {
|
||
"daily_goal_minutes": 45,
|
||
"notifications_enabled": false
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 用戶學習統計
|
||
```http
|
||
GET /api/v1/users/stats
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"total_dialogues": 245,
|
||
"total_study_time": 1280, // minutes
|
||
"vocabulary_learned": 890,
|
||
"vocabulary_mastered": 650,
|
||
"scenarios_completed": 35,
|
||
"achievements_unlocked": 18,
|
||
"current_streak": 15,
|
||
"longest_streak": 28,
|
||
"weekly_progress": {
|
||
"dialogues_this_week": 12,
|
||
"minutes_this_week": 180,
|
||
"goal_completion_rate": 0.85
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 學習內容 API
|
||
|
||
### 課程與場景 (Lesson)
|
||
|
||
#### 獲取場景列表
|
||
```http
|
||
GET /api/v1/lessons/scenarios
|
||
Authorization: Bearer <access_token>
|
||
Query Parameters:
|
||
- category: string (daily_life, social, emergency, professional)
|
||
- difficulty: string (A1, A2, B1, B2, C1, C2)
|
||
- limit: integer (default: 20)
|
||
- offset: integer (default: 0)
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"scenarios": [
|
||
{
|
||
"scenario_id": "SC_Restaurant_01",
|
||
"title": "餐廳訂位",
|
||
"description": "學習如何在餐廳預約座位和點餐",
|
||
"category": "daily_life",
|
||
"difficulty": "A2",
|
||
"estimated_duration": 8, // minutes
|
||
"thumbnail_url": "https://cdn.example.com/scenarios/restaurant.jpg",
|
||
"vocabulary_count": 25,
|
||
"completion_rate": 0.75,
|
||
"user_completed": true,
|
||
"user_score": 85,
|
||
"unlock_condition": null,
|
||
"is_premium": false
|
||
}
|
||
],
|
||
"pagination": {
|
||
"total": 65,
|
||
"page": 1,
|
||
"per_page": 20,
|
||
"total_pages": 4
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 獲取場景詳情
|
||
```http
|
||
GET /api/v1/lessons/scenarios/{scenario_id}
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"scenario_id": "SC_Restaurant_01",
|
||
"title": "餐廳訂位",
|
||
"description": "學習如何在餐廳預約座位和點餐",
|
||
"category": "daily_life",
|
||
"difficulty": "A2",
|
||
"learning_objectives": [
|
||
"學會預約餐廳座位",
|
||
"掌握點餐相關詞彙",
|
||
"練習詢問食材和偏好"
|
||
],
|
||
"target_vocabulary": [
|
||
{
|
||
"word": "reservation",
|
||
"phonetic": "/ˌrezəˈveɪʃən/",
|
||
"translation": "預約",
|
||
"definition": "an arrangement to have something kept for you"
|
||
}
|
||
],
|
||
"cultural_notes": "西式餐廳通常需要事先預約,特別是在熱門時段...",
|
||
"estimated_duration": 8,
|
||
"prerequisite_scenarios": ["SC_Greeting_01"],
|
||
"user_progress": {
|
||
"completed": true,
|
||
"best_score": 85,
|
||
"completion_count": 3,
|
||
"last_completed": "2024-09-03T19:20:00Z"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 詞彙管理 API
|
||
|
||
#### 獲取詞彙列表
|
||
```http
|
||
GET /api/v1/vocabulary
|
||
Authorization: Bearer <access_token>
|
||
Query Parameters:
|
||
- category: string (life, academic, business, etc.)
|
||
- difficulty: string (A1-C2)
|
||
- mastery_level: string (learning, practicing, mastered)
|
||
- limit: integer (default: 50)
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"vocabulary": [
|
||
{
|
||
"vocab_id": "VOC_0001",
|
||
"word": "restaurant",
|
||
"phonetic": "/ˈrestərɑːnt/",
|
||
"part_of_speech": "noun",
|
||
"definition": "A place where people pay to sit and eat meals",
|
||
"translation": "餐廳",
|
||
"difficulty": "A2",
|
||
"frequency_rank": 1250,
|
||
"user_mastery": {
|
||
"level": "practicing", // learning, practicing, mastered
|
||
"score": 75,
|
||
"review_count": 5,
|
||
"last_reviewed": "2024-09-03T10:15:00Z",
|
||
"next_review": "2024-09-07T10:15:00Z"
|
||
},
|
||
"example_sentences": [
|
||
{
|
||
"english": "We made a reservation at the new restaurant.",
|
||
"chinese": "我們在新餐廳訂了位。"
|
||
}
|
||
]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 詞彙複習API
|
||
```http
|
||
GET /api/v1/vocabulary/review/daily
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"review_session_id": "REV_20240905_USR12345",
|
||
"total_words": 15,
|
||
"estimated_time": 5, // minutes
|
||
"words": [
|
||
{
|
||
"vocab_id": "VOC_0001",
|
||
"word": "restaurant",
|
||
"review_type": "recognition", // recognition, recall, spelling
|
||
"options": ["餐廳", "旅館", "商店", "學校"] // for recognition type
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 提交複習結果
|
||
```http
|
||
POST /api/v1/vocabulary/review/submit
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"review_session_id": "REV_20240905_USR12345",
|
||
"results": [
|
||
{
|
||
"vocab_id": "VOC_0001",
|
||
"user_answer": "餐廳",
|
||
"is_correct": true,
|
||
"response_time": 2.5, // seconds
|
||
"confidence": 4 // 1-5 scale
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
## 對話練習 API
|
||
|
||
### 對話系統 (Dialogue)
|
||
|
||
#### 開始對話練習
|
||
```http
|
||
POST /api/v1/dialogues/start
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"scenario_id": "SC_Restaurant_01",
|
||
"difficulty_override": "A2", // optional
|
||
"target_vocabulary": ["reservation", "menu", "order"] // optional
|
||
}
|
||
|
||
Response 201 Created
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"dialogue_id": "DLG_20240905_001",
|
||
"scenario_id": "SC_Restaurant_01",
|
||
"session_token": "session_token_here",
|
||
"initial_context": {
|
||
"setting": "高級餐廳內部,晚上8點",
|
||
"your_role": "客人",
|
||
"ai_role": "餐廳服務員",
|
||
"objective": "成功預約並點餐"
|
||
},
|
||
"ai_message": {
|
||
"message": "Good evening! Welcome to Milano Restaurant. Do you have a reservation?",
|
||
"audio_url": "https://cdn.example.com/audio/dlg001_001.mp3",
|
||
"suggestions": [
|
||
"Yes, I have a reservation under Smith.",
|
||
"No, but could we get a table for two?",
|
||
"I'd like to make a reservation for tonight."
|
||
]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 發送對話訊息
|
||
```http
|
||
POST /api/v1/dialogues/{dialogue_id}/message
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"message": "Yes, I have a reservation under Chen for 8 PM.",
|
||
"message_type": "text", // text, audio
|
||
"audio_url": "https://cdn.example.com/user_audio/msg001.mp3" // if audio
|
||
}
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"ai_response": {
|
||
"message": "Perfect! Mr. Chen, your table for two is ready. Right this way please.",
|
||
"audio_url": "https://cdn.example.com/audio/dlg001_002.mp3",
|
||
"analysis": {
|
||
"grammar_score": 90,
|
||
"semantic_score": 95,
|
||
"fluency_score": 85,
|
||
"overall_score": 90,
|
||
"feedback": "Excellent use of formal language for restaurant context!"
|
||
},
|
||
"suggestions": [
|
||
"Thank you. Could we see the menu please?",
|
||
"Great! What do you recommend today?",
|
||
"Thank you. We'd like to start with drinks."
|
||
]
|
||
},
|
||
"dialogue_progress": {
|
||
"turns_completed": 2,
|
||
"estimated_turns_remaining": 6,
|
||
"objectives_completed": ["greeting", "reservation_confirmation"],
|
||
"objectives_remaining": ["ordering", "payment"]
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 獲取AI分析詳情
|
||
```http
|
||
GET /api/v1/dialogues/{dialogue_id}/analysis
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"dialogue_id": "DLG_20240905_001",
|
||
"overall_analysis": {
|
||
"grammar_score": 88,
|
||
"semantic_score": 92,
|
||
"fluency_score": 85,
|
||
"total_score": 88,
|
||
"completion_percentage": 100
|
||
},
|
||
"detailed_feedback": [
|
||
{
|
||
"turn_number": 1,
|
||
"user_message": "Yes, I have a reservation under Chen for 8 PM.",
|
||
"analysis": {
|
||
"grammar_issues": [],
|
||
"semantic_appropriateness": "Excellent - appropriate formality level",
|
||
"fluency_notes": "Natural and confident delivery",
|
||
"suggestions": [],
|
||
"vocabulary_used": [
|
||
{
|
||
"word": "reservation",
|
||
"usage_correctness": "perfect",
|
||
"context_appropriateness": "excellent"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
],
|
||
"improvement_suggestions": [
|
||
"Consider using more varied vocabulary for ordering",
|
||
"Practice pronunciation of 'th' sounds"
|
||
],
|
||
"vocabulary_progress": {
|
||
"words_practiced": 8,
|
||
"words_used_correctly": 7,
|
||
"new_words_encountered": 3
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 結束對話
|
||
```http
|
||
POST /api/v1/dialogues/{dialogue_id}/complete
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"dialogue_summary": {
|
||
"dialogue_id": "DLG_20240905_001",
|
||
"duration": 420, // seconds
|
||
"turns_completed": 8,
|
||
"final_score": 88,
|
||
"objectives_achieved": 4,
|
||
"objectives_total": 4,
|
||
"vocabulary_practiced": 12,
|
||
"experience_gained": 150,
|
||
"score_gained": 75
|
||
},
|
||
"rewards": {
|
||
"experience_points": 150,
|
||
"score_points": 75,
|
||
"achievements_unlocked": ["First Perfect Dialogue"],
|
||
"vocabulary_progress": {
|
||
"words_advanced": 3,
|
||
"words_mastered": 1
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 任務系統 API
|
||
|
||
### 任務管理 (Task & TaskReward)
|
||
|
||
#### 獲取可用任務
|
||
```http
|
||
GET /api/v1/tasks
|
||
Authorization: Bearer <access_token>
|
||
Query Parameters:
|
||
- type: string (daily, weekly, achievement, challenge)
|
||
- status: string (available, in_progress, completed)
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"tasks": [
|
||
{
|
||
"task_id": "TASK_DAILY_001",
|
||
"type": "daily",
|
||
"title": "完成3次對話練習",
|
||
"description": "今天完成任意3次對話練習以獲得獎勵",
|
||
"objectives": [
|
||
{
|
||
"objective_id": "OBJ_001",
|
||
"description": "完成對話練習",
|
||
"target_value": 3,
|
||
"current_value": 1,
|
||
"unit": "次"
|
||
}
|
||
],
|
||
"rewards": {
|
||
"experience": 100,
|
||
"score": 50,
|
||
"special_items": ["daily_streak_bonus"]
|
||
},
|
||
"deadline": "2024-09-05T23:59:59Z",
|
||
"status": "in_progress",
|
||
"created_at": "2024-09-05T00:00:00Z"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 獲取任務詳情
|
||
```http
|
||
GET /api/v1/tasks/{task_id}
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"task_id": "TASK_WEEKLY_001",
|
||
"type": "weekly",
|
||
"title": "週練習大師",
|
||
"description": "本週完成20次對話練習並達到平均85分",
|
||
"long_description": "挑戰自己在本週內完成20次高品質的對話練習...",
|
||
"objectives": [
|
||
{
|
||
"objective_id": "OBJ_001",
|
||
"description": "完成對話練習",
|
||
"target_value": 20,
|
||
"current_value": 8,
|
||
"unit": "次"
|
||
},
|
||
{
|
||
"objective_id": "OBJ_002",
|
||
"description": "平均分數達標",
|
||
"target_value": 85,
|
||
"current_value": 87.5,
|
||
"unit": "分"
|
||
}
|
||
],
|
||
"rewards": {
|
||
"experience": 500,
|
||
"score": 300,
|
||
"special_items": ["premium_scenario_unlock"],
|
||
"achievements": ["weekly_master"]
|
||
},
|
||
"progress_percentage": 40,
|
||
"deadline": "2024-09-08T23:59:59Z",
|
||
"difficulty": "medium"
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 領取任務獎勵
|
||
```http
|
||
POST /api/v1/tasks/{task_id}/claim_reward
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"rewards_claimed": {
|
||
"experience": 500,
|
||
"score": 300,
|
||
"special_items": ["premium_scenario_unlock"],
|
||
"achievements": ["weekly_master"]
|
||
},
|
||
"updated_user_stats": {
|
||
"total_experience": 15680,
|
||
"total_score": 8950,
|
||
"level": "B1+",
|
||
"achievements_count": 19
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 排行榜與競爭 API
|
||
|
||
### 排行榜系統 (Leaderboard)
|
||
|
||
#### 獲取排行榜
|
||
```http
|
||
GET /api/v1/leaderboard
|
||
Authorization: Bearer <access_token>
|
||
Query Parameters:
|
||
- type: string (global, weekly, friends, regional)
|
||
- category: string (overall, dialogue_count, vocabulary_mastered)
|
||
- limit: integer (default: 50)
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"leaderboard_type": "global",
|
||
"category": "overall",
|
||
"period": "all_time",
|
||
"updated_at": "2024-09-05T15:30:00Z",
|
||
"user_rank": {
|
||
"rank": 1247,
|
||
"score": 15680,
|
||
"percentile": 78.5
|
||
},
|
||
"top_users": [
|
||
{
|
||
"rank": 1,
|
||
"user_id": "USR_VIP_001",
|
||
"username": "LanguageMaster",
|
||
"avatar_url": "https://cdn.example.com/avatars/vip001.jpg",
|
||
"score": 45680,
|
||
"level": "C2",
|
||
"country": "TW",
|
||
"streak_days": 365,
|
||
"badges": ["yearly_champion", "perfectionist"]
|
||
}
|
||
],
|
||
"nearby_users": [
|
||
// Users around current user's rank
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 好友排行榜
|
||
```http
|
||
GET /api/v1/leaderboard/friends
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"friends_ranking": [
|
||
{
|
||
"rank": 1,
|
||
"user_id": "USR_12346",
|
||
"username": "StudyBuddy",
|
||
"avatar_url": "https://cdn.example.com/avatars/12346.jpg",
|
||
"score": 18950,
|
||
"level": "B2",
|
||
"status": "online",
|
||
"recent_activity": "完成了商務會議場景 - 2小時前"
|
||
}
|
||
],
|
||
"current_user": {
|
||
"rank": 3,
|
||
"score": 15680,
|
||
"score_difference": -3270, // difference from rank 1
|
||
"rank_change": 1 // compared to last week
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 訂閱與購買 API
|
||
|
||
### 訂閱管理 (Subscription)
|
||
|
||
#### 獲取訂閱方案
|
||
```http
|
||
GET /api/v1/subscriptions/plans
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"plans": [
|
||
{
|
||
"plan_id": "PLAN_BASIC",
|
||
"name": "基礎版",
|
||
"description": "解鎖基礎功能,享受無廣告體驗",
|
||
"price": {
|
||
"monthly": {
|
||
"amount": 199,
|
||
"currency": "TWD",
|
||
"original_price": 199
|
||
},
|
||
"yearly": {
|
||
"amount": 1980,
|
||
"currency": "TWD",
|
||
"original_price": 2388,
|
||
"discount_percentage": 17
|
||
}
|
||
},
|
||
"features": [
|
||
"無限對話練習",
|
||
"無廣告體驗",
|
||
"基礎AI分析",
|
||
"雲端同步"
|
||
],
|
||
"limitations": [
|
||
"僅基礎和社交場景",
|
||
"不含語音識別"
|
||
]
|
||
}
|
||
],
|
||
"current_subscription": {
|
||
"plan_id": "PLAN_PREMIUM",
|
||
"status": "active",
|
||
"expires_at": "2025-01-15T08:00:00Z",
|
||
"auto_renewal": true,
|
||
"payment_method": "credit_card"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 訂閱方案
|
||
```http
|
||
POST /api/v1/subscriptions/subscribe
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"plan_id": "PLAN_PREMIUM",
|
||
"billing_cycle": "yearly", // monthly, yearly
|
||
"payment_method_id": "pm_1234567890",
|
||
"auto_renewal": true
|
||
}
|
||
|
||
Response 201 Created
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"subscription_id": "SUB_20240905_001",
|
||
"plan_id": "PLAN_PREMIUM",
|
||
"status": "active",
|
||
"started_at": "2024-09-05T15:30:00Z",
|
||
"expires_at": "2025-09-05T15:30:00Z",
|
||
"next_billing_date": "2025-09-05T15:30:00Z",
|
||
"amount_paid": 3999,
|
||
"currency": "TWD"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 內購系統 (Purchase)
|
||
|
||
#### 獲取付費內容
|
||
```http
|
||
GET /api/v1/store/content
|
||
Authorization: Bearer <access_token>
|
||
Query Parameters:
|
||
- category: string (scenario_pack, expert_course, premium_content)
|
||
- price_range: string (0-100, 100-500, 500+)
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"content_packs": [
|
||
{
|
||
"content_id": "PACK_TRAVEL_001",
|
||
"type": "scenario_pack",
|
||
"title": "旅遊場景包",
|
||
"description": "包含機場、飯店、觀光等15個實用旅遊場景",
|
||
"price": {
|
||
"amount": 149,
|
||
"currency": "TWD",
|
||
"original_price": 199,
|
||
"discount_percentage": 25
|
||
},
|
||
"content_preview": {
|
||
"scenarios_count": 15,
|
||
"estimated_hours": 8,
|
||
"difficulty_range": "A2-B2",
|
||
"preview_scenario": "SC_AIRPORT_001"
|
||
},
|
||
"thumbnail_url": "https://cdn.example.com/packs/travel.jpg",
|
||
"user_owned": false,
|
||
"special_offer": {
|
||
"expires_at": "2024-09-10T23:59:59Z",
|
||
"offer_text": "限時75折優惠!"
|
||
}
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 購買內容
|
||
```http
|
||
POST /api/v1/store/purchase
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"content_id": "PACK_TRAVEL_001",
|
||
"payment_method_id": "pm_1234567890"
|
||
}
|
||
|
||
Response 201 Created
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"purchase_id": "PUR_20240905_001",
|
||
"content_id": "PACK_TRAVEL_001",
|
||
"amount_paid": 149,
|
||
"currency": "TWD",
|
||
"purchased_at": "2024-09-05T15:45:00Z",
|
||
"content_unlocked": {
|
||
"scenarios": ["SC_AIRPORT_001", "SC_HOTEL_001", "..."],
|
||
"access_expires": null // permanent access
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 廣告系統 (AdImpression)
|
||
|
||
#### 獲取廣告獎勵機會
|
||
```http
|
||
GET /api/v1/ads/opportunities
|
||
Authorization: Bearer <access_token>
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"available_ads": [
|
||
{
|
||
"ad_id": "AD_REWARD_001",
|
||
"type": "video",
|
||
"duration": 30, // seconds
|
||
"reward": {
|
||
"type": "extra_dialogue",
|
||
"quantity": 2,
|
||
"description": "額外2次對話練習機會"
|
||
},
|
||
"cooldown_remaining": 0, // seconds until next ad
|
||
"daily_limit_remaining": 3
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 觀看廣告獲得獎勵
|
||
```http
|
||
POST /api/v1/ads/watch
|
||
Authorization: Bearer <access_token>
|
||
{
|
||
"ad_id": "AD_REWARD_001",
|
||
"watch_duration": 30, // seconds actually watched
|
||
"completion_status": "completed" // completed, skipped, error
|
||
}
|
||
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"reward_granted": {
|
||
"type": "extra_dialogue",
|
||
"quantity": 2,
|
||
"expires_at": "2024-09-06T15:45:00Z"
|
||
},
|
||
"next_ad_available_at": "2024-09-05T16:15:00Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 錯誤處理
|
||
|
||
### 標準錯誤碼
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": {
|
||
"code": "VALIDATION_ERROR",
|
||
"message": "輸入資料驗證失敗",
|
||
"details": {
|
||
"field": "email",
|
||
"reason": "invalid_format"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 常見錯誤碼
|
||
- `UNAUTHORIZED` (401): 未授權存取
|
||
- `FORBIDDEN` (403): 權限不足
|
||
- `NOT_FOUND` (404): 資源不存在
|
||
- `VALIDATION_ERROR` (400): 資料驗證失敗
|
||
- `RATE_LIMIT_EXCEEDED` (429): 超過速率限制
|
||
- `INTERNAL_SERVER_ERROR` (500): 伺服器內部錯誤
|
||
- `SERVICE_UNAVAILABLE` (503): 服務暫時不可用
|
||
|
||
### 訂閱相關錯誤
|
||
- `SUBSCRIPTION_REQUIRED`: 需要訂閱才能存取
|
||
- `SUBSCRIPTION_EXPIRED`: 訂閱已過期
|
||
- `PAYMENT_FAILED`: 付款處理失敗
|
||
- `CONTENT_NOT_PURCHASED`: 內容未購買
|
||
|
||
---
|
||
|
||
## API 版本控制與部署
|
||
|
||
### 版本控制策略
|
||
- [ ] **URL版本控制**: `/api/v1/`, `/api/v2/`
|
||
- [ ] **向後相容**: 新版本保持向後相容性
|
||
- [ ] **廢棄通知**: 提前6個月通知API廢棄
|
||
- [ ] **多版本支援**: 同時支援2-3個版本
|
||
- [ ] **版本文檔**: 每個版本維護獨立文檔
|
||
|
||
### 環境配置
|
||
```bash
|
||
# 開發環境
|
||
API_BASE_URL=https://dev-api.dramaling.com
|
||
API_VERSION=v1
|
||
|
||
# 測試環境
|
||
API_BASE_URL=https://staging-api.dramaling.com
|
||
API_VERSION=v1
|
||
|
||
# 生產環境
|
||
API_BASE_URL=https://api.dramaling.com
|
||
API_VERSION=v1
|
||
```
|
||
|
||
### 效能考量
|
||
- [ ] **回應時間**: 95%的API請求在200ms內回應
|
||
- [ ] **快取策略**: 靜態內容使用CDN,動態內容使用Redis
|
||
- [ ] **資料庫優化**: 適當的索引和查詢優化
|
||
- [ ] **負載平衡**: 水平擴展API服務器
|
||
- [ ] **監控告警**: API效能和錯誤率監控
|
||
|
||
---
|
||
|
||
## 待完成任務
|
||
|
||
### 高優先級
|
||
1. [ ] 完善所有API端點的詳細規格和範例
|
||
2. [ ] 設計API的認證和授權機制
|
||
3. [ ] 建立API文檔的自動生成和維護流程
|
||
4. [ ] 實現API的錯誤處理和驗證邏輯
|
||
|
||
### 中優先級
|
||
1. [ ] 設計API的快取和效能優化策略
|
||
2. [ ] 建立API的測試套件和自動化測試
|
||
3. [ ] 規劃API的版本控制和遷移策略
|
||
4. [ ] 設計API的監控和分析系統
|
||
|
||
### 低優先級
|
||
1. [ ] 研究GraphQL作為REST API的補充
|
||
2. [ ] 探索Real-time API (WebSocket) 的應用場景
|
||
3. [ ] 建立API的開發者工具和SDK
|
||
4. [ ] 設計第三方整合的API授權機制
|
||
|
||
---
|
||
|
||
**最後更新**: 2024年9月5日
|
||
**負責人**: 待分配
|
||
**審查週期**: 每兩週檢討一次 |