dramaling-app/docs/04_technical/api-specifications.md

62 KiB
Raw Blame History

Drama Ling API 規格文檔 (已重構為模組化)

📋 重要通知

此文檔已重構為模組化設計!

新的API文檔結構位於 api/ 目錄下,包含:

  • API總覽和導航: api/README.md
  • 各功能模組文檔: 按功能拆分為10個獨立模組
  • 共通規範: 統一的設計原則和錯誤處理

🚀 快速導航

請前往 API 文檔總覽 查看完整的模組化API規格。

📚 模組化結構

api/
├── README.md                    # 總覽和導航
├── authentication.md            # 認證與授權
├── user-management.md           # 用戶管理 
├── learning-content.md          # 學習內容 (待建立)
├── dialogue-practice.md         # 對話練習 (待建立)
├── vocabulary.md               # 詞彙系統 (待建立)
├── gamification.md             # 遊戲化系統 (待建立)
├── subscription.md             # 訂閱系統 (待建立)
├── daily-missions.md           # 特殊任務 (待建立)
├── language-levels.md          # 語言程度 (待建立)
├── errors.md                   # 錯誤處理
└── common.md                   # 共通規範

已完成的模組

📋 待建立的模組

剩餘的API模組將從此文檔的內容中提取並重新組織

  • 學習內容API (第332-416行)
  • 對話練習API (第615-776行)
  • 詞彙系統API (第417-614行)
  • 遊戲化系統API (第98-252行第777-930行第1791-1867行)
  • 訂閱系統API (第1868-2188行)
  • 特殊任務API (第1142-1447行)
  • 語言程度API (第1448-1790行)

⚠️ 重要提醒: 請使用新的模組化文檔進行API開發此檔案僅作為遷移參考。

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

回應格式標準

{
  "success": boolean,
  "data": object | array | null,
  "message": string,
  "error": {
    "code": string,
    "message": string,
    "details": object
  },
  "meta": {
    "timestamp": "ISO8601",
    "request_id": "string",
    "pagination": object
  }
}

認證與授權 API

用戶認證

POST /api/v1/auth/register
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "securePassword123",
  "username": "dramatic_learner",
  "preferredLanguage": "en",
  "nativeLanguage": "zh-TW"
}
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"
  }
}

登入驗證

POST /api/v1/auth/login
{
  "email": "user@example.com", 
  "password": "securePassword123"
}

Token 更新

POST /api/v1/auth/refresh
Authorization: Bearer <refresh_token>

登出

POST /api/v1/auth/logout
Authorization: Bearer <access_token>

命條系統 API

命條狀態管理 (LifePoints)

獲取命條狀態

GET /api/v1/life-points/status
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "current_life_points": 3,
    "max_life_points": 5,
    "recovery_rate": "5_hours_per_point",
    "next_recovery_at": "2024-09-05T20:00:00Z",
    "time_until_next_recovery": 14400, // seconds
    "auto_recovery_enabled": true,
    "last_used_at": "2024-09-05T14:30:00Z",
    "daily_usage_stats": {
      "points_used_today": 2,
      "scenarios_attempted": 5,
      "scenarios_completed": 3
    }
  }
}

購買命條

POST /api/v1/life-points/purchase
Authorization: Bearer <access_token>
{
  "quantity": 5, // 購買數量
  "payment_method": "diamonds", // diamonds, cash, ad_watch
  "payment_details": {
    "diamond_cost": 100 // 如果使用鑽石支付
  }
}

Response 201 Created
{
  "success": true,
  "data": {
    "transaction_id": "LP_PUR_20240905_001",
    "life_points_added": 5,
    "payment_method": "diamonds",
    "cost": {
      "diamonds": 100
    },
    "new_life_points_total": 5,
    "previous_balance": 0,
    "purchased_at": "2024-09-05T16:00:00Z"
  }
}

觀看廣告獲得命條

POST /api/v1/life-points/ad-reward
Authorization: Bearer <access_token>
{
  "ad_id": "AD_LIFE_001",
  "watch_completion": true,
  "watch_duration": 30 // 實際觀看秒數
}

Response 200 OK
{
  "success": true,
  "data": {
    "life_points_gained": 1,
    "current_life_points": 4,
    "ad_cooldown_remaining": 3600, // 下次看廣告的冷卻時間(秒)
    "daily_ad_limit_remaining": 2,
    "reward_claimed_at": "2024-09-05T16:30:00Z"
  }
}

消耗命條 (系統內部調用)

POST /api/v1/life-points/consume
Authorization: Bearer <access_token>
{
  "reason": "dialogue_mistake", // dialogue_mistake, challenge_failure, retry_scenario
  "context": {
    "dialogue_id": "DLG_20240905_001",
    "scenario_id": "SC_Restaurant_01",
    "mistake_type": "grammar_error"
  }
}

Response 200 OK
{
  "success": true,
  "data": {
    "life_points_consumed": 1,
    "remaining_life_points": 2,
    "can_continue": true,
    "context_message": "語法錯誤,命條-1請再試一次",
    "recovery_info": {
      "next_recovery_at": "2024-09-05T20:00:00Z",
      "time_until_recovery": 13500
    }
  }
}

命條耗盡處理

GET /api/v1/life-points/exhausted-options
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "current_life_points": 0,
    "recovery_options": [
      {
        "method": "wait",
        "description": "等待自動回復",
        "time_required": 18000, // 5小時秒數
        "next_recovery_at": "2024-09-05T21:30:00Z",
        "cost": 0
      },
      {
        "method": "purchase_diamonds",
        "description": "使用鑽石購買",
        "life_points": 5,
        "cost": {
          "currency": "diamonds",
          "amount": 100
        }
      },
      {
        "method": "watch_ad",
        "description": "觀看廣告獲得",
        "life_points": 1,
        "available": true,
        "cooldown_remaining": 0,
        "daily_limit_remaining": 3
      }
    ],
    "consolation_reward": {
      "type": "time_scroll", // 時光卷作為安慰獎勵
      "quantity": 1,
      "description": "獲得1個時光卷可用於時光挑戰"
    }
  }
}

用戶資料管理 API

用戶資料 (UserProfile)

獲取用戶資料

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"
    }
  }
}

更新用戶資料

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
  }
}

用戶學習統計

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)

獲取場景列表

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
    }
  }
}

獲取場景詳情

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

獲取詞彙列表

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 (間隔複習系統)

獲取間隔複習任務

GET /api/v1/vocabulary/review/spaced
Authorization: Bearer <access_token>
Query Parameters:
- max_words: integer (default: 20, 每次複習的最大詞彙數)

Response 200 OK
{
  "success": true,
  "data": {
    "review_session_id": "REV_SPACED_20240905_USR12345",
    "total_words": 15,
    "estimated_time": 5, // minutes
    "review_algorithm": "spaced_repetition",
    "words": [
      {
        "vocab_id": "VOC_0001",
        "word": "restaurant",
        "review_count": 3, // 這是第幾次複習
        "next_review_multiplier": 8, // 2^3 = 8天後複習
        "last_reviewed": "2024-08-28T10:15:00Z",
        "mastery_level": "practicing", // learning, practicing, mastered
        "review_type": "recognition", // recognition, recall, spelling
        "options": ["餐廳", "旅館", "商店", "學校"] // for recognition type
      }
    ]
  }
}

詞彙學習階段API

GET /api/v1/vocabulary/learning-stages/{vocab_id}
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "vocab_id": "VOC_0001",
    "word": "restaurant",
    "current_stage": "recognition", // recognition, familiarity, dialogue_application
    "stages_progress": {
      "recognition": {
        "completed": true,
        "completion_date": "2024-09-01T14:30:00Z",
        "attempts": 2,
        "success_rate": 100
      },
      "familiarity": {
        "completed": false,
        "attempts": 1,
        "success_rate": 75,
        "next_exercise": "image_matching"
      },
      "dialogue_application": {
        "completed": false,
        "required_scenarios": ["SC_Restaurant_01"],
        "usage_count": 0
      }
    },
    "overall_mastery": {
      "level": "practicing",
      "confidence_score": 75,
      "estimated_mastery_date": "2024-09-15T00:00:00Z"
    }
  }
}

詞彙熟悉度練習API

POST /api/v1/vocabulary/fluency-practice
Authorization: Bearer <access_token>
{
  "practice_type": "image_matching", // image_matching, sentence_reorder, word_association
  "vocab_ids": ["VOC_0001", "VOC_0002"],
  "difficulty_level": "A2"
}

Response 201 Created
{
  "success": true,
  "data": {
    "practice_session_id": "FLUENCY_20240905_001",
    "practice_type": "image_matching",
    "exercises": [
      {
        "exercise_id": "EX_001",
        "vocab_id": "VOC_0001",
        "word": "restaurant",
        "image_url": "https://cdn.example.com/vocab/restaurant.jpg",
        "options": [
          {
            "text": "restaurant",
            "image_url": "https://cdn.example.com/vocab/restaurant.jpg"
          },
          {
            "text": "hospital", 
            "image_url": "https://cdn.example.com/vocab/hospital.jpg"
          }
        ]
      }
    ]
  }
}

每日詞彙複習API

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
      }
    ]
  }
}

提交複習結果

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)

開始對話練習

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."
      ]
    }
  }
}

發送對話訊息

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分析詳情

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
    }
  }
}

結束對話

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

回覆引導系統

獲取回覆輔助

POST /api/v1/dialogues/{dialogue_id}/assistance
Authorization: Bearer <access_token>
{
  "assistance_type": "reply_guidance", // reply_guidance, translation
  "context": {
    "partner_message": "Good morning! How is your day going?",
    "scenario_context": "friendly morning greeting at office",
    "user_language_level": "A2",
    "dialogue_history": [
      {
        "speaker": "partner",
        "message": "Hello! Nice to meet you."
      },
      {
        "speaker": "user", 
        "message": "Nice to meet you too."
      }
    ]
  }
}

Response 200 OK
{
  "success": true,
  "data": {
    "assistance_id": "AST_20240905_001",
    "assistance_type": "reply_guidance",
    "analysis": {
      "partner_intent": {
        "intent": "friendly_greeting_inquiry",
        "emotion": "positive_friendly",
        "expectation": "positive_response_about_day",
        "cultural_context": "Western casual workplace greeting",
        "explanation": "對方是在進行友好的早晨問候,期待你分享今天的狀況或心情"
      },
      "response_guidance": {
        "thinking_process": [
          "對方表現友好,我應該同樣友善回應",
          "這是詢問我今天的狀況,我可以簡單分享",  
          "可以考慮反問對方相同的問題表示關心"
        ],
        "response_strategies": [
          {
            "strategy": "positive_sharing",
            "description": "積極分享今天的狀況",
            "tone": "upbeat"
          },
          {
            "strategy": "brief_polite",
            "description": "簡潔禮貌的回應",
            "tone": "neutral_friendly"
          },
          {
            "strategy": "reciprocal_inquiry", 
            "description": "回應後反問對方",
            "tone": "engaging"
          }
        ]
      },
      "reply_examples": [
        {
          "example": "Great, thank you! I'm feeling energetic today. How about you?",
          "level": "A2",
          "style": "friendly_reciprocal",
          "explanation": "表達積極心情並反問對方,展現對話技巧"
        },
        {
          "example": "Pretty good, thanks for asking!",
          "level": "A2", 
          "style": "casual_brief",
          "explanation": "簡潔友善的回應,適合快節奏對話"
        },
        {
          "example": "It's going well so far! Just got to the office. What about your day?",
          "level": "B1",
          "style": "detailed_engaging",
          "explanation": "提供更多細節並主動延續對話"
        }
      ]
    },
    "cost_deducted": {
      "item_type": "reply_hint",
      "quantity": 1,
      "remaining_quantity": 4
    }
  }
}

中翻英翻譯輔助

POST /api/v1/translation/assistance
Authorization: Bearer <access_token>
{
  "source_text": "今天天氣真好,讓我心情很愉快",
  "context": {
    "dialogue_scenario": "casual_conversation",
    "formality_level": "informal",
    "target_language_level": "A2",
    "cultural_adaptation": true
  }
}

Response 200 OK
{
  "success": true,
  "data": {
    "translation_result": {
      "primary_translation": "The weather is really nice today, it makes me feel happy.",
      "alternative_translations": [
        {
          "text": "It's such a beautiful day today, I'm in a great mood!",
          "level": "B1",
          "style": "enthusiastic"
        },
        {
          "text": "Today's nice weather is making me cheerful.",
          "level": "A2",
          "style": "simple_clear"
        }
      ],
      "grammar_notes": [
        {
          "point": "weather_description",
          "explanation": "英文描述天氣常用 'The weather is + adjective' 句型"
        },
        {
          "point": "causative_structure", 
          "explanation": "'makes me feel + adjective' 表達某事讓你產生某種感受"
        }
      ],
      "vocabulary_highlights": [
        {
          "chinese": "心情愉快",
          "english": "feel happy / in a good mood",
          "note": "英文有多種表達好心情的方式"
        }
      ],
      "cultural_adaptation": {
        "original_style": "direct_emotional_expression",
        "adapted_style": "moderate_positive_expression",
        "explanation": "調整為西方文化中更常見的表達方式"
      }
    }
  }
}

時光挑戰系統 API

時光挑戰 (TimeWarp)

獲取可用時光挑戰

GET /api/v1/time-warp/challenges
Authorization: Bearer <access_token>
Query Parameters:
- difficulty: string (easy, medium, hard)
- challenge_type: string (vocabulary, dialogue, mixed)

Response 200 OK
{
  "success": true,
  "data": {
    "available_challenges": [
      {
        "challenge_id": "TW_VOCAB_EASY_001",
        "type": "vocabulary",
        "difficulty": "easy",
        "title": "快速詞彙挑戰",
        "description": "在300秒內完成20個詞彙測試",
        "time_limit": 300, // seconds
        "target_score": 20,
        "estimated_difficulty": "A2",
        "rewards": {
          "time_scrolls": 2,
          "experience": 200,
          "diamonds": 50
        },
        "requirements": {
          "min_vocabulary_mastered": 50,
          "min_level": "A2"
        },
        "user_best_score": 18,
        "user_attempts": 3,
        "unlock_condition": "complete_vocabulary_stage_1"
      }
    ],
    "user_time_scrolls": {
      "current": 5,
      "earned_today": 2,
      "used_today": 1,
      "total_earned": 87
    }
  }
}

開始時光挑戰

POST /api/v1/time-warp/start
Authorization: Bearer <access_token>
{
  "challenge_id": "TW_VOCAB_EASY_001",
  "use_time_scroll": true // 是否消耗時光卷
}

Response 201 Created
{
  "success": true,
  "data": {
    "session_id": "TW_SESSION_20240905_001",
    "challenge_id": "TW_VOCAB_EASY_001",
    "time_limit": 300,
    "started_at": "2024-09-05T16:00:00Z",
    "expires_at": "2024-09-05T16:05:00Z",
    "time_scrolls_used": 1,
    "remaining_time_scrolls": 4,
    "challenge_content": {
      "total_questions": 20,
      "current_question": 1,
      "questions": [
        {
          "question_id": "Q_001",
          "type": "vocabulary_recognition",
          "word": "restaurant",
          "question": "選擇正確的中文翻譯",
          "options": ["餐廳", "醫院", "學校", "商店"],
          "correct_answer": "餐廳"
        }
      ]
    }
  }
}

提交時光挑戰答案

POST /api/v1/time-warp/submit-answer
Authorization: Bearer <access_token>
{
  "session_id": "TW_SESSION_20240905_001",
  "question_id": "Q_001",
  "answer": "餐廳",
  "response_time": 2.5, // seconds
  "timestamp": "2024-09-05T16:00:03Z"
}

Response 200 OK
{
  "success": true,
  "data": {
    "correct": true,
    "score_gained": 1,
    "current_score": 1,
    "time_remaining": 297.5,
    "next_question": {
      "question_id": "Q_002",
      "type": "vocabulary_recognition",
      "word": "hospital",
      "question": "選擇正確的中文翻譯",
      "options": ["餐廳", "醫院", "學校", "商店"]
    },
    "progress": {
      "completed_questions": 1,
      "total_questions": 20,
      "completion_percentage": 5
    }
  }
}

完成時光挑戰

POST /api/v1/time-warp/complete
Authorization: Bearer <access_token>
{
  "session_id": "TW_SESSION_20240905_001",
  "completion_reason": "time_up" // time_up, all_completed, user_quit
}

Response 200 OK
{
  "success": true,
  "data": {
    "challenge_result": {
      "session_id": "TW_SESSION_20240905_001",
      "final_score": 18,
      "target_score": 20,
      "completion_percentage": 90,
      "time_used": 298, // seconds
      "time_limit": 300,
      "success": false, // 未達到目標分數
      "performance_rating": "good" // excellent, good, fair, poor
    },
    "rewards_earned": {
      "experience": 150, // 減少因為未完全完成
      "diamonds": 30,
      "time_scrolls": 1, // 安慰獎勵
      "achievements": []
    },
    "statistics": {
      "correct_answers": 18,
      "wrong_answers": 2,
      "average_response_time": 14.9,
      "fastest_answer": 1.2,
      "slowest_answer": 28.5
    },
    "new_personal_record": false,
    "leaderboard_rank": 245
  }
}

獲取時光卷狀態

GET /api/v1/time-warp/scrolls
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "current_scrolls": 5,
    "scroll_history": [
      {
        "earned_at": "2024-09-05T14:30:00Z",
        "source": "dialogue_failure_consolation",
        "quantity": 1,
        "scenario_id": "SC_Restaurant_01"
      },
      {
        "used_at": "2024-09-05T15:00:00Z",
        "challenge_id": "TW_VOCAB_EASY_001",
        "quantity": 1,
        "result": "completed"
      }
    ],
    "earning_sources": [
      {
        "source": "dialogue_failure_consolation",
        "description": "對話失敗安慰獎勵",
        "frequency": "每次對話失敗"
      },
      {
        "source": "time_challenge_reward",
        "description": "完成時光挑戰獎勵",
        "frequency": "挑戰成功時"
      },
      {
        "source": "daily_login_bonus",
        "description": "每日登入獎勵",
        "frequency": "連續登入7天"
      }
    ]
  }
}

特殊任務系統 API (新增基於新需求)

今日任務管理 (Daily Mission System)

獲取今日任務 (更新規格)

GET /api/v1/missions/daily
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "daily_missions": [
      {
        "mission_id": "MISSION_VOCAB_RECOGNITION",
        "type": "daily",
        "title": "詞彙認識挑戰",
        "description": "成功闖關1次詞彙認識關卡",
        "icon": "🎯",
        "objectives": [
          {
            "objective_id": "OBJ_VOCAB_RECOGNITION",
            "description": "完成詞彙認識關卡通關",
            "target_value": 1,
            "current_value": 0,
            "unit": "次",
            "completion_criteria": "three_star_completion"
          }
        ],
        "rewards": {
          "experience": 50,
          "reward_type": "experience_points",
          "description": "獲得50經驗值"
        },
        "status": "available",
        "deadline": "2024-09-05T23:59:59Z",
        "reset_time": "2024-09-06T00:00:00Z",
        "completion_tracking": {
          "last_completed_date": null,
          "completion_count_today": 0
        }
      },
      {
        "mission_id": "MISSION_VOCAB_FLUENCY",
        "type": "daily",
        "title": "詞彙熟悉挑戰",
        "description": "成功闖關1次詞彙熟悉關卡",
        "icon": "💪",
        "objectives": [
          {
            "objective_id": "OBJ_VOCAB_FLUENCY",
            "description": "完成詞彙熟悉關卡通關",
            "target_value": 1,
            "current_value": 0,
            "unit": "次",
            "completion_criteria": "three_star_completion"
          }
        ],
        "rewards": {
          "experience": 50,
          "reward_type": "experience_points",
          "description": "獲得50經驗值"
        },
        "status": "available",
        "deadline": "2024-09-05T23:59:59Z",
        "reset_time": "2024-09-06T00:00:00Z"
      },
      {
        "mission_id": "MISSION_DIALOGUE_TRAINING",
        "type": "daily",
        "title": "對話訓練挑戰",
        "description": "成功闖關1次對話訓練關卡",
        "icon": "💬",
        "objectives": [
          {
            "objective_id": "OBJ_DIALOGUE_TRAINING",
            "description": "完成對話訓練關卡通關",
            "target_value": 1,
            "current_value": 1,
            "unit": "次",
            "completion_criteria": "completion_only"
          }
        ],
        "rewards": {
          "experience": 75,
          "reward_type": "experience_points",
          "description": "獲得75經驗值"
        },
        "status": "completed",
        "deadline": "2024-09-05T23:59:59Z",
        "completed_at": "2024-09-05T14:30:00Z"
      },
      {
        "mission_id": "MISSION_PERFECT_DIALOGUE",
        "type": "daily",
        "title": "完美對話挑戰",
        "description": "在對話訓練關卡拿到滿星分數1次",
        "icon": "⭐",
        "objectives": [
          {
            "objective_id": "OBJ_PERFECT_DIALOGUE",
            "description": "對話訓練關卡獲得滿星評價",
            "target_value": 1,
            "current_value": 0,
            "unit": "次",
            "completion_criteria": "three_star_completion"
          }
        ],
        "rewards": {
          "experience": 100,
          "reward_type": "experience_points", 
          "description": "獲得100經驗值"
        },
        "status": "available",
        "deadline": "2024-09-05T23:59:59Z",
        "requirements": {
          "subscription_required": true,
          "feature_access": "dialogue_training"
        }
      }
    ],
    "daily_summary": {
      "total_missions": 4,
      "completed_missions": 1,
      "available_missions": 3,
      "total_experience_available": 275,
      "experience_earned_today": 75,
      "next_reset_time": "2024-09-06T00:00:00Z"
    }
  }
}

關卡完成任務檢查 (新增 - 關卡結算時調用)

POST /api/v1/missions/check-completion
Authorization: Bearer <access_token>
{
  "challenge_completed": {
    "challenge_type": "vocabulary_recognition", // vocabulary_recognition, vocabulary_fluency, dialogue_training
    "challenge_id": "VOCAB_INTRO_001",
    "completion_result": {
      "success": true,
      "stars_earned": 3,
      "score": 95,
      "perfect_score": true,
      "completion_time": 120 // seconds
    },
    "context": {
      "scenario_id": "SC_Restaurant_01", // For dialogue training
      "vocabulary_learned": ["reservation", "menu", "order"] // For vocab challenges
    }
  }
}

Response 200 OK
{
  "success": true,
  "data": {
    "missions_updated": [
      {
        "mission_id": "MISSION_VOCAB_RECOGNITION",
        "previous_progress": 0,
        "new_progress": 1,
        "completed": true,
        "completion_time": "2024-09-05T16:45:00Z",
        "reward_available": true
      }
    ],
    "missions_completed": [
      {
        "mission_id": "MISSION_VOCAB_RECOGNITION",
        "reward": {
          "experience": 50,
          "reward_type": "experience_points",
          "description": "完成詞彙認識挑戰!"
        },
        "show_completion_popup": true,
        "completion_message": "恭喜您完成了今日詞彙認識挑戰獲得50經驗值"
      }
    ],
    "should_show_reward_screen": true,
    "total_experience_gained": 50
  }
}

領取任務獎勵 (更新規格)

POST /api/v1/missions/{mission_id}/claim_reward
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "mission_id": "MISSION_VOCAB_RECOGNITION",
    "reward_claimed": {
      "experience": 50,
      "reward_type": "experience_points",
      "description": "詞彙認識挑戰完成獎勵"
    },
    "updated_user_stats": {
      "total_experience": 15730,
      "experience_gained_today": 125,
      "level_progress": {
        "current_level": "B1",
        "experience_to_next": 270,
        "level_up": false
      }
    },
    "reward_claimed_at": "2024-09-05T16:47:00Z"
  }
}

重置每日任務 (系統內部調用)

POST /api/v1/missions/daily/reset
Authorization: Bearer <system_token>
{
  "reset_time": "2024-09-06T00:00:00Z",
  "reset_type": "daily_automatic"
}

Response 200 OK
{
  "success": true,
  "data": {
    "missions_reset": 4,
    "users_affected": 15420,
    "reset_completed_at": "2024-09-06T00:00:15Z",
    "next_reset_scheduled": "2024-09-07T00:00:00Z"
  }
}

獲取任務詳情

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"
  }
}

領取任務獎勵

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 (新增基於新需求)

語言程度管理 (Language Level Advancement)

獲取語言程度狀態

GET /api/v1/language-level/status
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "current_level": {
      "level_id": "LEVEL_A2_2",
      "level_number": 3,
      "cefr_level": "A2",
      "level_name": "A2中級",
      "description": "能夠理解和使用日常用語和基本短語",
      "learning_focus": [
        "基礎日常對話",
        "簡單描述個人背景",
        "表達基本需求"
      ]
    },
    "advancement_progress": {
      "previous_level_requirements": {
        "required_perfect_dialogues": 15,
        "completed_perfect_dialogues": 15,
        "completion_percentage": 100,
        "completed_at": "2024-08-15T10:30:00Z"
      },
      "current_level_requirements": {
        "required_perfect_dialogues": 10,
        "completed_perfect_dialogues": 7,
        "completion_percentage": 70,
        "remaining_dialogues": 3
      },
      "total_progress": {
        "total_required": 25, // 15 + 10
        "total_completed": 22, // 15 + 7
        "overall_percentage": 88
      }
    },
    "next_level": {
      "level_id": "LEVEL_B1_1",
      "level_number": 4,
      "cefr_level": "B1",
      "level_name": "B1初級",
      "unlock_requirements": {
        "previous_level_dialogues": 15,
        "current_level_dialogues": 10
      },
      "benefits": [
        "解鎖更豐富的對話場景",
        "更複雜的語言結構練習",
        "進階語法訓練"
      ]
    },
    "level_statistics": {
      "days_at_current_level": 21,
      "estimated_days_to_next": 5,
      "perfect_dialogues_this_week": 3,
      "learning_streak": 12
    }
  }
}

滿星對話完成檢查 (關卡結算時調用)

POST /api/v1/language-level/perfect-dialogue-completed
Authorization: Bearer <access_token>
{
  "dialogue_result": {
    "dialogue_id": "DLG_20240905_001",
    "scenario_id": "SC_Restaurant_01",
    "final_score": 95,
    "stars_earned": 3,
    "is_perfect_score": true,
    "evaluation_scores": {
      "grammar_score": 95,
      "semantic_score": 96,
      "fluency_score": 94,
      "vocabulary_score": 97
    },
    "completion_time": "2024-09-05T16:45:00Z"
  }
}

Response 200 OK
{
  "success": true,
  "data": {
    "level_progress_updated": true,
    "previous_progress": {
      "current_level_dialogues": 6,
      "total_completed": 21
    },
    "new_progress": {
      "current_level_dialogues": 7,
      "total_completed": 22
    },
    "advancement_check": {
      "ready_for_advancement": false,
      "requirements_met": {
        "previous_level_complete": true,
        "current_level_complete": false
      },
      "remaining_requirements": {
        "perfect_dialogues_needed": 3
      }
    },
    "level_up_triggered": false
  }
}

語言程度晉階觸發 (系統檢查完成條件)

POST /api/v1/language-level/advancement-check
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "advancement_eligible": true,
    "current_level": {
      "level_id": "LEVEL_A2_2",
      "level_number": 3,
      "cefr_level": "A2"
    },
    "advancement_to": {
      "level_id": "LEVEL_B1_1",
      "level_number": 4,
      "cefr_level": "B1",
      "level_name": "B1初級"
    },
    "requirements_satisfied": {
      "previous_level_dialogues": {
        "required": 15,
        "completed": 15,
        "satisfied": true
      },
      "current_level_dialogues": {
        "required": 10,
        "completed": 10,
        "satisfied": true
      }
    },
    "advancement_rewards": {
      "experience_bonus": 500,
      "achievement": "language_advancement_b1",
      "content_unlocked": [
        "SC_Business_Meeting_01",
        "SC_Job_Interview_01",
        "SC_Academic_Discussion_01"
      ]
    },
    "show_advancement_ceremony": true
  }
}

執行語言程度晉階

POST /api/v1/language-level/advance
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "advancement_completed": true,
    "previous_level": {
      "level_id": "LEVEL_A2_2",
      "level_number": 3,
      "cefr_level": "A2"
    },
    "new_level": {
      "level_id": "LEVEL_B1_1",
      "level_number": 4,
      "cefr_level": "B1",
      "level_name": "B1初級",
      "description": "能夠處理日常生活中大部分語言需求",
      "learning_focus": [
        "工作和學習場景對話",
        "表達觀點和意見",
        "描述經驗和事件"
      ]
    },
    "rewards_granted": {
      "experience_gained": 500,
      "achievements_unlocked": ["language_advancement_b1"],
      "content_unlocked": {
        "scenarios": [
          {
            "scenario_id": "SC_Business_Meeting_01",
            "title": "商務會議",
            "difficulty": "B1"
          },
          {
            "scenario_id": "SC_Job_Interview_01", 
            "title": "工作面試",
            "difficulty": "B1"
          }
        ],
        "vocabulary_packs": ["VOCAB_PACK_B1_BUSINESS"]
      }
    },
    "next_level_preview": {
      "level_id": "LEVEL_B1_2",
      "level_name": "B1中級",
      "unlock_requirements": {
        "previous_level_dialogues": 15,
        "current_level_dialogues": 10
      }
    },
    "advancement_date": "2024-09-05T17:00:00Z"
  }
}

獲取語言程度歷史

GET /api/v1/language-level/history
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "advancement_history": [
      {
        "level_id": "LEVEL_A1_1",
        "level_name": "A1初級", 
        "cefr_level": "A1",
        "started_at": "2024-01-15T10:00:00Z",
        "completed_at": "2024-02-28T16:30:00Z",
        "duration_days": 44,
        "perfect_dialogues_completed": 10,
        "total_scenarios_completed": 25
      },
      {
        "level_id": "LEVEL_A2_1",
        "level_name": "A2初級",
        "cefr_level": "A2", 
        "started_at": "2024-02-28T16:30:00Z",
        "completed_at": "2024-06-15T14:20:00Z",
        "duration_days": 107,
        "perfect_dialogues_completed": 25,
        "total_scenarios_completed": 45
      }
    ],
    "performance_analysis": {
      "average_advancement_days": 75.5,
      "total_perfect_dialogues": 67,
      "strongest_areas": ["vocabulary_usage", "fluency"],
      "improvement_areas": ["grammar_complexity", "cultural_awareness"],
      "learning_velocity": "steady" // fast, steady, gradual
    }
  }
}

獲取各程度評估標準

GET /api/v1/language-level/criteria
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "evaluation_criteria": {
      "semantic_appropriateness": {
        "description": "語意合適度",
        "weight": 25,
        "factors": [
          "上下文理解準確性",
          "回應內容相關性", 
          "情境適當性"
        ]
      },
      "grammar_accuracy": {
        "description": "語法錯誤率",
        "weight": 25,
        "factors": [
          "句法結構正確性",
          "動詞時態使用",
          "語序和搭配"
        ]
      },
      "fluency": {
        "description": "表達流暢度",
        "weight": 25,
        "factors": [
          "語言自然度",
          "停頓和節奏",
          "表達連貫性"
        ]
      },
      "vocabulary_score": {
        "description": "詞彙分數", 
        "weight": 25,
        "factors": [
          "詞彙多樣性",
          "詞彙準確性",
          "適當詞彙選擇"
        ]
      }
    },
    "level_standards": {
      "A1": {
        "minimum_score": 60,
        "focus_areas": ["基礎詞彙", "簡單句型", "基本溝通"]
      },
      "A2": {
        "minimum_score": 70,
        "focus_areas": ["日常對話", "基本語法", "情境理解"]
      },
      "B1": {
        "minimum_score": 75,
        "focus_areas": ["工作學習", "意見表達", "經驗描述"]
      },
      "B2": {
        "minimum_score": 80,
        "focus_areas": ["複雜主題", "抽象概念", "論述技巧"]
      },
      "C1": {
        "minimum_score": 85,
        "focus_areas": ["專業溝通", "文化理解", "精確表達"]
      },
      "C2": {
        "minimum_score": 90,
        "focus_areas": ["母語水準", "微妙差異", "專精表達"]
      }
    }
  }
}

排行榜與競爭 API

排行榜系統 (Leaderboard)

獲取排行榜

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
    ]
  }
}

好友排行榜

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)

獲取訂閱方案 (更新基於新需求)

GET /api/v1/subscriptions/plans
Authorization: Bearer <access_token>

Response 200 OK
{
  "success": true,
  "data": {
    "plans": [
      {
        "plan_id": "PLAN_MONTHLY",
        "name": "月費會員",
        "description": "解鎖對話訓練功能,享受完整學習體驗",
        "price": {
          "monthly": {
            "amount": 600,
            "currency": "TWD",
            "original_price": 600,
            "test_discount": {
              "percentage": 80,
              "discounted_price": 120,
              "description": "內部測試期間2折優惠"
            }
          }
        },
        "features": [
          "解鎖所有對話訓練關卡",
          "無限制對話練習次數",
          "完整語言程度評估",
          "詳細學習分析報告",
          "優先客服支援"
        ],
        "limitations": [
          "訪客可透過設備ID訂閱",
          "不含額外道具和內容包"
        ],
        "access_control": {
          "required_for": ["dialogue_training", "conversation_scenarios"],
          "free_access": ["vocabulary_recognition", "vocabulary_fluency", "spaced_review"]
        }
      }
    ],
    "current_subscription": {
      "plan_id": "PLAN_MONTHLY",
      "status": "active",
      "expires_at": "2024-10-05T15:30:00Z",
      "auto_renewal": true,
      "payment_method": "credit_card",
      "subscription_source": "device_id" // device_id, registered_account
    }
  }
}

訂閱方案 (支援訪客訂閱)

POST /api/v1/subscriptions/subscribe
Authorization: Bearer <access_token> // Optional for guest users

{
  "plan_id": "PLAN_MONTHLY",
  "billing_cycle": "monthly",
  "payment_method_id": "pm_1234567890",
  "auto_renewal": true,
  "subscription_context": {
    "trigger_source": "first_vocabulary_completion", // first_vocabulary_completion, settings_page, dialogue_access_blocked
    "device_id": "DEV_iOS_12345", // Required for guest subscription
    "user_type": "guest" // guest, registered
  }
}

Response 201 Created
{
  "success": true,
  "data": {
    "subscription_id": "SUB_20240905_001",
    "plan_id": "PLAN_MONTHLY", 
    "status": "active",
    "started_at": "2024-09-05T15:30:00Z",
    "expires_at": "2024-10-05T15:30:00Z",
    "next_billing_date": "2024-10-05T15:30:00Z",
    "amount_paid": 120, // With test discount
    "original_amount": 600,
    "discount_applied": 480,
    "currency": "TWD",
    "subscription_source": "device_id",
    "access_unlocked": {
      "dialogue_training": true,
      "conversation_scenarios": true,
      "premium_content": false
    }
  }
}

檢查訂閱狀態 (新增 - 對話訓練權限檢查)

GET /api/v1/subscriptions/access-check
Authorization: Bearer <access_token> // Optional for guest users
Query Parameters:
- feature: string (dialogue_training, conversation_scenarios, premium_content)
- device_id: string (Required if no auth token)

Response 200 OK
{
  "success": true,
  "data": {
    "has_access": false,
    "subscription_status": "none", // active, expired, none
    "required_plan": "PLAN_MONTHLY",
    "blocking_reason": "subscription_required",
    "subscription_prompt": {
      "title": "解鎖對話訓練功能",
      "message": "對話訓練需要訂閱月費會員才能使用",
      "cta_text": "立即訂閱",
      "special_offer": {
        "discount_percentage": 80,
        "original_price": 600,
        "discounted_price": 120,
        "offer_text": "內部測試期間限時2折優惠"
      }
    },
    "free_alternatives": [
      {
        "feature": "vocabulary_recognition",
        "description": "免費的詞彙認識練習"
      },
      {
        "feature": "vocabulary_fluency", 
        "description": "免費的詞彙熟悉練習"
      }
    ]
  }
}

內購系統 (Purchase)

獲取道具商店內容

GET /api/v1/store/items
Authorization: Bearer <access_token>
Query Parameters:
- category: string (power_ups, scenario_pack, expert_course, premium_content)
- item_type: string (time_extension, life_restore, time_travel, reply_hint)

Response 200 OK
{
  "success": true,
  "data": {
    "power_up_items": [
      {
        "item_id": "ITEM_TIME_EXT_001",
        "type": "time_extension",
        "name": "加時道具",
        "icon": "🕰️",
        "description": "為對話訓練加時1分3秒",
        "single_price": {
          "amount": 300,
          "currency": "diamonds"
        },
        "bundle_price": {
          "amount": 1200,
          "currency": "diamonds", 
          "quantity": 5,
          "discount_percentage": 20
        },
        "usage_limit": null,
        "effects": ["adds_63_seconds"]
      },
      {
        "item_id": "ITEM_REPLY_HINT_001", 
        "type": "reply_hint",
        "name": "回覆提示道具",
        "icon": "💡",
        "description": "獲得AI智慧引導突破對話卡關",
        "single_price": {
          "amount": 30,
          "currency": "diamonds"
        },
        "bundle_price": {
          "amount": 250,
          "currency": "diamonds",
          "quantity": 10, 
          "discount_percentage": 17
        },
        "usage_limit": "3_per_dialogue",
        "effects": [
          "partner_intent_analysis",
          "response_thinking_guidance", 
          "reply_examples",
          "chinese_to_english_translation"
        ]
      },
      {
        "item_id": "ITEM_LIFE_RESTORE_001",
        "type": "life_restore", 
        "name": "補命道具",
        "icon": "❤️",
        "description": "為對話學習的時間卡復活1次機會",
        "single_price": {
          "amount": 100,
          "currency": "diamonds"
        },
        "bundle_price": {
          "amount": 400,
          "currency": "diamonds",
          "quantity": 5,
          "discount_percentage": 20
        },
        "usage_limit": null,
        "effects": ["retry_failed_dialogue"]
      }
    ]
  }
}

獲取付費內容

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折優惠"
        }
      }
    ]
  }
}

購買道具

POST /api/v1/store/purchase/item
Authorization: Bearer <access_token>
{
  "item_id": "ITEM_REPLY_HINT_001",
  "quantity": 1,
  "purchase_type": "single" // single, bundle
}

Response 201 Created
{
  "success": true,
  "data": {
    "purchase_id": "PUR_ITEM_20240905_001",
    "item_id": "ITEM_REPLY_HINT_001",
    "item_name": "回覆提示道具",
    "quantity_purchased": 1,
    "diamonds_spent": 30,
    "transaction_details": {
      "previous_diamond_balance": 1500,
      "current_diamond_balance": 1470,
      "previous_item_count": 0,
      "current_item_count": 1
    },
    "purchased_at": "2024-09-05T16:30:00Z"
  }
}

購買內容

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)

獲取廣告獎勵機會

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
      }
    ]
  }
}

觀看廣告獲得獎勵

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"
  }
}

錯誤處理

標準錯誤碼

{
  "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: 內容未購買

回覆輔助相關錯誤

  • INSUFFICIENT_REPLY_HINTS: 回覆提示道具不足
  • DAILY_HINT_LIMIT_EXCEEDED: 超過每日提示使用限制
  • DIALOGUE_HINT_LIMIT_EXCEEDED: 超過單次對話提示使用限制
  • TRANSLATION_SERVICE_ERROR: 翻譯服務錯誤
  • AI_ASSISTANCE_UNAVAILABLE: AI輔助服務暫時不可用

道具系統相關錯誤

  • INSUFFICIENT_DIAMONDS: 鑽石不足
  • ITEM_NOT_AVAILABLE: 道具不可購買
  • ITEM_USAGE_LIMIT_REACHED: 道具使用次數已達上限
  • INVALID_ITEM_QUANTITY: 無效的道具數量

命條系統相關錯誤

  • INSUFFICIENT_LIFE_POINTS: 命條不足,無法開始關卡
  • LIFE_POINTS_AT_MAXIMUM: 命條已滿,無法恢復更多
  • RECOVERY_COOLDOWN_ACTIVE: 恢復冷卻時間未結束
  • AD_WATCH_LIMIT_EXCEEDED: 超過每日觀看廣告次數限制
  • LIFE_POINTS_PURCHASE_FAILED: 命條購買失敗

詞彙學習系統相關錯誤

  • VOCABULARY_STAGE_LOCKED: 詞彙學習階段未解鎖
  • VOCABULARY_NOT_FOUND: 詞彙不存在
  • INVALID_LEARNING_STAGE: 無效的學習階段
  • SPACED_REPETITION_ALGORITHM_ERROR: 間隔複習算法計算錯誤
  • VOCABULARY_PROGRESS_SYNC_FAILED: 詞彙進度同步失敗

時光挑戰相關錯誤

  • INSUFFICIENT_TIME_SCROLLS: 時光卷不足
  • TIME_CHALLENGE_NOT_AVAILABLE: 時光挑戰不可用
  • CHALLENGE_ALREADY_IN_PROGRESS: 已有進行中的挑戰
  • CHALLENGE_TIME_EXPIRED: 挑戰時間已過期
  • CHALLENGE_SESSION_INVALID: 無效的挑戰會話
  • CHALLENGE_REQUIREMENTS_NOT_MET: 不滿足挑戰要求

特殊任務系統相關錯誤 (新增)

  • MISSION_NOT_AVAILABLE: 任務不可用或已完成
  • MISSION_REQUIREMENTS_NOT_MET: 不滿足任務要求
  • MISSION_ALREADY_COMPLETED: 任務已經完成
  • MISSION_EXPIRED: 任務已過期
  • MISSION_REWARD_ALREADY_CLAIMED: 任務獎勵已領取
  • INVALID_MISSION_COMPLETION_DATA: 無效的任務完成數據
  • MISSION_RESET_FAILED: 任務重置失敗

語言程度晉階相關錯誤 (新增)

  • LANGUAGE_LEVEL_NOT_FOUND: 語言程度不存在
  • ADVANCEMENT_REQUIREMENTS_NOT_MET: 不滿足晉階條件
  • ADVANCEMENT_ALREADY_COMPLETED: 晉階已經完成
  • INVALID_PERFECT_DIALOGUE_DATA: 無效的滿星對話數據
  • LEVEL_CALCULATION_ERROR: 程度計算錯誤
  • ADVANCEMENT_CEREMONY_FAILED: 晉階儀式顯示失敗
  • LEVEL_PROGRESS_SYNC_FAILED: 程度進度同步失敗

訂閱系統相關錯誤 (新增)

  • SUBSCRIPTION_ACCESS_DENIED: 訂閱權限不足
  • GUEST_SUBSCRIPTION_FAILED: 訪客訂閱失敗
  • DEVICE_ID_REQUIRED: 需要設備ID進行訂閱
  • SUBSCRIPTION_DISCOUNT_EXPIRED: 訂閱優惠已過期
  • SUBSCRIPTION_PLAN_NOT_FOUND: 訂閱方案不存在
  • FEATURE_REQUIRES_SUBSCRIPTION: 功能需要訂閱權限

API 版本控制與部署

版本控制策略

  • URL版本控制: /api/v1/, /api/v2/
  • 向後相容: 新版本保持向後相容性
  • 廢棄通知: 提前6個月通知API廢棄
  • 多版本支援: 同時支援2-3個版本
  • 版本文檔: 每個版本維護獨立文檔

環境配置

# 開發環境
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. 實現訂閱系統的付款流程和權限控制 (新增)
  4. 完善語言程度晉階算法的API實現 (新增)
  5. 建立API文檔的自動生成和維護流程
  6. 實現API的錯誤處理和驗證邏輯

中優先級

  1. 設計特殊任務系統的績效追蹤和分析API (新增)
  2. 實現訂閱系統與對話訓練的權限整合 (新增)
  3. 建立語言程度評估標準的動態調整機制 (新增)
  4. 設計API的快取和效能優化策略
  5. 建立API的測試套件和自動化測試
  6. 規劃API的版本控制和遷移策略
  7. 設計API的監控和分析系統

低優先級

  1. 研究GraphQL作為REST API的補充
  2. 探索Real-time API (WebSocket) 的應用場景
  3. 建立多語言程度並行學習的API架構 (新增)
  4. 設計個人化任務推薦系統API (新增)
  5. 建立API的開發者工具和SDK
  6. 設計第三方整合的API授權機制

新功能整合相關 (新增類別)

  1. 訂閱系統與現有付費功能的整合測試
  2. 特殊任務系統與遊戲化元素的API整合
  3. 語言程度系統與學習路徑規劃的API對接
  4. 三大新系統間的數據一致性保證機制
  5. 新功能的A/B測試API設計和實現

最後更新: 2024年9月5日
負責人: 待分配
審查週期: 每兩週檢討一次