feat: restructure API specifications into modular architecture
Major refactoring of API documentation for better maintainability: ## New Modular Structure - Split 2400+ line monolithic API spec into 10 focused modules - Created centralized navigation at docs/04_technical/api/README.md - Each module now 200-400 lines for easier maintenance ## Completed API Modules (7/10) - ✅ Authentication & Authorization API (JWT, OAuth, permissions) - ✅ User Management API (profiles, stats, achievements) - ✅ Dialogue Practice API (scenarios, AI analysis, assistance) - ✅ Subscription System API (in-app purchases, permissions) - ✅ Daily Missions API (tasks, progress, rewards) - ✅ Error Handling (comprehensive error codes) - ✅ Common Standards (RESTful principles, formats) ## Updated Specifications - Third-party integration spec with iOS/Android in-app purchases - API completion plan with 3-phase development strategy - Organized processed requirements in 已處理/ folder ## Technical Improvements - 35+ API endpoints fully documented with examples - 11 error categories with handling guidelines - Unified response formats and security standards - Team-friendly parallel development structure 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
|
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"permissions": {
|
||||
"allow": [
|
||||
"Bash(python3:*)",
|
||||
"Read(//Users/jettcheng1018/Downloads/**)"
|
||||
],
|
||||
"deny": [],
|
||||
"ask": []
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 64 KiB After Width: | Height: | Size: 64 KiB |
|
|
@ -0,0 +1,6 @@
|
|||
以下有一些要修正
|
||||
1. 收費平台不用stripe或任何第三方支付,應該是直接使用雙平台各自的內購
|
||||
2. 我只會先在台灣開放,所以支援台幣就好
|
||||
3. 對話生成相關 api 使用gpt-4o-mini為主
|
||||
4. 語言評估使用microsoft相關的api
|
||||
5. stt和tts使用google
|
||||
|
Before Width: | Height: | Size: 110 KiB After Width: | Height: | Size: 110 KiB |
|
Before Width: | Height: | Size: 49 KiB After Width: | Height: | Size: 49 KiB |
|
|
@ -0,0 +1,154 @@
|
|||
# Drama Ling API 規格文檔
|
||||
|
||||
## 📋 總覽
|
||||
Drama Ling 應用的完整 RESTful API 規格文檔,採用模組化設計便於維護和擴展。
|
||||
|
||||
## 🏗️ API 架構
|
||||
|
||||
### Base URL
|
||||
```
|
||||
Production: https://api.dramaling.com
|
||||
Staging: https://staging-api.dramaling.com
|
||||
Development: https://dev-api.dramaling.com
|
||||
```
|
||||
|
||||
### 版本控制
|
||||
所有 API 端點使用 `/api/v1/` 前綴進行版本控制。
|
||||
|
||||
## 📚 模組文檔導航
|
||||
|
||||
### 🔐 核心認證與用戶
|
||||
| 模組 | 文檔 | 描述 | 端點數量 |
|
||||
|------|------|------|----------|
|
||||
| **認證與授權** | [authentication.md](./authentication.md) ✅ | JWT認證、登入、登出、第三方登入 | 6個 |
|
||||
| **用戶管理** | [user-management.md](./user-management.md) ✅ | 用戶資料、個人檔案、學習統計 | 8個 |
|
||||
|
||||
### 🎓 學習核心功能
|
||||
| 模組 | 文檔 | 描述 | 端點數量 |
|
||||
|------|------|------|----------|
|
||||
| **學習內容** | [learning-content.md](./learning-content.md) ⏳ | 課程、場景、內容管理 | 5個 |
|
||||
| **對話練習** | [dialogue-practice.md](./dialogue-practice.md) ✅ | 對話系統、AI分析、回覆輔助 | 8個 |
|
||||
| **詞彙系統** | [vocabulary.md](./vocabulary.md) ⏳ | 間隔複習、熟悉度練習、詞彙管理 | 8個 |
|
||||
|
||||
### 🎮 遊戲化與競爭
|
||||
| 模組 | 文檔 | 描述 | 端點數量 |
|
||||
|------|------|------|----------|
|
||||
| **遊戲化系統** | [gamification.md](./gamification.md) ⏳ | 命條、時光挑戰、廣告獎勵、排行榜 | 15個 |
|
||||
|
||||
### 💳 商業功能
|
||||
| 模組 | 文檔 | 描述 | 端點數量 |
|
||||
|------|------|------|----------|
|
||||
| **訂閱系統** | [subscription.md](./subscription.md) ✅ | 訂閱方案、內購驗證、權限管理 | 7個 |
|
||||
|
||||
### 🏆 進階功能
|
||||
| 模組 | 文檔 | 描述 | 端點數量 |
|
||||
|------|------|------|----------|
|
||||
| **特殊任務** | [daily-missions.md](./daily-missions.md) ✅ | 每日任務、獎勵系統、進度追蹤 | 6個 |
|
||||
| **語言程度** | [language-levels.md](./language-levels.md) ⏳ | 13級程度系統、晉階機制 | 7個 |
|
||||
|
||||
### ⚙️ 系統支援
|
||||
| 模組 | 文檔 | 描述 | 說明 |
|
||||
|------|------|------|------|
|
||||
| **錯誤處理** | [errors.md](./errors.md) ✅ | 標準錯誤碼、錯誤回應格式 | 11個錯誤類別 |
|
||||
| **共通規範** | [common.md](./common.md) ✅ | API設計原則、回應格式、安全規範 | 設計標準 |
|
||||
|
||||
## 🔧 API 設計原則
|
||||
|
||||
### RESTful 標準
|
||||
- ✅ 資源導向的URL設計
|
||||
- ✅ 標準HTTP動詞 (GET, POST, PUT, DELETE, PATCH)
|
||||
- ✅ 統一的HTTP狀態碼
|
||||
- ✅ 無狀態設計
|
||||
- ✅ 版本控制策略
|
||||
|
||||
### 安全原則
|
||||
- ✅ JWT Token認證
|
||||
- ✅ Role-based權限控制
|
||||
- ✅ 嚴格資料驗證
|
||||
- ✅ API速率限制
|
||||
- ✅ 強制HTTPS傳輸
|
||||
|
||||
### 回應格式
|
||||
所有API使用統一的JSON回應格式:
|
||||
```json
|
||||
{
|
||||
"success": boolean,
|
||||
"data": object | array | null,
|
||||
"message": string,
|
||||
"error": {
|
||||
"code": "ERROR_CODE",
|
||||
"message": "錯誤描述",
|
||||
"details": {}
|
||||
},
|
||||
"meta": {
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"request_id": "uuid-string",
|
||||
"pagination": {}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📈 API 統計
|
||||
|
||||
### 整體規模
|
||||
- **總端點數量**: 78個API端點
|
||||
- **功能模組**: 10個主要模組
|
||||
- **錯誤類別**: 11種錯誤類型
|
||||
- **文檔行數**: ~2,400行 → 分拆為10個文件
|
||||
|
||||
### 開發狀態
|
||||
- ✅ **已完成**: 7個核心模組 (認證、用戶、對話、訂閱、任務、錯誤、共通) (70%)
|
||||
- 🔄 **進行中**: 剩餘4個模組拆分 (遊戲化、語言程度、詞彙、學習內容) (25%)
|
||||
- ⏳ **待優化**: API詳細範例和整合測試 (5%)
|
||||
|
||||
## 🚀 快速開始
|
||||
|
||||
### 1. 認證流程
|
||||
```bash
|
||||
# 用戶註冊
|
||||
POST /api/v1/auth/register
|
||||
|
||||
# 用戶登入取得Token
|
||||
POST /api/v1/auth/login
|
||||
|
||||
# 使用Token存取API
|
||||
GET /api/v1/user/profile
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
### 2. 常用API範例
|
||||
- 取得學習統計:`GET /api/v1/user/learning-stats`
|
||||
- 開始對話練習:`POST /api/v1/dialogues/start`
|
||||
- 獲取今日任務:`GET /api/v1/missions/today`
|
||||
- 檢查訂閱狀態:`GET /api/v1/subscriptions/status`
|
||||
|
||||
## 📖 相關文檔
|
||||
|
||||
### 技術文檔
|
||||
- [資料庫架構設計](../database-schema.md)
|
||||
- [第三方服務整合](../third-party-integration-specification.md)
|
||||
- [Flutter/.NET整合指南](../flutter-dotnet-integration.md)
|
||||
|
||||
### 開發計劃
|
||||
- [API完善計劃](../api-specifications-completion-plan.md)
|
||||
- [技術選型決策](../tech-stack-decision.md)
|
||||
|
||||
## 🤝 貢獻指南
|
||||
|
||||
### 文檔維護
|
||||
- 每個模組文件維持在200-400行
|
||||
- 所有API端點需要完整範例
|
||||
- 錯誤情境需要詳細說明
|
||||
- 定期同步更新相關文檔
|
||||
|
||||
### 版本更新
|
||||
- API變更需要版本控制
|
||||
- 向後相容性考量
|
||||
- 廢棄API提前通知機制
|
||||
|
||||
---
|
||||
|
||||
**文件版本**: v2.0 (模組化重構)
|
||||
**最後更新**: 2024年9月7日
|
||||
**維護負責**: 技術團隊
|
||||
**下次審查**: 每月第一週檢討更新
|
||||
|
|
@ -0,0 +1,352 @@
|
|||
# 認證與授權 API
|
||||
|
||||
## 📋 概述
|
||||
Drama Ling 應用的認證與授權系統,支援傳統註冊登入和第三方社群登入(Apple ID、Google)。
|
||||
|
||||
## 🔐 JWT 認證機制
|
||||
|
||||
### Token 結構
|
||||
```json
|
||||
{
|
||||
"alg": "HS256",
|
||||
"typ": "JWT"
|
||||
}
|
||||
{
|
||||
"sub": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"email": "user@example.com",
|
||||
"username": "dramatic_learner",
|
||||
"role": "user", // user, subscriber, admin
|
||||
"subscription_status": "active", // active, inactive, trial
|
||||
"iat": 1693920600,
|
||||
"exp": 1693924200
|
||||
}
|
||||
```
|
||||
|
||||
### Token 生命週期
|
||||
- **Access Token**: 1小時有效期
|
||||
- **Refresh Token**: 30天有效期
|
||||
- **Token 輪替**: 每次刷新會產生新的 Refresh Token
|
||||
- **Token 黑名單**: 登出時將 Token 加入黑名單
|
||||
|
||||
## 📌 API 端點
|
||||
|
||||
### 1. 用戶註冊
|
||||
```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,
|
||||
"userRole": "user",
|
||||
"isNewUser": true
|
||||
},
|
||||
"message": "User registered successfully",
|
||||
"meta": {
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"requestId": "550e8400-e29b-41d4-a716-446655440002"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 註冊驗證規則
|
||||
- **Email**: 有效的電子郵件格式
|
||||
- **Password**: 最少8位,包含大小寫字母和數字
|
||||
- **Username**: 3-20字元,僅允許字母數字和底線
|
||||
- **Language**: ISO 639-1 語言碼
|
||||
|
||||
#### 錯誤處理
|
||||
```http
|
||||
Response 400 Bad Request
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "VALIDATION_ERROR",
|
||||
"message": "註冊資料驗證失敗",
|
||||
"details": {
|
||||
"email": ["Email format is invalid"],
|
||||
"password": ["Password must be at least 8 characters"],
|
||||
"username": ["Username already exists"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 用戶登入
|
||||
```http
|
||||
POST /api/v1/auth/login
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"email": "user@example.com",
|
||||
"password": "securePassword123",
|
||||
"rememberMe": true
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"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,
|
||||
"userRole": "subscriber",
|
||||
"subscriptionStatus": "active",
|
||||
"lastLoginAt": "2024-09-07T12:00:00Z"
|
||||
},
|
||||
"message": "Login successful"
|
||||
}
|
||||
```
|
||||
|
||||
#### 錯誤處理
|
||||
```http
|
||||
Response 401 Unauthorized
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "INVALID_CREDENTIALS",
|
||||
"message": "Email或密碼錯誤",
|
||||
"details": {
|
||||
"attemptCount": 3,
|
||||
"lockoutTime": null
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Token 刷新
|
||||
```http
|
||||
POST /api/v1/auth/refresh
|
||||
Authorization: Bearer <refresh_token>
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"refreshToken": "550e8400-e29b-41d4-a716-446655440001",
|
||||
"expiresIn": 3600,
|
||||
"tokenType": "Bearer"
|
||||
},
|
||||
"message": "Token refreshed successfully"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 用戶登出
|
||||
```http
|
||||
POST /api/v1/auth/logout
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"loggedOut": true,
|
||||
"tokenBlacklisted": true
|
||||
},
|
||||
"message": "Logout successful"
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Apple ID 登入
|
||||
```http
|
||||
POST /api/v1/auth/apple
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"identityToken": "apple_identity_token",
|
||||
"authorizationCode": "apple_authorization_code",
|
||||
"userIdentifier": "apple_user_identifier",
|
||||
"email": "user@privaterelay.appleid.com",
|
||||
"fullName": {
|
||||
"givenName": "John",
|
||||
"familyName": "Doe"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"userId": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"username": "apple_user_12345",
|
||||
"email": "user@privaterelay.appleid.com",
|
||||
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"refreshToken": "550e8400-e29b-41d4-a716-446655440001",
|
||||
"expiresIn": 3600,
|
||||
"isNewUser": false,
|
||||
"authProvider": "apple"
|
||||
},
|
||||
"message": "Apple login successful"
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Google 登入
|
||||
```http
|
||||
POST /api/v1/auth/google
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"idToken": "google_id_token",
|
||||
"accessToken": "google_access_token",
|
||||
"serverAuthCode": "google_server_auth_code"
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"userId": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"username": "google_user_12345",
|
||||
"email": "user@gmail.com",
|
||||
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||||
"refreshToken": "550e8400-e29b-41d4-a716-446655440001",
|
||||
"expiresIn": 3600,
|
||||
"isNewUser": true,
|
||||
"authProvider": "google"
|
||||
},
|
||||
"message": "Google login successful"
|
||||
}
|
||||
```
|
||||
|
||||
## 🔒 權限控制
|
||||
|
||||
### 用戶角色
|
||||
```typescript
|
||||
enum UserRole {
|
||||
USER = "user", // 免費用戶
|
||||
SUBSCRIBER = "subscriber", // 訂閱用戶
|
||||
ADMIN = "admin" // 管理員
|
||||
}
|
||||
```
|
||||
|
||||
### 權限矩陣
|
||||
| 功能 | 免費用戶 | 訂閱用戶 | 管理員 |
|
||||
|------|----------|----------|---------|
|
||||
| 基礎對話練習 | 3次/日 | 無限制 | 無限制 |
|
||||
| 高級對話功能 | ❌ | ✅ | ✅ |
|
||||
| 詞彙複習 | 基礎 | 進階 | 完整 |
|
||||
| 特殊任務 | 部分 | 完整 | 完整 |
|
||||
| 數據分析 | 基礎 | 詳細 | 完整 |
|
||||
| 管理功能 | ❌ | ❌ | ✅ |
|
||||
|
||||
### 權限檢查中介軟體
|
||||
```javascript
|
||||
// API 權限檢查範例
|
||||
app.use('/api/v1/dialogues/advanced', requireSubscription);
|
||||
app.use('/api/v1/admin/*', requireAdminRole);
|
||||
|
||||
function requireSubscription(req, res, next) {
|
||||
if (req.user.role !== 'subscriber' && req.user.role !== 'admin') {
|
||||
return res.status(403).json({
|
||||
success: false,
|
||||
error: {
|
||||
code: "SUBSCRIPTION_REQUIRED",
|
||||
message: "此功能需要訂閱會員"
|
||||
}
|
||||
});
|
||||
}
|
||||
next();
|
||||
}
|
||||
```
|
||||
|
||||
## ⚡ 安全措施
|
||||
|
||||
### 密碼安全
|
||||
- **加密**: bcrypt + salt,成本因子 12
|
||||
- **複雜度**: 最少8位,大小寫字母+數字
|
||||
- **重設**: 臨時token,15分鐘有效期
|
||||
|
||||
### 防攻擊機制
|
||||
- **Rate Limiting**: 每IP每分鐘5次登入嘗試
|
||||
- **帳號鎖定**: 5次失敗後鎖定15分鐘
|
||||
- **CSRF Protection**: 所有POST請求需要CSRF token
|
||||
- **Input Sanitization**: 所有輸入進行清理和驗證
|
||||
|
||||
### Token 安全
|
||||
- **HTTPS Only**: 所有認證相關請求強制HTTPS
|
||||
- **HttpOnly Cookies**: Refresh token存放在HttpOnly cookie
|
||||
- **Token 黑名單**: 登出和可疑活動時加入黑名單
|
||||
- **定期輪替**: 每24小時自動輪替長期token
|
||||
|
||||
## 🔧 錯誤碼
|
||||
|
||||
### 認證相關錯誤
|
||||
| 錯誤碼 | HTTP狀態 | 描述 |
|
||||
|--------|----------|------|
|
||||
| `INVALID_CREDENTIALS` | 401 | 登入憑證錯誤 |
|
||||
| `TOKEN_EXPIRED` | 401 | Token已過期 |
|
||||
| `TOKEN_INVALID` | 401 | Token無效或格式錯誤 |
|
||||
| `TOKEN_BLACKLISTED` | 401 | Token已被列入黑名單 |
|
||||
| `ACCOUNT_LOCKED` | 423 | 帳號因多次失敗嘗試被鎖定 |
|
||||
| `EMAIL_EXISTS` | 409 | 電子郵件已被註冊 |
|
||||
| `USERNAME_EXISTS` | 409 | 使用者名稱已存在 |
|
||||
| `VALIDATION_ERROR` | 400 | 輸入資料驗證失敗 |
|
||||
| `SOCIAL_LOGIN_ERROR` | 400 | 第三方登入驗證失敗 |
|
||||
|
||||
## 🧪 測試指南
|
||||
|
||||
### 測試用例
|
||||
```bash
|
||||
# 正常註冊流程測試
|
||||
curl -X POST https://api.dramaling.com/api/v1/auth/register \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"test@example.com","password":"Test123456","username":"testuser"}'
|
||||
|
||||
# 登入流程測試
|
||||
curl -X POST https://api.dramaling.com/api/v1/auth/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"email":"test@example.com","password":"Test123456"}'
|
||||
|
||||
# Token刷新測試
|
||||
curl -X POST https://api.dramaling.com/api/v1/auth/refresh \
|
||||
-H "Authorization: Bearer <refresh_token>"
|
||||
```
|
||||
|
||||
### 安全測試
|
||||
- **暴力破解測試**: 驗證帳號鎖定機制
|
||||
- **Token洩漏測試**: 驗證Token黑名單機制
|
||||
- **權限繞過測試**: 驗證角色權限控制
|
||||
- **資料注入測試**: 驗證輸入清理機制
|
||||
|
||||
---
|
||||
|
||||
**模組負責人**: 後端團隊
|
||||
**最後更新**: 2024年9月7日
|
||||
**相關文檔**: [用戶管理API](./user-management.md), [錯誤處理](./errors.md)
|
||||
|
|
@ -0,0 +1,297 @@
|
|||
# API 共通規範
|
||||
|
||||
## 📋 概述
|
||||
所有 Drama Ling API 共用的設計原則、資料格式、安全規範等。
|
||||
|
||||
## 🏗️ RESTful 設計標準
|
||||
|
||||
### ✅ 已實施的設計標準
|
||||
- **資源導向**: API端點基於資源設計而非動作
|
||||
- **HTTP動詞**: 正確使用GET、POST、PUT、DELETE、PATCH
|
||||
- **狀態碼**: 使用標準HTTP狀態碼表示結果
|
||||
- **無狀態**: API設計為無狀態,不依賴server端session
|
||||
- **版本控制**: API版本控制策略 (使用 `/api/v1/`)
|
||||
|
||||
### HTTP 動詞使用規範
|
||||
| 動詞 | 用途 | 範例 |
|
||||
|------|------|------|
|
||||
| GET | 讀取資源 | `GET /api/v1/users/profile` |
|
||||
| POST | 創建資源 | `POST /api/v1/auth/login` |
|
||||
| PUT | 完整更新資源 | `PUT /api/v1/users/profile` |
|
||||
| PATCH | 部分更新資源 | `PATCH /api/v1/users/preferences` |
|
||||
| DELETE | 刪除資源 | `DELETE /api/v1/users/account` |
|
||||
|
||||
### HTTP 狀態碼標準
|
||||
| 狀態碼 | 含義 | 使用場景 |
|
||||
|--------|------|----------|
|
||||
| 200 | OK | 請求成功 |
|
||||
| 201 | Created | 資源創建成功 |
|
||||
| 204 | No Content | 成功但無回應內容 |
|
||||
| 400 | Bad Request | 請求格式錯誤 |
|
||||
| 401 | Unauthorized | 未認證或Token無效 |
|
||||
| 403 | Forbidden | 無權限存取 |
|
||||
| 404 | Not Found | 資源不存在 |
|
||||
| 409 | Conflict | 資源衝突 |
|
||||
| 422 | Unprocessable Entity | 資料驗證失敗 |
|
||||
| 429 | Too Many Requests | 請求頻率超限 |
|
||||
| 500 | Internal Server Error | 伺服器內部錯誤 |
|
||||
|
||||
## 📦 統一回應格式
|
||||
|
||||
### 成功回應格式
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
// 回應資料內容
|
||||
},
|
||||
"message": "操作成功描述",
|
||||
"meta": {
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"request_id": "req_550e8400-e29b-41d4-a716-446655440000",
|
||||
"api_version": "v1",
|
||||
"pagination": {
|
||||
"current_page": 1,
|
||||
"total_pages": 5,
|
||||
"total_items": 89,
|
||||
"items_per_page": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 錯誤回應格式
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": null,
|
||||
"message": "操作失敗描述",
|
||||
"error": {
|
||||
"code": "SPECIFIC_ERROR_CODE",
|
||||
"message": "詳細錯誤訊息",
|
||||
"details": {
|
||||
"field": "username",
|
||||
"reason": "Username already exists",
|
||||
"suggestion": "Please choose a different username"
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"request_id": "req_550e8400-e29b-41d4-a716-446655440000",
|
||||
"api_version": "v1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 分頁回應格式
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"items": [
|
||||
// 資料陣列
|
||||
]
|
||||
},
|
||||
"meta": {
|
||||
"pagination": {
|
||||
"current_page": 2,
|
||||
"total_pages": 10,
|
||||
"total_items": 195,
|
||||
"items_per_page": 20,
|
||||
"has_next": true,
|
||||
"has_prev": true,
|
||||
"next_url": "/api/v1/resource?page=3&limit=20",
|
||||
"prev_url": "/api/v1/resource?page=1&limit=20"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔒 API 安全原則
|
||||
|
||||
### ✅ 已實施的安全措施
|
||||
- **身份驗證**: JWT Token認證機制
|
||||
- **授權控制**: Role-based權限控制
|
||||
- **資料驗證**: 嚴格的輸入資料驗證
|
||||
- **速率限制**: 防止API濫用的速率控制
|
||||
- **HTTPS強制**: 所有API強制使用HTTPS
|
||||
|
||||
### JWT Token 認證
|
||||
```http
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
### API Key 認證 (內部服務)
|
||||
```http
|
||||
X-API-Key: api_key_here
|
||||
X-Client-ID: client_id_here
|
||||
```
|
||||
|
||||
### 速率限制
|
||||
| 用戶類型 | 限制 | 窗口 |
|
||||
|----------|------|------|
|
||||
| 免費用戶 | 100 請求 | 每小時 |
|
||||
| 訂閱用戶 | 500 請求 | 每小時 |
|
||||
| API 金鑰 | 1000 請求 | 每小時 |
|
||||
|
||||
## 📅 版本控制策略
|
||||
|
||||
### URL 版本控制
|
||||
- **格式**: `/api/v1/`, `/api/v2/`
|
||||
- **向後相容**: 新版本保持向後相容性
|
||||
- **廢棄通知**: 提前6個月通知API廢棄
|
||||
- **多版本支援**: 同時支援2-3個版本
|
||||
- **版本文檔**: 每個版本維護獨立文檔
|
||||
|
||||
### 版本生命週期
|
||||
```
|
||||
v1.0 (穩定版) ──── v1.1 (向下相容更新)
|
||||
│ │
|
||||
└─ v2.0 (重大變更) ──── v2.1 (向下相容更新)
|
||||
```
|
||||
|
||||
## 🌍 國際化支援
|
||||
|
||||
### 語言標頭
|
||||
```http
|
||||
Accept-Language: zh-TW, en-US;q=0.8
|
||||
```
|
||||
|
||||
### 時區處理
|
||||
```http
|
||||
X-Timezone: Asia/Taipei
|
||||
```
|
||||
|
||||
### 日期時間格式
|
||||
- **標準**: ISO 8601 格式 (`2024-09-07T12:00:00Z`)
|
||||
- **時區**: 統一使用UTC,客戶端負責本地化
|
||||
|
||||
## 📊 效能考量
|
||||
|
||||
### ✅ 已實施的效能優化
|
||||
- **回應時間**: 95%的API請求在200ms內回應
|
||||
- **快取策略**: 靜態內容使用CDN,動態內容使用Redis
|
||||
- **資料庫優化**: 適當的索引和查詢優化
|
||||
- **負載平衡**: 水平擴展API服務器
|
||||
- **監控告警**: API效能和錯誤率監控
|
||||
|
||||
### 快取標頭
|
||||
```http
|
||||
Cache-Control: max-age=300, must-revalidate
|
||||
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
|
||||
Last-Modified: Wed, 07 Sep 2024 12:00:00 GMT
|
||||
```
|
||||
|
||||
### 壓縮支援
|
||||
```http
|
||||
Accept-Encoding: gzip, deflate, br
|
||||
Content-Encoding: gzip
|
||||
```
|
||||
|
||||
## 🔍 請求追蹤
|
||||
|
||||
### 請求識別
|
||||
每個 API 請求都會分配唯一的請求 ID:
|
||||
```http
|
||||
X-Request-ID: req_550e8400-e29b-41d4-a716-446655440000
|
||||
```
|
||||
|
||||
### 除錯標頭
|
||||
```http
|
||||
X-Debug-Mode: true
|
||||
X-Correlation-ID: corr_12345
|
||||
```
|
||||
|
||||
## 📋 資料驗證規則
|
||||
|
||||
### 通用驗證規則
|
||||
- **Email**: RFC 5322 標準
|
||||
- **Password**: 最少8位,包含大小寫字母和數字
|
||||
- **Username**: 3-20字元,僅允許字母數字和底線
|
||||
- **URL**: 有效的HTTP/HTTPS URL
|
||||
- **UUID**: 標準UUID格式
|
||||
|
||||
### 輸入清理
|
||||
- **XSS 防護**: 自動清理HTML標籤
|
||||
- **SQL 注入防護**: 參數化查詢
|
||||
- **檔案上傳**: 類型和大小限制
|
||||
- **JSON 深度**: 最大巢狀層級限制
|
||||
|
||||
## 🚦 API 狀態監控
|
||||
|
||||
### 健康檢查端點
|
||||
```http
|
||||
GET /health
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"version": "1.0.0",
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"checks": {
|
||||
"database": "healthy",
|
||||
"redis": "healthy",
|
||||
"external_apis": "healthy"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 服務狀態
|
||||
```http
|
||||
GET /api/v1/status
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
```json
|
||||
{
|
||||
"api_status": "operational",
|
||||
"maintenance_mode": false,
|
||||
"rate_limit_remaining": 450,
|
||||
"rate_limit_reset": "2024-09-07T13:00:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## 📝 請求範例
|
||||
|
||||
### 標準 GET 請求
|
||||
```bash
|
||||
curl -X GET "https://api.dramaling.com/api/v1/users/profile" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "Accept: application/json" \
|
||||
-H "Accept-Language: zh-TW"
|
||||
```
|
||||
|
||||
### 標準 POST 請求
|
||||
```bash
|
||||
curl -X POST "https://api.dramaling.com/api/v1/dialogues/start" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-H "Accept: application/json" \
|
||||
-d '{"scenario_id": "restaurant_order"}'
|
||||
```
|
||||
|
||||
### 檔案上傳請求
|
||||
```bash
|
||||
curl -X POST "https://api.dramaling.com/api/v1/users/avatar" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-F "avatar=@/path/to/image.jpg"
|
||||
```
|
||||
|
||||
## 🔧 開發工具
|
||||
|
||||
### Swagger/OpenAPI 文檔
|
||||
- **URL**: https://api.dramaling.com/docs
|
||||
- **互動測試**: 支援直接在文檔中測試API
|
||||
- **Schema 驗證**: 自動驗證請求和回應格式
|
||||
|
||||
### Postman Collection
|
||||
- **檔案**: `dramaling-api.postman_collection.json`
|
||||
- **環境變數**: 開發/測試/生產環境設定
|
||||
- **自動化測試**: API 回歸測試套件
|
||||
|
||||
---
|
||||
|
||||
**負責人**: 技術架構團隊
|
||||
**最後更新**: 2024年9月7日
|
||||
**相關文檔**: [錯誤處理](./errors.md), [認證API](./authentication.md)
|
||||
|
|
@ -0,0 +1,596 @@
|
|||
# 特殊任務系統 API
|
||||
|
||||
## 📋 概述
|
||||
Drama Ling 的每日任務系統,提供4種任務類型,透過遊戲化機制增加用戶黏性和學習動機。
|
||||
|
||||
## 🎯 任務系統特色
|
||||
|
||||
### 4種任務類型
|
||||
1. **詞彙認識挑戰** - 詞彙認識關卡三星通關
|
||||
2. **詞彙熟悉挑戰** - 詞彙熟悉關卡三星通關
|
||||
3. **對話訓練挑戰** - 對話訓練關卡完成通關
|
||||
4. **完美對話挑戰** - 對話訓練關卡滿星評價
|
||||
|
||||
### 任務機制
|
||||
- **每日重置** - 每日 00:00 (GMT+8) 重新生成任務
|
||||
- **完成獎勵** - 經驗值、鑽石、成就等獎勵
|
||||
- **進度追蹤** - 即時更新任務完成進度
|
||||
- **限時完成** - 當日 23:59:59 前完成
|
||||
|
||||
## 📌 API 端點
|
||||
|
||||
### 1. 獲取今日任務
|
||||
```http
|
||||
GET /api/v1/missions/daily
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 查詢參數
|
||||
- `include_history`: 是否包含歷史完成記錄 (`true`/`false`)
|
||||
- `timezone`: 用戶時區 (預設 `Asia/Taipei`)
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"mission_date": "2024-09-07",
|
||||
"timezone": "Asia/Taipei",
|
||||
"reset_time": "2024-09-08T00:00:00+08:00",
|
||||
"time_remaining": {
|
||||
"hours": 14,
|
||||
"minutes": 25,
|
||||
"seconds": 30
|
||||
},
|
||||
"daily_missions": [
|
||||
{
|
||||
"mission_id": "MISSION_VOCAB_RECOGNITION_20240907",
|
||||
"type": "vocabulary_recognition",
|
||||
"priority": 1,
|
||||
"title": "詞彙認識挑戰",
|
||||
"description": "在詞彙認識關卡獲得三星評價1次",
|
||||
"icon": "🎯",
|
||||
"category": "vocabulary",
|
||||
"difficulty": "normal",
|
||||
"estimated_time": 5, // minutes
|
||||
"objectives": [
|
||||
{
|
||||
"objective_id": "OBJ_VOCAB_RECOGNITION_3STAR",
|
||||
"description": "詞彙認識關卡三星通關",
|
||||
"target_value": 1,
|
||||
"current_value": 0,
|
||||
"unit": "次",
|
||||
"completion_criteria": "three_star_completion",
|
||||
"progress_percentage": 0
|
||||
}
|
||||
],
|
||||
"rewards": {
|
||||
"primary_reward": {
|
||||
"type": "experience_points",
|
||||
"amount": 50,
|
||||
"description": "獲得50經驗值"
|
||||
},
|
||||
"bonus_rewards": [
|
||||
{
|
||||
"type": "diamonds",
|
||||
"amount": 5,
|
||||
"description": "獲得5鑽石"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": "available", // available, in_progress, completed, expired
|
||||
"deadline": "2024-09-07T23:59:59+08:00",
|
||||
"completion_tracking": {
|
||||
"started_at": null,
|
||||
"completed_at": null,
|
||||
"attempts": 0,
|
||||
"last_attempt_at": null
|
||||
}
|
||||
},
|
||||
{
|
||||
"mission_id": "MISSION_VOCAB_FLUENCY_20240907",
|
||||
"type": "vocabulary_fluency",
|
||||
"priority": 2,
|
||||
"title": "詞彙熟悉挑戰",
|
||||
"description": "在詞彙熟悉關卡獲得三星評價1次",
|
||||
"icon": "💪",
|
||||
"category": "vocabulary",
|
||||
"difficulty": "normal",
|
||||
"estimated_time": 8,
|
||||
"objectives": [
|
||||
{
|
||||
"objective_id": "OBJ_VOCAB_FLUENCY_3STAR",
|
||||
"description": "詞彙熟悉關卡三星通關",
|
||||
"target_value": 1,
|
||||
"current_value": 0,
|
||||
"unit": "次",
|
||||
"completion_criteria": "three_star_completion",
|
||||
"progress_percentage": 0
|
||||
}
|
||||
],
|
||||
"rewards": {
|
||||
"primary_reward": {
|
||||
"type": "experience_points",
|
||||
"amount": 50,
|
||||
"description": "獲得50經驗值"
|
||||
},
|
||||
"bonus_rewards": [
|
||||
{
|
||||
"type": "diamonds",
|
||||
"amount": 5,
|
||||
"description": "獲得5鑽石"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": "available",
|
||||
"deadline": "2024-09-07T23:59:59+08:00"
|
||||
},
|
||||
{
|
||||
"mission_id": "MISSION_DIALOGUE_TRAINING_20240907",
|
||||
"type": "dialogue_training",
|
||||
"priority": 3,
|
||||
"title": "對話訓練挑戰",
|
||||
"description": "完成對話訓練關卡1次",
|
||||
"icon": "💬",
|
||||
"category": "dialogue",
|
||||
"difficulty": "normal",
|
||||
"estimated_time": 15,
|
||||
"requires_subscription": true,
|
||||
"objectives": [
|
||||
{
|
||||
"objective_id": "OBJ_DIALOGUE_COMPLETION",
|
||||
"description": "完成對話訓練關卡",
|
||||
"target_value": 1,
|
||||
"current_value": 1,
|
||||
"unit": "次",
|
||||
"completion_criteria": "completion_only",
|
||||
"progress_percentage": 100
|
||||
}
|
||||
],
|
||||
"rewards": {
|
||||
"primary_reward": {
|
||||
"type": "experience_points",
|
||||
"amount": 75,
|
||||
"description": "獲得75經驗值"
|
||||
},
|
||||
"bonus_rewards": [
|
||||
{
|
||||
"type": "diamonds",
|
||||
"amount": 10,
|
||||
"description": "獲得10鑽石"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": "completed",
|
||||
"deadline": "2024-09-07T23:59:59+08:00",
|
||||
"completed_at": "2024-09-07T14:30:00+08:00",
|
||||
"reward_claimed": false
|
||||
},
|
||||
{
|
||||
"mission_id": "MISSION_PERFECT_DIALOGUE_20240907",
|
||||
"type": "perfect_dialogue",
|
||||
"priority": 4,
|
||||
"title": "完美對話挑戰",
|
||||
"description": "在對話訓練關卡獲得滿星評價1次",
|
||||
"icon": "⭐",
|
||||
"category": "dialogue",
|
||||
"difficulty": "hard",
|
||||
"estimated_time": 20,
|
||||
"requires_subscription": true,
|
||||
"objectives": [
|
||||
{
|
||||
"objective_id": "OBJ_PERFECT_DIALOGUE",
|
||||
"description": "對話訓練關卡獲得滿星評價",
|
||||
"target_value": 1,
|
||||
"current_value": 0,
|
||||
"unit": "次",
|
||||
"completion_criteria": "perfect_score", // score >= 90
|
||||
"progress_percentage": 0
|
||||
}
|
||||
],
|
||||
"rewards": {
|
||||
"primary_reward": {
|
||||
"type": "experience_points",
|
||||
"amount": 100,
|
||||
"description": "獲得100經驗值"
|
||||
},
|
||||
"bonus_rewards": [
|
||||
{
|
||||
"type": "diamonds",
|
||||
"amount": 20,
|
||||
"description": "獲得20鑽石"
|
||||
},
|
||||
{
|
||||
"type": "achievement",
|
||||
"achievement_id": "daily_perfectionist",
|
||||
"description": "解鎖「每日完美主義者」成就"
|
||||
}
|
||||
]
|
||||
},
|
||||
"status": "available",
|
||||
"deadline": "2024-09-07T23:59:59+08:00"
|
||||
}
|
||||
],
|
||||
"daily_summary": {
|
||||
"total_missions": 4,
|
||||
"completed_missions": 1,
|
||||
"available_missions": 3,
|
||||
"completion_percentage": 25,
|
||||
"total_rewards_earned": {
|
||||
"experience_points": 0, // 未領取的獎勵
|
||||
"diamonds": 0
|
||||
},
|
||||
"total_rewards_available": {
|
||||
"experience_points": 275,
|
||||
"diamonds": 40
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 任務進度更新 (系統內部調用)
|
||||
```http
|
||||
POST /api/v1/missions/progress-update
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"trigger_event": "dialogue_completed", // vocabulary_completed, dialogue_completed, perfect_score_achieved
|
||||
"event_context": {
|
||||
"activity_type": "dialogue_training",
|
||||
"scenario_id": "SC_Restaurant_01",
|
||||
"completion_score": 85,
|
||||
"is_three_star": false,
|
||||
"is_perfect_score": false,
|
||||
"completed_at": "2024-09-07T15:30:00+08:00"
|
||||
},
|
||||
"user_context": {
|
||||
"subscription_status": "active",
|
||||
"current_level": "B1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"progress_updates": [
|
||||
{
|
||||
"mission_id": "MISSION_DIALOGUE_TRAINING_20240907",
|
||||
"previous_progress": {
|
||||
"current_value": 0,
|
||||
"progress_percentage": 0
|
||||
},
|
||||
"updated_progress": {
|
||||
"current_value": 1,
|
||||
"progress_percentage": 100
|
||||
},
|
||||
"mission_completed": true,
|
||||
"completion_time": "2024-09-07T15:30:00+08:00"
|
||||
}
|
||||
],
|
||||
"missions_completed_count": 1,
|
||||
"rewards_unlocked": [
|
||||
{
|
||||
"mission_id": "MISSION_DIALOGUE_TRAINING_20240907",
|
||||
"rewards": [
|
||||
{
|
||||
"type": "experience_points",
|
||||
"amount": 75
|
||||
},
|
||||
{
|
||||
"type": "diamonds",
|
||||
"amount": 10
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"message": "Mission progress updated successfully"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 領取任務獎勵
|
||||
```http
|
||||
POST /api/v1/missions/{mission_id}/claim-reward
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"mission_id": "MISSION_DIALOGUE_TRAINING_20240907",
|
||||
"rewards_claimed": [
|
||||
{
|
||||
"type": "experience_points",
|
||||
"amount": 75,
|
||||
"previous_total": 1250,
|
||||
"new_total": 1325
|
||||
},
|
||||
{
|
||||
"type": "diamonds",
|
||||
"amount": 10,
|
||||
"previous_total": 45,
|
||||
"new_total": 55
|
||||
}
|
||||
],
|
||||
"achievements_unlocked": [
|
||||
{
|
||||
"achievement_id": "daily_dialogue_master",
|
||||
"name": "每日對話大師",
|
||||
"description": "完成對話訓練每日任務10次"
|
||||
}
|
||||
],
|
||||
"mission_status": "reward_claimed",
|
||||
"claimed_at": "2024-09-07T15:45:00+08:00"
|
||||
},
|
||||
"message": "Rewards claimed successfully"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 獲取任務歷史
|
||||
```http
|
||||
GET /api/v1/missions/history
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 查詢參數
|
||||
- `date_from`: 開始日期 (`YYYY-MM-DD`)
|
||||
- `date_to`: 結束日期 (`YYYY-MM-DD`)
|
||||
- `mission_type`: 任務類型篩選
|
||||
- `status`: 完成狀態篩選 (`completed`, `expired`, `all`)
|
||||
- `page`: 頁碼 (預設 1)
|
||||
- `limit`: 每頁筆數 (預設 7, 最大 30)
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"mission_history": [
|
||||
{
|
||||
"date": "2024-09-07",
|
||||
"missions_summary": {
|
||||
"total_missions": 4,
|
||||
"completed_missions": 2,
|
||||
"completion_rate": 0.5
|
||||
},
|
||||
"missions": [
|
||||
{
|
||||
"mission_id": "MISSION_VOCAB_RECOGNITION_20240907",
|
||||
"title": "詞彙認識挑戰",
|
||||
"status": "completed",
|
||||
"completed_at": "2024-09-07T10:15:00+08:00",
|
||||
"rewards_claimed": true
|
||||
},
|
||||
{
|
||||
"mission_id": "MISSION_DIALOGUE_TRAINING_20240907",
|
||||
"title": "對話訓練挑戰",
|
||||
"status": "completed",
|
||||
"completed_at": "2024-09-07T15:30:00+08:00",
|
||||
"rewards_claimed": true
|
||||
}
|
||||
],
|
||||
"total_rewards_earned": {
|
||||
"experience_points": 125,
|
||||
"diamonds": 15
|
||||
}
|
||||
},
|
||||
{
|
||||
"date": "2024-09-06",
|
||||
"missions_summary": {
|
||||
"total_missions": 4,
|
||||
"completed_missions": 4,
|
||||
"completion_rate": 1.0
|
||||
},
|
||||
"total_rewards_earned": {
|
||||
"experience_points": 275,
|
||||
"diamonds": 40
|
||||
},
|
||||
"perfect_day_bonus": {
|
||||
"type": "diamonds",
|
||||
"amount": 10,
|
||||
"description": "完美一天獎勵"
|
||||
}
|
||||
}
|
||||
],
|
||||
"statistics": {
|
||||
"total_days": 7,
|
||||
"perfect_days": 1,
|
||||
"average_completion_rate": 0.75,
|
||||
"total_rewards": {
|
||||
"experience_points": 1850,
|
||||
"diamonds": 275
|
||||
},
|
||||
"streak_info": {
|
||||
"current_streak": 3,
|
||||
"longest_streak": 5,
|
||||
"streak_type": "daily_completion"
|
||||
}
|
||||
},
|
||||
"pagination": {
|
||||
"current_page": 1,
|
||||
"total_pages": 1,
|
||||
"total_items": 7
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 每日任務重置 (系統內部調用)
|
||||
```http
|
||||
POST /api/v1/missions/daily-reset
|
||||
Authorization: Bearer <system_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"reset_date": "2024-09-08",
|
||||
"timezone": "Asia/Taipei",
|
||||
"user_filters": {
|
||||
"active_users_only": true,
|
||||
"subscription_status": "all" // all, active, inactive
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"reset_summary": {
|
||||
"reset_date": "2024-09-08",
|
||||
"users_processed": 15430,
|
||||
"missions_generated": 61720,
|
||||
"processing_time_ms": 2500
|
||||
},
|
||||
"mission_generation": {
|
||||
"vocabulary_recognition": 15430,
|
||||
"vocabulary_fluency": 15430,
|
||||
"dialogue_training": 15430,
|
||||
"perfect_dialogue": 15430
|
||||
},
|
||||
"previous_day_stats": {
|
||||
"total_completed_missions": 42890,
|
||||
"completion_rate": 0.69,
|
||||
"perfect_completion_users": 1820
|
||||
}
|
||||
},
|
||||
"message": "Daily missions reset successfully"
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 獲取任務統計
|
||||
```http
|
||||
GET /api/v1/missions/statistics
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 查詢參數
|
||||
- `period`: 統計週期 (`week`, `month`, `quarter`, `year`)
|
||||
- `mission_type`: 特定任務類型 (可選)
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"period": "month",
|
||||
"date_range": {
|
||||
"start_date": "2024-08-01",
|
||||
"end_date": "2024-08-31"
|
||||
},
|
||||
"mission_completion_stats": {
|
||||
"total_missions_available": 124, // 31 days × 4 missions
|
||||
"total_missions_completed": 89,
|
||||
"overall_completion_rate": 0.72,
|
||||
"by_mission_type": {
|
||||
"vocabulary_recognition": {
|
||||
"available": 31,
|
||||
"completed": 28,
|
||||
"completion_rate": 0.90
|
||||
},
|
||||
"vocabulary_fluency": {
|
||||
"available": 31,
|
||||
"completed": 25,
|
||||
"completion_rate": 0.81
|
||||
},
|
||||
"dialogue_training": {
|
||||
"available": 31,
|
||||
"completed": 22,
|
||||
"completion_rate": 0.71
|
||||
},
|
||||
"perfect_dialogue": {
|
||||
"available": 31,
|
||||
"completed": 14,
|
||||
"completion_rate": 0.45
|
||||
}
|
||||
}
|
||||
},
|
||||
"streak_performance": {
|
||||
"longest_streak": 12,
|
||||
"current_streak": 5,
|
||||
"perfect_days": 3, // 完成所有任務的天數
|
||||
"streak_breaks": 2
|
||||
},
|
||||
"rewards_earned": {
|
||||
"total_experience_points": 6725,
|
||||
"total_diamonds": 890,
|
||||
"achievements_unlocked": 5,
|
||||
"perfect_day_bonuses": 3
|
||||
},
|
||||
"performance_trends": {
|
||||
"best_performing_day": "Monday",
|
||||
"completion_rate_trend": "improving", // improving, stable, declining
|
||||
"average_completion_time": 25.4 // minutes per day
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 任務完成條件
|
||||
|
||||
### 任務觸發檢查
|
||||
| 任務類型 | 觸發事件 | 完成條件 | 檢查時機 |
|
||||
|----------|----------|----------|----------|
|
||||
| 詞彙認識挑戰 | 詞彙練習完成 | 三星評價 (≥90分) | 關卡結算時 |
|
||||
| 詞彙熟悉挑戰 | 詞彙練習完成 | 三星評價 (≥90分) | 關卡結算時 |
|
||||
| 對話訓練挑戰 | 對話練習完成 | 完成對話 (任意分數) | 對話結束時 |
|
||||
| 完美對話挑戰 | 對話練習完成 | 滿星評價 (≥90分) | 對話結束時 |
|
||||
|
||||
### 系統檢查流程
|
||||
1. 用戶完成學習活動
|
||||
2. 系統調用 `progress-update` API
|
||||
3. 檢查是否滿足任務完成條件
|
||||
4. 更新任務進度
|
||||
5. 自動解鎖獎勵 (待用戶領取)
|
||||
|
||||
## 🔧 錯誤處理
|
||||
|
||||
### 特殊任務相關錯誤
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 處理建議 |
|
||||
|--------|----------|------|----------|
|
||||
| `MISSION_NOT_FOUND` | 404 | 任務不存在 | 檢查任務ID或刷新任務列表 |
|
||||
| `MISSION_EXPIRED` | 410 | 任務已過期 | 等待新任務重置 |
|
||||
| `MISSION_ALREADY_COMPLETED` | 409 | 任務已完成 | 檢查任務狀態 |
|
||||
| `REWARD_ALREADY_CLAIMED` | 409 | 獎勵已領取 | 檢查獎勵狀態 |
|
||||
| `MISSION_PROGRESS_UPDATE_FAILED` | 500 | 任務進度更新失敗 | 稍後重試 |
|
||||
| `DAILY_RESET_FAILED` | 500 | 每日重置失敗 | 聯繫系統管理員 |
|
||||
| `SUBSCRIPTION_REQUIRED_FOR_MISSION` | 403 | 任務需要訂閱權限 | 引導用戶訂閱 |
|
||||
|
||||
## 🧪 測試範例
|
||||
|
||||
### 獲取今日任務
|
||||
```bash
|
||||
curl -X GET "https://api.dramaling.com/api/v1/missions/daily" \
|
||||
-H "Authorization: Bearer <access_token>"
|
||||
```
|
||||
|
||||
### 領取任務獎勵
|
||||
```bash
|
||||
curl -X POST "https://api.dramaling.com/api/v1/missions/MISSION_DIALOGUE_TRAINING_20240907/claim-reward" \
|
||||
-H "Authorization: Bearer <access_token>"
|
||||
```
|
||||
|
||||
### 獲取任務歷史
|
||||
```bash
|
||||
curl -X GET "https://api.dramaling.com/api/v1/missions/history?date_from=2024-09-01&date_to=2024-09-07" \
|
||||
-H "Authorization: Bearer <access_token>"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**模組負責人**: 遊戲化團隊 + 後端團隊
|
||||
**最後更新**: 2024年9月7日
|
||||
**相關文檔**: [用戶管理API](./user-management.md), [遊戲化系統API](./gamification.md)
|
||||
|
|
@ -0,0 +1,549 @@
|
|||
# 對話練習 API
|
||||
|
||||
## 📋 概述
|
||||
Drama Ling 的核心功能 - 情境對話練習系統,包含場景對話、AI分析、回覆輔助等功能。
|
||||
|
||||
## 🎭 核心功能
|
||||
|
||||
### 對話系統特色
|
||||
- **情境化對話**: 真實場景模擬(餐廳、機場、購物等)
|
||||
- **AI智能回應**: OpenAI GPT-4o-mini 驅動的自然對話
|
||||
- **即時分析**: 語法、語義、流暢度多維度評分
|
||||
- **學習輔助**: 智能提示和回覆建議
|
||||
- **進度追蹤**: 對話目標和完成度監控
|
||||
|
||||
## 📌 API 端點
|
||||
|
||||
### 1. 開始對話練習
|
||||
```http
|
||||
POST /api/v1/dialogues/start
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"scenario_id": "SC_Restaurant_01",
|
||||
"difficulty_override": "A2",
|
||||
"target_vocabulary": ["reservation", "menu", "order"],
|
||||
"practice_mode": "guided" // guided, free_form, challenge
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 201 Created
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"dialogue_id": "DLG_20240907_001",
|
||||
"scenario_id": "SC_Restaurant_01",
|
||||
"session_token": "session_eyJhbGciOiJIUzI1NiIs...",
|
||||
"dialogue_config": {
|
||||
"max_turns": 12,
|
||||
"time_limit": 600, // seconds
|
||||
"difficulty_level": "A2",
|
||||
"practice_mode": "guided"
|
||||
},
|
||||
"scenario_context": {
|
||||
"setting": "高級義大利餐廳內部,晚上8點",
|
||||
"location": "Milano Restaurant, 市中心",
|
||||
"your_role": "顧客",
|
||||
"ai_role": "餐廳服務員",
|
||||
"objective": "成功預約座位並完成點餐",
|
||||
"background_info": "這是一家需要預約的高檔餐廳,服務正式"
|
||||
},
|
||||
"initial_state": {
|
||||
"life_points_cost": 1,
|
||||
"remaining_life_points": 4,
|
||||
"objectives": [
|
||||
"確認預約",
|
||||
"選擇餐桌",
|
||||
"點餐主菜",
|
||||
"完成付款"
|
||||
]
|
||||
},
|
||||
"ai_opening": {
|
||||
"message": "Good evening! Welcome to Milano Restaurant. Do you have a reservation with us tonight?",
|
||||
"audio_url": "https://cdn.dramaling.com/audio/dialogues/DLG_20240907_001_001.mp3",
|
||||
"audio_duration": 4.2,
|
||||
"emotion": "polite_welcoming",
|
||||
"formality_level": "formal",
|
||||
"suggestions": [
|
||||
"Yes, I have a reservation under Chen.",
|
||||
"No, but could we get a table for two?",
|
||||
"I'd like to check if you have any available tables."
|
||||
]
|
||||
}
|
||||
},
|
||||
"message": "Dialogue session started successfully"
|
||||
}
|
||||
```
|
||||
|
||||
#### 場景類型
|
||||
- `SC_Restaurant_*`: 餐廳相關場景
|
||||
- `SC_Airport_*`: 機場/旅行場景
|
||||
- `SC_Shopping_*`: 購物場景
|
||||
- `SC_Business_*`: 商務場景
|
||||
- `SC_Medical_*`: 醫療場景
|
||||
- `SC_Education_*`: 教育場景
|
||||
|
||||
### 2. 發送對話訊息
|
||||
```http
|
||||
POST /api/v1/dialogues/{dialogue_id}/message
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"message": "Yes, I have a reservation under Chen for 8 PM for two people.",
|
||||
"message_type": "text",
|
||||
"audio_data": {
|
||||
"audio_url": "https://cdn.dramaling.com/user_audio/msg001.mp3",
|
||||
"duration": 3.5
|
||||
},
|
||||
"metadata": {
|
||||
"input_method": "voice", // voice, keyboard
|
||||
"confidence_level": 4, // 1-5, user's confidence
|
||||
"time_taken": 15.2 // seconds to compose
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"turn_id": "TURN_002",
|
||||
"dialogue_status": "active",
|
||||
"ai_response": {
|
||||
"message": "Excellent! Mr. Chen, party of two at 8 PM. Your table is ready. Would you prefer a window seat or would you like to sit in our main dining area?",
|
||||
"audio_url": "https://cdn.dramaling.com/audio/dialogues/DLG_20240907_001_002.mp3",
|
||||
"audio_duration": 6.8,
|
||||
"emotion": "friendly_professional",
|
||||
"formality_level": "formal",
|
||||
"context_hints": {
|
||||
"next_expected": "table_preference",
|
||||
"vocabulary_focus": ["window seat", "dining area", "prefer"]
|
||||
}
|
||||
},
|
||||
"user_analysis": {
|
||||
"grammar_score": 90,
|
||||
"semantic_score": 95,
|
||||
"fluency_score": 85,
|
||||
"pronunciation_score": 88,
|
||||
"overall_score": 90,
|
||||
"detailed_feedback": {
|
||||
"strengths": [
|
||||
"Perfect use of formal language",
|
||||
"Appropriate information included",
|
||||
"Natural sentence structure"
|
||||
],
|
||||
"improvements": [
|
||||
"Consider adding 'please' for extra politeness"
|
||||
],
|
||||
"vocabulary_analysis": [
|
||||
{
|
||||
"word": "reservation",
|
||||
"usage": "perfect",
|
||||
"level": "A2",
|
||||
"context_appropriateness": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"dialogue_progress": {
|
||||
"turns_completed": 2,
|
||||
"estimated_turns_remaining": 6,
|
||||
"progress_percentage": 25,
|
||||
"objectives_status": {
|
||||
"confirmed_reservation": true,
|
||||
"selected_table": false,
|
||||
"ordered_food": false,
|
||||
"completed_payment": false
|
||||
},
|
||||
"current_phase": "table_selection"
|
||||
},
|
||||
"suggestions": [
|
||||
"I'd love a window seat if available.",
|
||||
"The main dining area sounds great.",
|
||||
"Could we see both options first?"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 請求回覆輔助
|
||||
```http
|
||||
POST /api/v1/dialogues/{dialogue_id}/assistance
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"assistance_type": "reply_guidance",
|
||||
"context": {
|
||||
"partner_message": "Would you prefer a window seat or would you like to sit in our main dining area?",
|
||||
"scenario_context": "choosing table at restaurant",
|
||||
"user_language_level": "A2",
|
||||
"stuck_reason": "vocabulary", // vocabulary, grammar, context
|
||||
"partial_response": "I would like..." // user's partial input
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"assistance_id": "AST_20240907_001",
|
||||
"assistance_type": "reply_guidance",
|
||||
"guidance": {
|
||||
"intent_analysis": "對方在詢問你的座位偏好,這是餐廳服務的常見情況",
|
||||
"response_strategy": "表達你的偏好並保持禮貌",
|
||||
"key_phrases": [
|
||||
{
|
||||
"phrase": "I'd prefer...",
|
||||
"meaning": "我比較喜歡...",
|
||||
"usage": "表達偏好的禮貌方式"
|
||||
},
|
||||
{
|
||||
"phrase": "window seat",
|
||||
"meaning": "靠窗座位",
|
||||
"usage": "餐廳座位類型"
|
||||
}
|
||||
],
|
||||
"sample_responses": [
|
||||
{
|
||||
"response": "I'd prefer a window seat, please.",
|
||||
"level": "A2",
|
||||
"politeness": "appropriate",
|
||||
"explanation": "簡單直接地表達偏好"
|
||||
},
|
||||
{
|
||||
"response": "A window seat would be lovely if you have one available.",
|
||||
"level": "B1",
|
||||
"politeness": "very_polite",
|
||||
"explanation": "更加禮貌和委婉的表達方式"
|
||||
}
|
||||
]
|
||||
},
|
||||
"usage_cost": {
|
||||
"hints_used": 1,
|
||||
"remaining_hints": 4,
|
||||
"hint_type": "free" // free, premium
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 中翻英翻譯輔助
|
||||
```http
|
||||
POST /api/v1/dialogues/{dialogue_id}/translation
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"chinese_text": "我想要一個靠窗的座位",
|
||||
"context": {
|
||||
"scenario": "restaurant_dining",
|
||||
"formality_level": "formal",
|
||||
"target_level": "A2"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"translation_id": "TRANS_20240907_001",
|
||||
"translations": [
|
||||
{
|
||||
"english_text": "I'd like a window seat.",
|
||||
"level": "A2",
|
||||
"formality": "polite",
|
||||
"naturalness": 5,
|
||||
"explanation": "最直接和常用的表達方式"
|
||||
},
|
||||
{
|
||||
"english_text": "Could I have a window seat, please?",
|
||||
"level": "A2",
|
||||
"formality": "very_polite",
|
||||
"naturalness": 5,
|
||||
"explanation": "更加禮貌的請求方式"
|
||||
},
|
||||
{
|
||||
"english_text": "I would prefer a seat by the window.",
|
||||
"level": "B1",
|
||||
"formality": "formal",
|
||||
"naturalness": 4,
|
||||
"explanation": "較正式的表達方式"
|
||||
}
|
||||
],
|
||||
"grammar_notes": [
|
||||
"使用 'I'd like' 比 'I want' 更禮貌",
|
||||
"'window seat' 是固定搭配,不需要冠詞"
|
||||
],
|
||||
"usage_cost": {
|
||||
"translations_used": 1,
|
||||
"remaining_translations": 9
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 獲取詳細分析
|
||||
```http
|
||||
GET /api/v1/dialogues/{dialogue_id}/analysis
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 查詢參數
|
||||
- `turn_id`: 特定對話輪次ID (可選)
|
||||
- `analysis_type`: `summary` | `detailed` | `vocabulary` (預設 `summary`)
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"dialogue_id": "DLG_20240907_001",
|
||||
"analysis_summary": {
|
||||
"overall_performance": {
|
||||
"grammar_score": 88,
|
||||
"semantic_score": 92,
|
||||
"fluency_score": 85,
|
||||
"pronunciation_score": 87,
|
||||
"total_score": 88,
|
||||
"completion_percentage": 100,
|
||||
"is_perfect_score": false
|
||||
},
|
||||
"interaction_quality": {
|
||||
"appropriateness": 95,
|
||||
"naturalness": 88,
|
||||
"engagement": 90,
|
||||
"cultural_sensitivity": 92
|
||||
}
|
||||
},
|
||||
"turn_by_turn_analysis": [
|
||||
{
|
||||
"turn_number": 1,
|
||||
"user_message": "Yes, I have a reservation under Chen for 8 PM for two people.",
|
||||
"analysis": {
|
||||
"scores": {
|
||||
"grammar": 90,
|
||||
"semantic": 95,
|
||||
"fluency": 85,
|
||||
"pronunciation": 88
|
||||
},
|
||||
"feedback": {
|
||||
"positive_aspects": [
|
||||
"Perfect use of formal register",
|
||||
"All necessary information included",
|
||||
"Natural sentence structure"
|
||||
],
|
||||
"areas_for_improvement": [
|
||||
"Consider using 'please' for extra politeness"
|
||||
],
|
||||
"grammar_analysis": {
|
||||
"errors": [],
|
||||
"complexity_level": "A2",
|
||||
"sentence_patterns": ["declarative_affirmative"]
|
||||
}
|
||||
},
|
||||
"vocabulary_usage": [
|
||||
{
|
||||
"word": "reservation",
|
||||
"correctness": "perfect",
|
||||
"level": "A2",
|
||||
"context_score": 5,
|
||||
"frequency": "high"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
"learning_outcomes": {
|
||||
"vocabulary_progress": {
|
||||
"words_practiced": 12,
|
||||
"words_used_correctly": 11,
|
||||
"new_words_encountered": 4,
|
||||
"words_to_review": ["appetizer", "dessert"]
|
||||
},
|
||||
"skill_development": {
|
||||
"improved_areas": ["formal_requests", "restaurant_vocabulary"],
|
||||
"mastery_achieved": ["basic_reservation_language"],
|
||||
"next_focus": ["ordering_specific_dishes"]
|
||||
},
|
||||
"achievement_progress": {
|
||||
"dialogue_completion": true,
|
||||
"perfect_turns": 3,
|
||||
"vocabulary_milestone": false,
|
||||
"fluency_improvement": true
|
||||
}
|
||||
},
|
||||
"personalized_recommendations": [
|
||||
"Practice pronunciation of 'th' sounds in words like 'thank you'",
|
||||
"Learn more specific food vocabulary for ordering",
|
||||
"Try more complex sentence structures for B1 level"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 結束對話
|
||||
```http
|
||||
POST /api/v1/dialogues/{dialogue_id}/complete
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"completion_type": "natural", // natural, forced, timeout
|
||||
"user_rating": 4, // 1-5, user satisfaction
|
||||
"feedback": "Great practice session!"
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"completion_summary": {
|
||||
"dialogue_id": "DLG_20240907_001",
|
||||
"scenario_name": "餐廳預約與點餐",
|
||||
"duration_seconds": 420,
|
||||
"turns_completed": 8,
|
||||
"all_objectives_met": true,
|
||||
"completion_type": "natural"
|
||||
},
|
||||
"performance_summary": {
|
||||
"final_score": 88,
|
||||
"grade": "B+",
|
||||
"is_perfect_dialogue": false,
|
||||
"best_turn_score": 95,
|
||||
"average_response_time": 12.5,
|
||||
"vocabulary_accuracy": 0.92
|
||||
},
|
||||
"rewards_earned": {
|
||||
"experience_points": 150,
|
||||
"score_points": 88,
|
||||
"diamonds": 10,
|
||||
"achievements_unlocked": [
|
||||
{
|
||||
"achievement_id": "restaurant_master",
|
||||
"name": "餐廳對話專家",
|
||||
"description": "完成餐廳場景對話"
|
||||
}
|
||||
]
|
||||
},
|
||||
"learning_progress": {
|
||||
"vocabulary_advances": [
|
||||
{
|
||||
"word": "reservation",
|
||||
"old_level": "learning",
|
||||
"new_level": "familiar"
|
||||
}
|
||||
],
|
||||
"skill_improvements": [
|
||||
"formal_conversation",
|
||||
"restaurant_etiquette"
|
||||
]
|
||||
},
|
||||
"next_recommendations": {
|
||||
"suggested_scenarios": [
|
||||
"SC_Restaurant_02", // 更高級餐廳場景
|
||||
"SC_Shopping_01" // 購物場景
|
||||
],
|
||||
"focus_areas": [
|
||||
"complex_sentence_structures",
|
||||
"polite_expressions"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7. 暫停/恢復對話
|
||||
```http
|
||||
POST /api/v1/dialogues/{dialogue_id}/pause
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
```http
|
||||
POST /api/v1/dialogues/{dialogue_id}/resume
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
### 8. 獲取對話歷史
|
||||
```http
|
||||
GET /api/v1/dialogues/history
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 查詢參數
|
||||
- `scenario_id`: 特定場景ID (可選)
|
||||
- `date_from`: 開始日期 (可選)
|
||||
- `date_to`: 結束日期 (可選)
|
||||
- `min_score`: 最低分數 (可選)
|
||||
- `page`: 頁碼 (預設 1)
|
||||
- `limit`: 每頁筆數 (預設 20)
|
||||
|
||||
## 🎯 對話評分系統
|
||||
|
||||
### 評分維度
|
||||
| 維度 | 權重 | 評分標準 |
|
||||
|------|------|----------|
|
||||
| **Grammar** | 25% | 語法正確性和複雜度 |
|
||||
| **Semantic** | 30% | 語義適切性和理解度 |
|
||||
| **Fluency** | 25% | 流暢度和自然性 |
|
||||
| **Pronunciation** | 20% | 發音準確度 (語音輸入) |
|
||||
|
||||
### 分數等級
|
||||
- **90-100**: A+ (完美) - 滿星對話
|
||||
- **80-89**: B+ (優秀)
|
||||
- **70-79**: B (良好)
|
||||
- **60-69**: C (及格)
|
||||
- **<60**: D (需改進)
|
||||
|
||||
## 🔧 錯誤處理
|
||||
|
||||
### 對話相關錯誤
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 處理建議 |
|
||||
|--------|----------|------|----------|
|
||||
| `DIALOGUE_NOT_FOUND` | 404 | 對話記錄不存在 | 檢查對話ID或重新開始 |
|
||||
| `SCENARIO_NOT_FOUND` | 404 | 場景不存在 | 檢查場景ID |
|
||||
| `DIALOGUE_EXPIRED` | 410 | 對話已過期 | 重新開始對話 |
|
||||
| `INSUFFICIENT_LIFE_POINTS` | 403 | 命條不足 | 購買命條或等待恢復 |
|
||||
| `AI_SERVICE_UNAVAILABLE` | 503 | AI服務暫時無法使用 | 稍後重試 |
|
||||
| `RESPONSE_GENERATION_FAILED` | 500 | 回應生成失敗 | 重新發送訊息 |
|
||||
| `HINT_LIMIT_EXCEEDED` | 429 | 提示使用次數超限 | 購買更多提示或明日重置 |
|
||||
|
||||
## 🧪 測試範例
|
||||
|
||||
### 開始對話
|
||||
```bash
|
||||
curl -X POST "https://api.dramaling.com/api/v1/dialogues/start" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"scenario_id": "SC_Restaurant_01", "practice_mode": "guided"}'
|
||||
```
|
||||
|
||||
### 發送訊息
|
||||
```bash
|
||||
curl -X POST "https://api.dramaling.com/api/v1/dialogues/DLG_123/message" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"message": "I have a reservation under Smith.", "message_type": "text"}'
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**模組負責人**: AI團隊 + 後端團隊
|
||||
**最後更新**: 2024年9月7日
|
||||
**相關文檔**: [用戶管理API](./user-management.md), [遊戲化系統API](./gamification.md)
|
||||
|
|
@ -0,0 +1,304 @@
|
|||
# API 錯誤處理規範
|
||||
|
||||
## 📋 概述
|
||||
Drama Ling API 的統一錯誤處理機制、錯誤碼定義和錯誤回應格式。
|
||||
|
||||
## 🔧 標準錯誤格式
|
||||
|
||||
### 錯誤回應結構
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": null,
|
||||
"message": "操作失敗的簡短描述",
|
||||
"error": {
|
||||
"code": "SPECIFIC_ERROR_CODE",
|
||||
"message": "詳細的錯誤描述",
|
||||
"details": {
|
||||
"field": "field_name",
|
||||
"reason": "具體錯誤原因",
|
||||
"suggestion": "建議的解決方案"
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"request_id": "req_550e8400-e29b-41d4-a716-446655440000",
|
||||
"api_version": "v1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📚 錯誤碼分類
|
||||
|
||||
### 🔐 認證相關錯誤 (1xxx)
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 建議處理 |
|
||||
|--------|----------|------|----------|
|
||||
| `INVALID_CREDENTIALS` | 401 | 登入憑證錯誤 | 要求用戶重新輸入憑證 |
|
||||
| `TOKEN_EXPIRED` | 401 | Token已過期 | 自動刷新Token或要求重新登入 |
|
||||
| `TOKEN_INVALID` | 401 | Token無效或格式錯誤 | 清除本地Token並要求重新登入 |
|
||||
| `TOKEN_BLACKLISTED` | 401 | Token已被列入黑名單 | 強制用戶重新登入 |
|
||||
| `ACCOUNT_LOCKED` | 423 | 帳號因多次失敗嘗試被鎖定 | 顯示鎖定時間並提供密碼重設 |
|
||||
| `EMAIL_EXISTS` | 409 | 電子郵件已被註冊 | 建議用戶登入或使用其他Email |
|
||||
| `USERNAME_EXISTS` | 409 | 使用者名稱已存在 | 建議其他可用的使用者名稱 |
|
||||
| `VALIDATION_ERROR` | 400 | 輸入資料驗證失敗 | 顯示具體的驗證錯誤訊息 |
|
||||
| `SOCIAL_LOGIN_ERROR` | 400 | 第三方登入驗證失敗 | 要求用戶重試或使用其他登入方式 |
|
||||
|
||||
### 👤 用戶管理相關錯誤 (2xxx)
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 建議處理 |
|
||||
|--------|----------|------|----------|
|
||||
| `USER_NOT_FOUND` | 404 | 用戶不存在 | 檢查用戶ID或要求重新登入 |
|
||||
| `PROFILE_UPDATE_FAILED` | 400 | 個人資料更新失敗 | 檢查輸入資料格式 |
|
||||
| `AVATAR_UPLOAD_FAILED` | 400 | 頭像上傳失敗 | 檢查檔案格式和大小 |
|
||||
| `INVALID_PREFERENCES` | 400 | 偏好設定無效 | 檢查設定值範圍 |
|
||||
| `USERNAME_TAKEN` | 409 | 用戶名已被使用 | 建議其他可用用戶名 |
|
||||
| `AVATAR_TOO_LARGE` | 413 | 頭像檔案過大 | 要求用戶壓縮圖片 |
|
||||
| `ACCOUNT_DELETION_FAILED` | 400 | 帳號刪除失敗 | 檢查密碼或聯繫客服 |
|
||||
|
||||
### 💳 訂閱相關錯誤 (3xxx)
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 建議處理 |
|
||||
|--------|----------|------|----------|
|
||||
| `SUBSCRIPTION_NOT_FOUND` | 404 | 訂閱記錄不存在 | 檢查訂閱狀態 |
|
||||
| `SUBSCRIPTION_EXPIRED` | 403 | 訂閱已過期 | 引導用戶續訂 |
|
||||
| `SUBSCRIPTION_CANCELLED` | 403 | 訂閱已取消 | 提供重新訂閱選項 |
|
||||
| `PAYMENT_VERIFICATION_FAILED` | 400 | 付款驗證失敗 | 要求用戶重新購買 |
|
||||
| `RECEIPT_INVALID` | 400 | 收據無效 | 檢查收據格式或重新購買 |
|
||||
| `SUBSCRIPTION_ALREADY_ACTIVE` | 409 | 訂閱已啟用 | 提示用戶當前訂閱狀態 |
|
||||
| `REFUND_REQUEST_FAILED` | 400 | 退款請求失敗 | 聯繫客服處理 |
|
||||
|
||||
### 💬 對話練習相關錯誤 (4xxx)
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 建議處理 |
|
||||
|--------|----------|------|----------|
|
||||
| `DIALOGUE_NOT_FOUND` | 404 | 對話記錄不存在 | 檢查對話ID |
|
||||
| `SCENARIO_NOT_FOUND` | 404 | 場景不存在 | 檢查場景ID或刷新場景列表 |
|
||||
| `DIALOGUE_ALREADY_COMPLETED` | 409 | 對話已完成 | 開始新的對話 |
|
||||
| `INSUFFICIENT_LIFE_POINTS` | 403 | 命條不足 | 引導用戶購買或等待恢復 |
|
||||
| `AI_SERVICE_UNAVAILABLE` | 503 | AI服務暫時無法使用 | 稍後重試 |
|
||||
| `RESPONSE_GENERATION_FAILED` | 500 | 回應生成失敗 | 重新發送訊息 |
|
||||
| `DIALOGUE_TIMEOUT` | 408 | 對話逾時 | 重新開始對話 |
|
||||
|
||||
### 🎮 遊戲化系統相關錯誤 (5xxx)
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 建議處理 |
|
||||
|--------|----------|------|----------|
|
||||
| `LIFE_POINTS_INSUFFICIENT` | 403 | 命條不足 | 引導購買或等待恢復 |
|
||||
| `PURCHASE_FAILED` | 400 | 道具購買失敗 | 檢查餘額或重試 |
|
||||
| `REWARD_ALREADY_CLAIMED` | 409 | 獎勵已領取 | 提示用戶已領取 |
|
||||
| `ACHIEVEMENT_UNLOCK_FAILED` | 500 | 成就解鎖失敗 | 稍後重試 |
|
||||
| `LEADERBOARD_UPDATE_FAILED` | 500 | 排行榜更新失敗 | 稍後重試 |
|
||||
| `TIME_CHALLENGE_EXPIRED` | 410 | 時光挑戰已過期 | 開始新的挑戰 |
|
||||
|
||||
### 📚 詞彙學習相關錯誤 (6xxx)
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 建議處理 |
|
||||
|--------|----------|------|----------|
|
||||
| `VOCABULARY_NOT_FOUND` | 404 | 詞彙不存在 | 檢查詞彙ID |
|
||||
| `REVIEW_SESSION_EXPIRED` | 410 | 複習階段已過期 | 開始新的複習 |
|
||||
| `SPACED_REPETITION_ERROR` | 500 | 間隔複習計算錯誤 | 稍後重試 |
|
||||
| `VOCABULARY_PROGRESS_SYNC_FAILED` | 500 | 詞彙進度同步失敗 | 稍後重試 |
|
||||
| `MASTERY_UPDATE_FAILED` | 500 | 熟練度更新失敗 | 稍後重試 |
|
||||
|
||||
### 🏆 特殊任務相關錯誤 (7xxx)
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 建議處理 |
|
||||
|--------|----------|------|----------|
|
||||
| `MISSION_NOT_FOUND` | 404 | 任務不存在 | 檢查任務ID |
|
||||
| `MISSION_NOT_AVAILABLE` | 403 | 任務不可用 | 檢查任務條件 |
|
||||
| `MISSION_ALREADY_COMPLETED` | 409 | 任務已完成 | 等待明日任務重置 |
|
||||
| `MISSION_PROGRESS_UPDATE_FAILED` | 500 | 任務進度更新失敗 | 稍後重試 |
|
||||
| `REWARD_CLAIM_FAILED` | 500 | 獎勵領取失敗 | 稍後重試 |
|
||||
| `DAILY_RESET_FAILED` | 500 | 每日重置失敗 | 聯繫客服 |
|
||||
|
||||
### 📈 語言程度相關錯誤 (8xxx)
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 建議處理 |
|
||||
|--------|----------|------|----------|
|
||||
| `LEVEL_ASSESSMENT_FAILED` | 500 | 程度評估失敗 | 稍後重試 |
|
||||
| `ADVANCEMENT_CONDITIONS_NOT_MET` | 403 | 晉階條件未滿足 | 顯示所需條件 |
|
||||
| `LEVEL_UPDATE_FAILED` | 500 | 程度更新失敗 | 稍後重試 |
|
||||
| `PERFECT_DIALOGUE_VALIDATION_FAILED` | 400 | 滿星對話驗證失敗 | 重新檢查對話結果 |
|
||||
|
||||
### 🔄 回覆輔助相關錯誤 (9xxx)
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 建議處理 |
|
||||
|--------|----------|------|----------|
|
||||
| `HINT_LIMIT_EXCEEDED` | 429 | 提示使用次數超限 | 等待重置或購買更多 |
|
||||
| `TRANSLATION_SERVICE_UNAVAILABLE` | 503 | 翻譯服務暫時無法使用 | 稍後重試 |
|
||||
| `SUGGESTION_GENERATION_FAILED` | 500 | 建議生成失敗 | 稍後重試 |
|
||||
| `CONTEXT_ANALYSIS_FAILED` | 500 | 語境分析失敗 | 稍後重試 |
|
||||
|
||||
### ⚙️ 系統相關錯誤 (9xxx)
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 建議處理 |
|
||||
|--------|----------|------|----------|
|
||||
| `INTERNAL_SERVER_ERROR` | 500 | 內部伺服器錯誤 | 稍後重試或聯繫客服 |
|
||||
| `SERVICE_UNAVAILABLE` | 503 | 服務暫時無法使用 | 稍後重試 |
|
||||
| `RATE_LIMIT_EXCEEDED` | 429 | 請求頻率超限 | 降低請求頻率 |
|
||||
| `MAINTENANCE_MODE` | 503 | 系統維護中 | 等待維護完成 |
|
||||
| `DATABASE_CONNECTION_FAILED` | 500 | 資料庫連線失敗 | 稍後重試 |
|
||||
| `EXTERNAL_API_ERROR` | 502 | 外部API錯誤 | 稍後重試 |
|
||||
|
||||
## 📱 錯誤回應範例
|
||||
|
||||
### 驗證錯誤
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": null,
|
||||
"message": "輸入資料驗證失敗",
|
||||
"error": {
|
||||
"code": "VALIDATION_ERROR",
|
||||
"message": "註冊資料格式不正確",
|
||||
"details": {
|
||||
"email": ["Email格式無效"],
|
||||
"password": ["密碼至少需要8位字元"],
|
||||
"username": ["用戶名只能包含字母和數字"]
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"request_id": "req_12345"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 權限錯誤
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": null,
|
||||
"message": "無權限存取此功能",
|
||||
"error": {
|
||||
"code": "SUBSCRIPTION_REQUIRED",
|
||||
"message": "此功能需要訂閱會員",
|
||||
"details": {
|
||||
"required_subscription": "premium",
|
||||
"current_status": "free_user",
|
||||
"upgrade_url": "/subscription/plans"
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"request_id": "req_12345"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 資源不存在錯誤
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": null,
|
||||
"message": "請求的資源不存在",
|
||||
"error": {
|
||||
"code": "DIALOGUE_NOT_FOUND",
|
||||
"message": "指定的對話記錄不存在",
|
||||
"details": {
|
||||
"dialogue_id": "DLG_12345",
|
||||
"possible_reasons": [
|
||||
"對話ID錯誤",
|
||||
"對話已被刪除",
|
||||
"無權限存取此對話"
|
||||
]
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"request_id": "req_12345"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 服務無法使用錯誤
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": null,
|
||||
"message": "服務暫時無法使用",
|
||||
"error": {
|
||||
"code": "AI_SERVICE_UNAVAILABLE",
|
||||
"message": "AI對話服務暫時無法使用",
|
||||
"details": {
|
||||
"service": "openai_gpt",
|
||||
"estimated_recovery": "2024-09-07T12:30:00Z",
|
||||
"alternative_actions": [
|
||||
"稍後重試",
|
||||
"使用離線功能"
|
||||
]
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"request_id": "req_12345"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 錯誤處理最佳實踐
|
||||
|
||||
### 客戶端錯誤處理
|
||||
```javascript
|
||||
// 錯誤處理範例
|
||||
async function handleApiCall(apiFunction) {
|
||||
try {
|
||||
const response = await apiFunction();
|
||||
return response.data;
|
||||
} catch (error) {
|
||||
const errorCode = error.response?.data?.error?.code;
|
||||
|
||||
switch (errorCode) {
|
||||
case 'TOKEN_EXPIRED':
|
||||
// 自動刷新Token
|
||||
await refreshAuthToken();
|
||||
return await apiFunction();
|
||||
|
||||
case 'SUBSCRIPTION_REQUIRED':
|
||||
// 引導用戶升級
|
||||
showSubscriptionModal();
|
||||
break;
|
||||
|
||||
case 'RATE_LIMIT_EXCEEDED':
|
||||
// 等待後重試
|
||||
await delay(5000);
|
||||
return await apiFunction();
|
||||
|
||||
default:
|
||||
// 顯示通用錯誤訊息
|
||||
showErrorMessage(error.response?.data?.error?.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 伺服器錯誤記錄
|
||||
```javascript
|
||||
// 伺服器端錯誤記錄
|
||||
function logError(error, request) {
|
||||
const errorLog = {
|
||||
timestamp: new Date().toISOString(),
|
||||
request_id: request.headers['x-request-id'],
|
||||
user_id: request.user?.id,
|
||||
endpoint: request.path,
|
||||
method: request.method,
|
||||
error_code: error.code,
|
||||
error_message: error.message,
|
||||
stack_trace: error.stack,
|
||||
user_agent: request.headers['user-agent']
|
||||
};
|
||||
|
||||
logger.error('API Error', errorLog);
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 錯誤監控與分析
|
||||
|
||||
### 錯誤指標
|
||||
- **4xx錯誤率**: 客戶端錯誤百分比
|
||||
- **5xx錯誤率**: 伺服器錯誤百分比
|
||||
- **回應時間**: 錯誤回應的速度
|
||||
- **錯誤趨勢**: 錯誤數量隨時間變化
|
||||
|
||||
### 告警規則
|
||||
- 5xx錯誤率 > 1%
|
||||
- Token相關錯誤激增
|
||||
- 外部服務錯誤頻繁
|
||||
- 特定端點錯誤率異常
|
||||
|
||||
---
|
||||
|
||||
**負責人**: 後端開發團隊
|
||||
**最後更新**: 2024年9月7日
|
||||
**相關文檔**: [共通規範](./common.md), [認證API](./authentication.md)
|
||||
|
|
@ -0,0 +1,525 @@
|
|||
# 訂閱系統 API
|
||||
|
||||
## 📋 概述
|
||||
Drama Ling 的訂閱會員系統,支援iOS/Android原生內購,提供對話訓練功能解鎖和進階學習體驗。
|
||||
|
||||
## 💳 訂閱特色
|
||||
|
||||
### 訂閱方案
|
||||
- **月費會員**: NT$600/月 (測試期2折優惠 NT$120)
|
||||
- **支援平台**: iOS App Store、Google Play 原生內購
|
||||
- **訪客訂閱**: 支援透過裝置ID的訪客用戶訂閱
|
||||
- **權限管理**: 基於訂閱狀態的功能權限控制
|
||||
|
||||
### 解鎖功能
|
||||
- ✅ **對話訓練**: 無限制對話練習
|
||||
- ✅ **進階場景**: 專業場景和挑戰模式
|
||||
- ✅ **詳細分析**: 完整學習報告和建議
|
||||
- ✅ **語言評估**: Microsoft API 驅動的專業評估
|
||||
- ✅ **優先支援**: 專屬客服通道
|
||||
|
||||
## 📌 API 端點
|
||||
|
||||
### 1. 獲取訂閱方案
|
||||
```http
|
||||
GET /api/v1/subscriptions/plans
|
||||
Authorization: Bearer <access_token> // 訪客用戶可選
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"available_plans": [
|
||||
{
|
||||
"plan_id": "PLAN_MONTHLY_TWD",
|
||||
"product_id": "dramaling.subscription.monthly",
|
||||
"name": "月費會員",
|
||||
"description": "解鎖對話訓練功能,享受完整學習體驗",
|
||||
"pricing": {
|
||||
"regular_price": {
|
||||
"amount": 600,
|
||||
"currency": "TWD",
|
||||
"display": "NT$600"
|
||||
},
|
||||
"test_period_discount": {
|
||||
"percentage": 80,
|
||||
"discounted_amount": 120,
|
||||
"currency": "TWD",
|
||||
"display": "NT$120",
|
||||
"description": "內部測試期間限時2折優惠",
|
||||
"valid_until": "2025-03-31T23:59:59Z"
|
||||
}
|
||||
},
|
||||
"billing_cycle": "monthly",
|
||||
"trial_period": {
|
||||
"duration_days": 7,
|
||||
"available": true
|
||||
},
|
||||
"features": [
|
||||
{
|
||||
"feature_id": "unlimited_dialogue",
|
||||
"name": "無限制對話練習",
|
||||
"description": "解鎖所有對話訓練場景,無每日次數限制"
|
||||
},
|
||||
{
|
||||
"feature_id": "advanced_scenarios",
|
||||
"name": "進階情境練習",
|
||||
"description": "商務、醫療、學術等專業場景"
|
||||
},
|
||||
{
|
||||
"feature_id": "detailed_analysis",
|
||||
"name": "詳細學習分析",
|
||||
"description": "Microsoft AI 驅動的語言評估和建議"
|
||||
},
|
||||
{
|
||||
"feature_id": "priority_support",
|
||||
"name": "優先客服支援",
|
||||
"description": "專屬客服通道,優先處理問題"
|
||||
}
|
||||
],
|
||||
"platform_config": {
|
||||
"ios": {
|
||||
"product_id": "dramaling.subscription.monthly",
|
||||
"app_store_id": "6451234567"
|
||||
},
|
||||
"android": {
|
||||
"sku": "dramaling_monthly_subscription",
|
||||
"billing_key": "MIIBIjANBgkqhkiG9w0BAQEFAAOC..."
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"current_user_status": {
|
||||
"is_subscribed": false,
|
||||
"user_type": "guest", // guest, registered
|
||||
"device_id": "DEV_iOS_12345",
|
||||
"eligible_for_trial": true,
|
||||
"subscription_triggers": [
|
||||
{
|
||||
"trigger_id": "first_dialogue_attempt",
|
||||
"description": "首次嘗試對話訓練時",
|
||||
"timing": "immediate"
|
||||
},
|
||||
{
|
||||
"trigger_id": "vocabulary_completion",
|
||||
"description": "完成詞彙練習後",
|
||||
"timing": "after_completion"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 驗證內購收據
|
||||
```http
|
||||
POST /api/v1/subscriptions/verify-receipt
|
||||
Authorization: Bearer <access_token> // 訪客用戶可選
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"platform": "ios", // ios, android
|
||||
"receipt_data": "base64_encoded_receipt",
|
||||
"transaction_id": "1000000123456789",
|
||||
"product_id": "dramaling.subscription.monthly",
|
||||
"user_context": {
|
||||
"user_type": "guest", // guest, registered
|
||||
"device_id": "DEV_iOS_12345",
|
||||
"subscription_trigger": "dialogue_access_blocked"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### iOS 收據驗證範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"subscription_created": {
|
||||
"subscription_id": "SUB_20240907_001",
|
||||
"plan_id": "PLAN_MONTHLY_TWD",
|
||||
"user_id": "USR_12345", // null for guest users
|
||||
"device_id": "DEV_iOS_12345",
|
||||
"status": "active"
|
||||
},
|
||||
"receipt_validation": {
|
||||
"is_valid": true,
|
||||
"platform": "ios",
|
||||
"original_transaction_id": "1000000123456789",
|
||||
"purchase_date": "2024-09-07T12:00:00Z",
|
||||
"expires_date": "2024-10-07T12:00:00Z",
|
||||
"product_id": "dramaling.subscription.monthly",
|
||||
"auto_renew_status": true
|
||||
},
|
||||
"subscription_details": {
|
||||
"activated_at": "2024-09-07T12:00:00Z",
|
||||
"expires_at": "2024-10-07T12:00:00Z",
|
||||
"auto_renewal": true,
|
||||
"billing_cycle": "monthly",
|
||||
"is_trial_period": false,
|
||||
"price_paid": {
|
||||
"amount": 120,
|
||||
"currency": "TWD",
|
||||
"was_discounted": true
|
||||
}
|
||||
},
|
||||
"unlocked_features": [
|
||||
"unlimited_dialogue",
|
||||
"advanced_scenarios",
|
||||
"detailed_analysis",
|
||||
"priority_support"
|
||||
]
|
||||
},
|
||||
"message": "Subscription activated successfully"
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 檢查訂閱狀態
|
||||
```http
|
||||
GET /api/v1/subscriptions/status
|
||||
Authorization: Bearer <access_token> // 訪客用戶可選
|
||||
```
|
||||
|
||||
#### 查詢參數
|
||||
- `include_features`: 是否包含功能權限詳情 (`true`/`false`)
|
||||
- `check_renewal`: 是否檢查自動續訂狀態 (`true`/`false`)
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"subscription_status": {
|
||||
"is_active": true,
|
||||
"subscription_id": "SUB_20240907_001",
|
||||
"plan_id": "PLAN_MONTHLY_TWD",
|
||||
"status": "active", // active, expired, cancelled, pending
|
||||
"activated_at": "2024-09-07T12:00:00Z",
|
||||
"expires_at": "2024-10-07T12:00:00Z",
|
||||
"days_remaining": 30,
|
||||
"auto_renewal": true,
|
||||
"billing_cycle": "monthly"
|
||||
},
|
||||
"user_context": {
|
||||
"user_type": "registered", // guest, registered
|
||||
"device_id": "DEV_iOS_12345",
|
||||
"platform": "ios"
|
||||
},
|
||||
"access_permissions": {
|
||||
"dialogue_training": {
|
||||
"has_access": true,
|
||||
"access_type": "unlimited",
|
||||
"restrictions": []
|
||||
},
|
||||
"advanced_features": {
|
||||
"detailed_analysis": true,
|
||||
"progress_reports": true,
|
||||
"priority_support": true,
|
||||
"offline_content": false // 未來功能
|
||||
}
|
||||
},
|
||||
"usage_statistics": {
|
||||
"dialogues_this_month": 45,
|
||||
"analysis_requests": 23,
|
||||
"last_activity": "2024-09-07T11:30:00Z"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 取消訂閱
|
||||
```http
|
||||
POST /api/v1/subscriptions/cancel
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"cancellation_reason": "too_expensive", // too_expensive, not_using, technical_issues, other
|
||||
"feedback": "價格對學生來說太高了",
|
||||
"immediate_cancellation": false // true: 立即取消, false: 期滿後取消
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"cancellation_processed": {
|
||||
"subscription_id": "SUB_20240907_001",
|
||||
"cancellation_effective_date": "2024-10-07T12:00:00Z",
|
||||
"immediate_cancellation": false,
|
||||
"remaining_access_days": 30
|
||||
},
|
||||
"retention_offer": {
|
||||
"offer_id": "RETENTION_STUDENT_50",
|
||||
"discount_percentage": 50,
|
||||
"offer_description": "學生專屬50%折扣",
|
||||
"valid_until": "2024-09-14T12:00:00Z",
|
||||
"reactivation_url": "/subscriptions/reactivate?offer=RETENTION_STUDENT_50"
|
||||
},
|
||||
"feature_impact": {
|
||||
"features_will_be_disabled": [
|
||||
"unlimited_dialogue",
|
||||
"detailed_analysis"
|
||||
],
|
||||
"features_remain_accessible": [
|
||||
"basic_vocabulary",
|
||||
"spaced_repetition"
|
||||
]
|
||||
}
|
||||
},
|
||||
"message": "Subscription will be cancelled at the end of current billing period"
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 重新啟用訂閱
|
||||
```http
|
||||
POST /api/v1/subscriptions/reactivate
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"offer_id": "RETENTION_STUDENT_50", // 可選,使用挽留優惠
|
||||
"payment_method_update": {
|
||||
"platform": "ios",
|
||||
"new_receipt_data": "base64_receipt_data"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 訂閱歷史記錄
|
||||
```http
|
||||
GET /api/v1/subscriptions/history
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 查詢參數
|
||||
- `start_date`: 開始日期
|
||||
- `end_date`: 結束日期
|
||||
- `status`: 訂閱狀態篩選
|
||||
- `page`: 頁碼
|
||||
- `limit`: 每頁筆數
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"subscription_history": [
|
||||
{
|
||||
"subscription_id": "SUB_20240907_001",
|
||||
"plan_name": "月費會員",
|
||||
"status": "active",
|
||||
"activated_at": "2024-09-07T12:00:00Z",
|
||||
"expires_at": "2024-10-07T12:00:00Z",
|
||||
"platform": "ios",
|
||||
"amount_paid": 120,
|
||||
"currency": "TWD",
|
||||
"transaction_id": "1000000123456789"
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"total_subscriptions": 1,
|
||||
"total_amount_paid": 120,
|
||||
"currency": "TWD",
|
||||
"average_subscription_length": 30, // days
|
||||
"most_recent_status": "active"
|
||||
},
|
||||
"pagination": {
|
||||
"current_page": 1,
|
||||
"total_pages": 1,
|
||||
"total_items": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7. 訂閱優惠和促銷
|
||||
```http
|
||||
GET /api/v1/subscriptions/offers
|
||||
Authorization: Bearer <access_token> // 可選
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"active_offers": [
|
||||
{
|
||||
"offer_id": "NEW_USER_TRIAL",
|
||||
"name": "新用戶免費試用",
|
||||
"description": "7天免費試用,隨時可取消",
|
||||
"discount_type": "free_trial",
|
||||
"trial_duration_days": 7,
|
||||
"applicable_plans": ["PLAN_MONTHLY_TWD"],
|
||||
"eligibility": {
|
||||
"new_users_only": true,
|
||||
"device_restriction": false,
|
||||
"geographic_restriction": ["TW"]
|
||||
},
|
||||
"valid_until": "2024-12-31T23:59:59Z"
|
||||
},
|
||||
{
|
||||
"offer_id": "STUDENT_DISCOUNT",
|
||||
"name": "學生專屬折扣",
|
||||
"description": "學生身分驗證後享50%折扣",
|
||||
"discount_type": "percentage",
|
||||
"discount_percentage": 50,
|
||||
"verification_required": "student_email",
|
||||
"valid_until": "2024-12-31T23:59:59Z"
|
||||
}
|
||||
],
|
||||
"user_eligibility": {
|
||||
"eligible_offers": ["NEW_USER_TRIAL"],
|
||||
"ineligible_offers": [
|
||||
{
|
||||
"offer_id": "STUDENT_DISCOUNT",
|
||||
"reason": "verification_required"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔐 權限控制系統
|
||||
|
||||
### 功能權限矩陣
|
||||
| 功能 | 免費用戶 | 訂閱用戶 | 備註 |
|
||||
|------|----------|----------|------|
|
||||
| 基礎詞彙練習 | ✅ | ✅ | 完全開放 |
|
||||
| 間隔複習 | ✅ | ✅ | 完全開放 |
|
||||
| 對話訓練 | ❌ | ✅ | 需訂閱解鎖 |
|
||||
| 進階場景 | ❌ | ✅ | 需訂閱解鎖 |
|
||||
| 詳細分析報告 | ❌ | ✅ | 需訂閱解鎖 |
|
||||
| 語言程度評估 | ❌ | ✅ | 需訂閱解鎖 |
|
||||
|
||||
### 權限檢查 API
|
||||
```http
|
||||
GET /api/v1/subscriptions/check-access/{feature_id}
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"feature_id": "dialogue_training",
|
||||
"has_access": false,
|
||||
"access_reason": "subscription_required",
|
||||
"subscription_info": {
|
||||
"required_plan": "PLAN_MONTHLY_TWD",
|
||||
"upgrade_url": "/subscriptions/plans",
|
||||
"current_status": "expired"
|
||||
},
|
||||
"alternative_actions": [
|
||||
"subscribe_now",
|
||||
"start_free_trial",
|
||||
"use_basic_features"
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 錯誤處理
|
||||
|
||||
### 訂閱相關錯誤
|
||||
| 錯誤碼 | HTTP狀態 | 描述 | 處理建議 |
|
||||
|--------|----------|------|----------|
|
||||
| `SUBSCRIPTION_NOT_FOUND` | 404 | 訂閱記錄不存在 | 檢查訂閱狀態或重新訂閱 |
|
||||
| `SUBSCRIPTION_EXPIRED` | 403 | 訂閱已過期 | 引導用戶續訂 |
|
||||
| `SUBSCRIPTION_CANCELLED` | 403 | 訂閱已取消 | 提供重新訂閱選項 |
|
||||
| `RECEIPT_VERIFICATION_FAILED` | 400 | 收據驗證失敗 | 檢查收據格式或重新購買 |
|
||||
| `RECEIPT_INVALID` | 400 | 收據無效 | 聯繫App Store/Google Play |
|
||||
| `SUBSCRIPTION_ALREADY_ACTIVE` | 409 | 訂閱已啟用 | 提示用戶當前訂閱狀態 |
|
||||
| `PLATFORM_VERIFICATION_ERROR` | 502 | 平台驗證服務錯誤 | 稍後重試 |
|
||||
| `REFUND_PROCESSING_ERROR` | 400 | 退款處理失敗 | 聯繫客服 |
|
||||
|
||||
### 錯誤回應範例
|
||||
```http
|
||||
Response 403 Forbidden
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "SUBSCRIPTION_EXPIRED",
|
||||
"message": "訂閱已過期,無法存取此功能",
|
||||
"details": {
|
||||
"expired_at": "2024-09-01T12:00:00Z",
|
||||
"days_since_expiration": 6,
|
||||
"grace_period_remaining": 1,
|
||||
"renewal_options": [
|
||||
{
|
||||
"plan_id": "PLAN_MONTHLY_TWD",
|
||||
"price": 600,
|
||||
"currency": "TWD"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🧪 測試範例
|
||||
|
||||
### 檢查訂閱狀態
|
||||
```bash
|
||||
curl -X GET "https://api.dramaling.com/api/v1/subscriptions/status" \
|
||||
-H "Authorization: Bearer <access_token>"
|
||||
```
|
||||
|
||||
### 驗證iOS收據
|
||||
```bash
|
||||
curl -X POST "https://api.dramaling.com/api/v1/subscriptions/verify-receipt" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"platform": "ios",
|
||||
"receipt_data": "base64_receipt_here",
|
||||
"transaction_id": "1000000123456789",
|
||||
"product_id": "dramaling.subscription.monthly"
|
||||
}'
|
||||
```
|
||||
|
||||
### 取消訂閱
|
||||
```bash
|
||||
curl -X POST "https://api.dramaling.com/api/v1/subscriptions/cancel" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"cancellation_reason": "not_using",
|
||||
"feedback": "暫時不需要進階功能",
|
||||
"immediate_cancellation": false
|
||||
}'
|
||||
```
|
||||
|
||||
## 📊 收據驗證流程
|
||||
|
||||
### iOS App Store 驗證
|
||||
1. 客戶端完成內購後取得收據
|
||||
2. 將收據傳送到後端 API
|
||||
3. 後端調用 Apple App Store API 驗證
|
||||
4. 驗證成功後啟用訂閱
|
||||
|
||||
### Google Play 驗證
|
||||
1. 客戶端完成內購後取得購買token
|
||||
2. 將token傳送到後端 API
|
||||
3. 後端調用 Google Play Developer API 驗證
|
||||
4. 驗證成功後啟用訂閱
|
||||
|
||||
---
|
||||
|
||||
**模組負責人**: 後端團隊 + 金流團隊
|
||||
**最後更新**: 2024年9月7日
|
||||
**相關文檔**: [用戶管理API](./user-management.md), [錯誤處理](./errors.md)
|
||||
|
|
@ -0,0 +1,496 @@
|
|||
# 用戶管理 API
|
||||
|
||||
## 📋 概述
|
||||
用戶資料管理、個人檔案設定、學習統計等功能的 API 端點。
|
||||
|
||||
## 📌 API 端點
|
||||
|
||||
### 1. 獲取用戶資料
|
||||
```http
|
||||
GET /api/v1/users/profile
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"user_id": "USR_12345",
|
||||
"username": "dramatic_learner",
|
||||
"email": "user@example.com",
|
||||
"avatar_url": "https://cdn.dramaling.com/avatars/12345.jpg",
|
||||
"display_name": "學習者",
|
||||
"level": "B1",
|
||||
"level_progress": {
|
||||
"current_level": "B1",
|
||||
"progress_percentage": 65,
|
||||
"total_perfect_dialogues": 23,
|
||||
"required_perfect_dialogues": 30
|
||||
},
|
||||
"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,
|
||||
"push_notifications": {
|
||||
"daily_reminder": true,
|
||||
"streak_milestone": true,
|
||||
"achievement_unlock": false
|
||||
},
|
||||
"theme": "light",
|
||||
"auto_play_audio": true,
|
||||
"subtitle_display": "always"
|
||||
},
|
||||
"subscription": {
|
||||
"plan": "premium",
|
||||
"status": "active",
|
||||
"started_at": "2024-01-15T08:00:00Z",
|
||||
"expires_at": "2025-01-15T08:00:00Z",
|
||||
"auto_renewal": true,
|
||||
"platform": "ios" // ios, android, web
|
||||
}
|
||||
},
|
||||
"meta": {
|
||||
"timestamp": "2024-09-07T12:00:00Z",
|
||||
"cache_expires_at": "2024-09-07T12:05:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 更新用戶資料
|
||||
```http
|
||||
PUT /api/v1/users/profile
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"username": "new_username",
|
||||
"display_name": "新暱稱",
|
||||
"avatar_url": "https://cdn.dramaling.com/avatars/new_avatar.jpg",
|
||||
"preferences": {
|
||||
"daily_goal_minutes": 45,
|
||||
"notifications_enabled": false,
|
||||
"theme": "dark",
|
||||
"push_notifications": {
|
||||
"daily_reminder": false,
|
||||
"streak_milestone": true
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"updated_fields": [
|
||||
"username",
|
||||
"display_name",
|
||||
"preferences.daily_goal_minutes",
|
||||
"preferences.notifications_enabled",
|
||||
"preferences.theme"
|
||||
],
|
||||
"profile": {
|
||||
"user_id": "USR_12345",
|
||||
"username": "new_username",
|
||||
"display_name": "新暱稱",
|
||||
"preferences": {
|
||||
"daily_goal_minutes": 45,
|
||||
"notifications_enabled": false,
|
||||
"theme": "dark"
|
||||
}
|
||||
}
|
||||
},
|
||||
"message": "Profile updated successfully"
|
||||
}
|
||||
```
|
||||
|
||||
#### 資料驗證規則
|
||||
- **username**: 3-20字元,僅允許字母數字和底線
|
||||
- **display_name**: 1-30字元,支援中英文
|
||||
- **daily_goal_minutes**: 5-180分鐘
|
||||
- **avatar_url**: 有效的URL格式
|
||||
|
||||
### 3. 上傳用戶頭像
|
||||
```http
|
||||
POST /api/v1/users/avatar
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: multipart/form-data
|
||||
|
||||
Form Data:
|
||||
- avatar: [Image File] (JPG, PNG, max 5MB)
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"avatar_url": "https://cdn.dramaling.com/avatars/USR_12345_20240907.jpg",
|
||||
"thumbnail_url": "https://cdn.dramaling.com/avatars/thumbs/USR_12345_20240907.jpg",
|
||||
"upload_timestamp": "2024-09-07T12:00:00Z"
|
||||
},
|
||||
"message": "Avatar uploaded successfully"
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 獲取用戶學習統計
|
||||
```http
|
||||
GET /api/v1/users/stats
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 查詢參數
|
||||
- `period`: 統計週期 (`today`, `week`, `month`, `all`) - 預設 `all`
|
||||
- `include_details`: 是否包含詳細分解 (`true`, `false`) - 預設 `false`
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"summary": {
|
||||
"total_dialogues": 245,
|
||||
"total_study_time": 1280, // minutes
|
||||
"vocabulary_learned": 890,
|
||||
"vocabulary_mastered": 650,
|
||||
"scenarios_completed": 35,
|
||||
"achievements_unlocked": 18,
|
||||
"perfect_dialogues": 89
|
||||
},
|
||||
"streaks": {
|
||||
"current_streak": 15,
|
||||
"longest_streak": 28,
|
||||
"streak_start_date": "2024-08-23T00:00:00Z"
|
||||
},
|
||||
"weekly_progress": {
|
||||
"dialogues_this_week": 12,
|
||||
"minutes_this_week": 180,
|
||||
"vocabulary_this_week": 45,
|
||||
"daily_goal_minutes": 30,
|
||||
"goal_completion_rate": 0.85,
|
||||
"days_active_this_week": 6
|
||||
},
|
||||
"monthly_progress": {
|
||||
"dialogues_this_month": 52,
|
||||
"minutes_this_month": 780,
|
||||
"vocabulary_this_month": 189,
|
||||
"monthly_goal_completion": 0.92
|
||||
},
|
||||
"level_progression": {
|
||||
"current_level": "B1",
|
||||
"level_start_date": "2024-08-01T00:00:00Z",
|
||||
"progress_in_current_level": 0.65,
|
||||
"perfect_dialogues_in_level": 23,
|
||||
"required_for_next_level": 30,
|
||||
"estimated_days_to_next_level": 12
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 獲取詳細學習歷史
|
||||
```http
|
||||
GET /api/v1/users/learning-history
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 查詢參數
|
||||
- `start_date`: 開始日期 (ISO 8601)
|
||||
- `end_date`: 結束日期 (ISO 8601)
|
||||
- `activity_type`: 活動類型 (`dialogue`, `vocabulary`, `mission`, `all`)
|
||||
- `page`: 頁碼 (預設 1)
|
||||
- `limit`: 每頁筆數 (預設 20, 最大 100)
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"activities": [
|
||||
{
|
||||
"activity_id": "ACT_12345",
|
||||
"type": "dialogue",
|
||||
"scenario_id": "restaurant_order",
|
||||
"scenario_name": "餐廳點餐",
|
||||
"score": 85,
|
||||
"is_perfect": false,
|
||||
"duration_minutes": 12,
|
||||
"vocabulary_learned": 5,
|
||||
"completed_at": "2024-09-07T11:30:00Z"
|
||||
},
|
||||
{
|
||||
"activity_id": "ACT_12346",
|
||||
"type": "vocabulary",
|
||||
"practice_type": "spaced_repetition",
|
||||
"words_reviewed": 20,
|
||||
"words_mastered": 15,
|
||||
"accuracy_rate": 0.75,
|
||||
"completed_at": "2024-09-07T10:15:00Z"
|
||||
},
|
||||
{
|
||||
"activity_id": "ACT_12347",
|
||||
"type": "mission",
|
||||
"mission_id": "daily_dialogue_3",
|
||||
"mission_name": "今日對話練習 3次",
|
||||
"progress": "3/3",
|
||||
"reward_diamonds": 50,
|
||||
"completed_at": "2024-09-07T09:45:00Z"
|
||||
}
|
||||
],
|
||||
"pagination": {
|
||||
"current_page": 1,
|
||||
"total_pages": 5,
|
||||
"total_items": 89,
|
||||
"items_per_page": 20
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 獲取成就系統
|
||||
```http
|
||||
GET /api/v1/users/achievements
|
||||
Authorization: Bearer <access_token>
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"unlocked_achievements": [
|
||||
{
|
||||
"achievement_id": "first_dialogue",
|
||||
"name": "初次對話",
|
||||
"description": "完成第一次對話練習",
|
||||
"icon_url": "https://cdn.dramaling.com/achievements/first_dialogue.png",
|
||||
"unlocked_at": "2024-01-15T10:30:00Z",
|
||||
"rarity": "common"
|
||||
},
|
||||
{
|
||||
"achievement_id": "week_streak_1",
|
||||
"name": "週連擊手",
|
||||
"description": "連續學習7天",
|
||||
"icon_url": "https://cdn.dramaling.com/achievements/week_streak.png",
|
||||
"unlocked_at": "2024-01-22T09:15:00Z",
|
||||
"rarity": "uncommon"
|
||||
}
|
||||
],
|
||||
"available_achievements": [
|
||||
{
|
||||
"achievement_id": "perfect_score_10",
|
||||
"name": "完美十連",
|
||||
"description": "獲得10次滿分對話",
|
||||
"icon_url": "https://cdn.dramaling.com/achievements/perfect_10.png",
|
||||
"progress": {
|
||||
"current": 7,
|
||||
"required": 10
|
||||
},
|
||||
"rarity": "rare"
|
||||
}
|
||||
],
|
||||
"achievement_stats": {
|
||||
"total_unlocked": 18,
|
||||
"total_available": 45,
|
||||
"completion_percentage": 0.4,
|
||||
"rarity_breakdown": {
|
||||
"common": 12,
|
||||
"uncommon": 5,
|
||||
"rare": 1,
|
||||
"epic": 0,
|
||||
"legendary": 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7. 更新學習偏好設定
|
||||
```http
|
||||
PATCH /api/v1/users/preferences
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"target_language": "en",
|
||||
"difficulty_preference": "challenging",
|
||||
"daily_goal_minutes": 60,
|
||||
"auto_play_audio": false,
|
||||
"push_notifications": {
|
||||
"daily_reminder": true,
|
||||
"streak_milestone": false,
|
||||
"achievement_unlock": true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"updated_preferences": {
|
||||
"target_language": "en",
|
||||
"difficulty_preference": "challenging",
|
||||
"daily_goal_minutes": 60,
|
||||
"auto_play_audio": false,
|
||||
"push_notifications": {
|
||||
"daily_reminder": true,
|
||||
"streak_milestone": false,
|
||||
"achievement_unlock": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"message": "Preferences updated successfully"
|
||||
}
|
||||
```
|
||||
|
||||
### 8. 刪除用戶帳號
|
||||
```http
|
||||
DELETE /api/v1/users/account
|
||||
Authorization: Bearer <access_token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"password": "current_password",
|
||||
"confirmation": "DELETE_MY_ACCOUNT"
|
||||
}
|
||||
```
|
||||
|
||||
#### 回應範例
|
||||
```http
|
||||
Response 200 OK
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"deletion_scheduled_at": "2024-09-14T12:00:00Z",
|
||||
"grace_period_days": 7,
|
||||
"cancellation_token": "CANCEL_DEL_TOKEN_12345"
|
||||
},
|
||||
"message": "Account deletion scheduled. You have 7 days to cancel."
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 資料結構
|
||||
|
||||
### 用戶偏好設定
|
||||
```typescript
|
||||
interface UserPreferences {
|
||||
target_language: string; // ISO 639-1 語言碼
|
||||
native_language: string; // ISO 639-1 語言碼
|
||||
difficulty_preference: 'easy' | 'adaptive' | 'challenging';
|
||||
daily_goal_minutes: number; // 5-180
|
||||
notifications_enabled: boolean;
|
||||
push_notifications: {
|
||||
daily_reminder: boolean;
|
||||
streak_milestone: boolean;
|
||||
achievement_unlock: boolean;
|
||||
};
|
||||
theme: 'light' | 'dark' | 'auto';
|
||||
auto_play_audio: boolean;
|
||||
subtitle_display: 'always' | 'never' | 'learning_mode';
|
||||
}
|
||||
```
|
||||
|
||||
### 學習統計
|
||||
```typescript
|
||||
interface LearningStats {
|
||||
total_dialogues: number;
|
||||
total_study_time: number; // minutes
|
||||
vocabulary_learned: number;
|
||||
vocabulary_mastered: number;
|
||||
scenarios_completed: number;
|
||||
achievements_unlocked: number;
|
||||
perfect_dialogues: number;
|
||||
current_streak: number;
|
||||
longest_streak: number;
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 錯誤處理
|
||||
|
||||
### 用戶管理相關錯誤
|
||||
| 錯誤碼 | HTTP狀態 | 描述 |
|
||||
|--------|----------|------|
|
||||
| `USER_NOT_FOUND` | 404 | 用戶不存在 |
|
||||
| `PROFILE_UPDATE_FAILED` | 400 | 個人資料更新失敗 |
|
||||
| `AVATAR_UPLOAD_FAILED` | 400 | 頭像上傳失敗 |
|
||||
| `INVALID_PREFERENCES` | 400 | 偏好設定無效 |
|
||||
| `USERNAME_TAKEN` | 409 | 用戶名已被使用 |
|
||||
| `AVATAR_TOO_LARGE` | 413 | 頭像檔案過大 |
|
||||
| `ACCOUNT_DELETION_FAILED` | 400 | 帳號刪除失敗 |
|
||||
|
||||
### 錯誤回應範例
|
||||
```http
|
||||
Response 400 Bad Request
|
||||
{
|
||||
"success": false,
|
||||
"error": {
|
||||
"code": "PROFILE_UPDATE_FAILED",
|
||||
"message": "個人資料更新失敗",
|
||||
"details": {
|
||||
"field": "username",
|
||||
"reason": "Username must be 3-20 characters",
|
||||
"provided_value": "ab"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🛡️ 權限控制
|
||||
|
||||
### 資料存取權限
|
||||
- **個人資料**: 只能存取和修改自己的資料
|
||||
- **學習統計**: 只能查看自己的統計資料
|
||||
- **成就系統**: 只能查看自己的成就進度
|
||||
- **帳號刪除**: 需要密碼驗證
|
||||
|
||||
### 訂閱用戶特殊權限
|
||||
- **詳細統計**: 可存取更詳細的學習分析
|
||||
- **高級偏好**: 可設定進階學習偏好
|
||||
- **資料導出**: 可導出完整學習歷史
|
||||
|
||||
## 🧪 測試範例
|
||||
|
||||
### 取得用戶資料
|
||||
```bash
|
||||
curl -X GET "https://api.dramaling.com/api/v1/users/profile" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "Accept: application/json"
|
||||
```
|
||||
|
||||
### 更新偏好設定
|
||||
```bash
|
||||
curl -X PATCH "https://api.dramaling.com/api/v1/users/preferences" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"daily_goal_minutes": 45, "theme": "dark"}'
|
||||
```
|
||||
|
||||
### 上傳頭像
|
||||
```bash
|
||||
curl -X POST "https://api.dramaling.com/api/v1/users/avatar" \
|
||||
-H "Authorization: Bearer <access_token>" \
|
||||
-F "avatar=@/path/to/avatar.jpg"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**模組負責人**: 後端團隊
|
||||
**最後更新**: 2024年9月7日
|
||||
**相關文檔**: [認證API](./authentication.md), [訂閱系統API](./subscription.md)
|
||||
|
|
@ -0,0 +1,203 @@
|
|||
# API規格文檔完善計劃
|
||||
|
||||
## 概述
|
||||
基於現有API規格文檔分析,共發現38個待完成項目。本計劃將系統性地完成這些項目,確保API規格的完整性和可實施性。
|
||||
|
||||
## 階段規劃
|
||||
|
||||
### 階段一:核心安全與認證機制 (第1-2週)
|
||||
|
||||
#### 1.1 實現JWT認證系統
|
||||
- **設計Token生成、驗證、刷新邏輯**
|
||||
- JWT Token結構定義
|
||||
- Token過期時間策略
|
||||
- Refresh Token輪替機制
|
||||
- Token黑名單機制
|
||||
|
||||
- **建立Role-based權限控制**
|
||||
- 用戶角色定義 (免費用戶、訂閱用戶、管理員)
|
||||
- 權限矩陣設計
|
||||
- API端點權限檢查邏輯
|
||||
|
||||
- **實現API安全原則的5個檢查項目**
|
||||
- [x] 身份驗證:JWT Token認證機制
|
||||
- [x] 授權控制:Role-based權限控制
|
||||
- [x] 資料驗證:嚴格的輸入資料驗證
|
||||
- [x] 速率限制:防止API濫用的速率控制
|
||||
- [x] HTTPS強制:所有API強制使用HTTPS
|
||||
|
||||
#### 1.2 完善iOS/Android內購API
|
||||
- **設計收據驗證端點**
|
||||
```http
|
||||
POST /api/v1/subscriptions/verify-receipt
|
||||
```
|
||||
- iOS App Store收據驗證
|
||||
- Google Play收據驗證
|
||||
- 收據有效性檢查
|
||||
|
||||
- **實現訂閱狀態管理**
|
||||
- 訂閱狀態追蹤
|
||||
- 自動續訂處理
|
||||
- 訂閱取消處理
|
||||
|
||||
- **建立權限檢查機制**
|
||||
- 訂閱用戶功能權限
|
||||
- 對話訓練次數限制
|
||||
- 特殊功能存取控制
|
||||
|
||||
### 階段二:核心功能API完善 (第3-4週)
|
||||
|
||||
#### 2.1 語言程度系統API
|
||||
- **實現13級晉階算法**
|
||||
- A1-C2語言程度定義
|
||||
- 晉級條件設計
|
||||
- 評估分數算法
|
||||
|
||||
- **設計評估標準動態調整**
|
||||
- 個人化難度調整
|
||||
- 學習進度追蹤
|
||||
- 適應性評估機制
|
||||
|
||||
- **完善程度測試相關端點**
|
||||
- 程度測試API
|
||||
- 結果分析API
|
||||
- 學習建議API
|
||||
|
||||
#### 2.2 特殊任務系統API
|
||||
- **設計日常任務管理端點**
|
||||
- 任務分配邏輯
|
||||
- 任務進度追蹤
|
||||
- 任務完成驗證
|
||||
|
||||
- **實現績效追蹤分析**
|
||||
- 學習統計API
|
||||
- 成就系統API
|
||||
- 排行榜API
|
||||
|
||||
- **建立任務完成驗證機制**
|
||||
- 對話完成度檢查
|
||||
- 分數達標驗證
|
||||
- 獎勵發放邏輯
|
||||
|
||||
### 階段三:系統整合與優化 (第5-6週)
|
||||
|
||||
#### 3.1 API文檔標準化
|
||||
- **建立Swagger/OpenAPI規格**
|
||||
- API文檔自動生成
|
||||
- 互動式API測試介面
|
||||
- 客戶端SDK生成
|
||||
|
||||
- **完善所有端點的詳細範例**
|
||||
- 完整的請求範例
|
||||
- 各種回應情境
|
||||
- 錯誤處理範例
|
||||
|
||||
- **設計錯誤處理和驗證邏輯**
|
||||
- 統一錯誤碼系統
|
||||
- 資料驗證規則
|
||||
- 錯誤訊息國際化
|
||||
|
||||
#### 3.2 效能與監控
|
||||
- **實現快取策略**
|
||||
- Redis快取設計
|
||||
- 快取失效策略
|
||||
- 快取預熱機制
|
||||
|
||||
- **建立監控告警系統**
|
||||
- API效能監控
|
||||
- 錯誤率追蹤
|
||||
- 告警規則設定
|
||||
|
||||
- **設計自動化測試套件**
|
||||
- 單元測試
|
||||
- 整合測試
|
||||
- API契約測試
|
||||
|
||||
## 詳細待完成項目清單
|
||||
|
||||
### 🔴 高優先級待完成項目 (6項)
|
||||
1. [ ] 完善所有API端點的詳細規格和範例
|
||||
2. [ ] 設計API的認證和授權機制
|
||||
3. [ ] 實現訂閱系統的付款流程和權限控制
|
||||
4. [ ] 完善語言程度晉階算法的API實現
|
||||
5. [ ] 建立API文檔的自動生成和維護流程
|
||||
6. [ ] 實現API的錯誤處理和驗證邏輯
|
||||
|
||||
### 🟡 中優先級待完成項目 (7項)
|
||||
1. [ ] 設計特殊任務系統的績效追蹤和分析API
|
||||
2. [ ] 實現訂閱系統與對話訓練的權限整合
|
||||
3. [ ] 建立語言程度評估標準的動態調整機制
|
||||
4. [ ] 設計API的快取和效能優化策略
|
||||
5. [ ] 建立API的測試套件和自動化測試
|
||||
6. [ ] 規劃API的版本控制和遷移策略
|
||||
7. [ ] 設計API的監控和分析系統
|
||||
|
||||
### 🟢 低優先級待完成項目 (6項)
|
||||
1. [ ] 研究GraphQL作為REST API的補充
|
||||
2. [ ] 探索Real-time API (WebSocket) 的應用場景
|
||||
3. [ ] 建立多語言程度並行學習的API架構
|
||||
4. [ ] 設計個人化任務推薦系統API
|
||||
5. [ ] 建立API的開發者工具和SDK
|
||||
6. [ ] 設計第三方整合的API授權機制
|
||||
|
||||
### 🆕 新功能整合相關待完成項目 (5項)
|
||||
1. [ ] 訂閱系統與現有付費功能的整合測試
|
||||
2. [ ] 特殊任務系統與遊戲化元素的API整合
|
||||
3. [ ] 語言程度系統與學習路徑規劃的API對接
|
||||
4. [ ] 三大新系統間的數據一致性保證機制
|
||||
5. [ ] 新功能的A/B測試API設計和實現
|
||||
|
||||
### 📋 RESTful設計標準待完成項目 (5項)
|
||||
1. [ ] 資源導向:API端點基於資源設計而非動作
|
||||
2. [ ] HTTP動詞:正確使用GET、POST、PUT、DELETE、PATCH
|
||||
3. [ ] 狀態碼:使用標準HTTP狀態碼表示結果
|
||||
4. [ ] 無狀態:API設計為無狀態,不依賴server端session
|
||||
5. [ ] 版本控制:API版本控制策略
|
||||
|
||||
### 🔒 API安全原則待完成項目 (5項)
|
||||
1. [ ] 身份驗證:JWT Token認證機制
|
||||
2. [ ] 授權控制:Role-based權限控制
|
||||
3. [ ] 資料驗證:嚴格的輸入資料驗證
|
||||
4. [ ] 速率限制:防止API濫用的速率控制
|
||||
5. [ ] HTTPS強制:所有API強制使用HTTPS
|
||||
|
||||
### 📊 效能考量待完成項目 (5項)
|
||||
1. [ ] 回應時間:95%的API請求在200ms內回應
|
||||
2. [ ] 快取策略:靜態內容使用CDN,動態內容使用Redis
|
||||
3. [ ] 資料庫優化:適當的索引和查詢優化
|
||||
4. [ ] 負載平衡:水平擴展API服務器
|
||||
5. [ ] 監控告警:API效能和錯誤率監控
|
||||
|
||||
## 成功指標
|
||||
- [ ] 所有API端點都有完整的文檔和範例
|
||||
- [ ] 安全認證機制完全實現
|
||||
- [ ] 內購系統API完成並測試通過
|
||||
- [ ] 13級語言程度系統API實現
|
||||
- [ ] 特殊任務系統API實現
|
||||
- [ ] API效能達到設定目標 (95%請求<200ms)
|
||||
- [ ] 自動化測試覆蓋率達到80%以上
|
||||
|
||||
## 資源需求
|
||||
- **後端開發工程師**: 1-2人,負責API實現
|
||||
- **前端開發工程師**: 1人,負責API整合測試
|
||||
- **DevOps工程師**: 1人,負責部署和監控設置
|
||||
- **QA工程師**: 1人,負責API測試和驗證
|
||||
|
||||
## 風險評估
|
||||
- **技術風險**: 內購驗證機制複雜度較高
|
||||
- **時間風險**: API數量眾多,可能需要額外時間
|
||||
- **整合風險**: 新舊系統整合可能遇到相容性問題
|
||||
|
||||
## 下一步行動
|
||||
1. 開始階段一的JWT認證系統設計
|
||||
2. 與團隊確認技術選型和實作細節
|
||||
3. 建立開發環境和測試環境
|
||||
4. 開始編寫API規格的詳細實現
|
||||
|
||||
---
|
||||
|
||||
**文件版本**: v1.0
|
||||
**建立日期**: 2024年9月7日
|
||||
**負責人**: 技術團隊
|
||||
**預計完成日期**: 2024年11月中旬
|
||||
**審查週期**: 每週檢討進度
|
||||
|
|
@ -6,8 +6,9 @@
|
|||
|
||||
## 主要用戶角色
|
||||
|
||||
- **訪客用戶 (Guest)**: 未註冊/登入的用戶
|
||||
- **訪客用戶 (Guest)**: 未註冊/登入的用戶,可透過設備ID進行訂閱
|
||||
- **註冊用戶 (Registered)**: 已註冊但使用免費功能的用戶
|
||||
- **訂閱用戶 (Subscribed)**: 已購買月費訂閱(600元/月)的用戶,可使用對話訓練功能
|
||||
- **付費用戶 (Premium)**: 已購買訂閱或付費內容的用戶
|
||||
|
||||
## 核心用戶流程
|
||||
|
|
@ -30,10 +31,13 @@ graph TD
|
|||
K --> L[UI_GuestIntro_Result]
|
||||
L --> M[UI_LanguageLevel_Main]
|
||||
M --> N[UI_LanguageLevel_Result]
|
||||
N --> D
|
||||
N --> O[UI_SubscriptionPlans - 首次訂閱觸發]
|
||||
O --> P{訂閱狀態}
|
||||
P -->|完成訂閱| D
|
||||
P -->|跳過/取消| D
|
||||
|
||||
C -->|忘記密碼| O[UI_PasswordReset_Form]
|
||||
O --> P[UI_PasswordReset_Popup]
|
||||
C -->|忘記密碼| Q[UI_PasswordReset_Form]
|
||||
Q --> R[UI_PasswordReset_Popup]
|
||||
```
|
||||
|
||||
#### 流程說明
|
||||
|
|
@ -60,11 +64,21 @@ graph TD
|
|||
- `UI_LanguageLevel_Main`: 進行程度評估測試
|
||||
- `UI_LanguageLevel_Result`: 顯示測試結果和建議
|
||||
|
||||
5. **首次訂閱觸發**
|
||||
- `UI_SubscriptionPlans`: 完成第一次詞彙認識關卡後自動觸發訂閱頁面
|
||||
- 月費訂閱:600元/月(內部測試期間2折優惠)
|
||||
- 支援訪客透過設備ID直接訂閱
|
||||
|
||||
### 2. 完整學習核心流程 *(更新基於最新規格)*
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[UI_ChallengeLevel_Map] --> A1{命條檢查}
|
||||
A[UI_ChallengeLevel_Map] --> A0{訂閱狀態檢查}
|
||||
A0 -->|未訂閱且選擇對話訓練| A00[UI_SubscriptionPlans]
|
||||
A0 -->|已訂閱或非對話訓練| A1{命條檢查}
|
||||
A00 --> A000{訂閱結果}
|
||||
A000 -->|完成訂閱| A1
|
||||
A000 -->|取消| A
|
||||
A1 -->|命條>1| B{關卡類型}
|
||||
A1 -->|命條=0| A2[命條不足提示]
|
||||
A2 --> A3[購買命條/等待回復]
|
||||
|
|
@ -88,7 +102,7 @@ graph TD
|
|||
C5 -->|是| C9[三顆星通關]
|
||||
C5 -->|否| C3
|
||||
C8 --> A
|
||||
C9 --> C10[詞彙加入複習清單] --> A
|
||||
C9 --> C10[詞彙加入複習清單] --> C11[今日任務檢查+獎勵] --> A
|
||||
|
||||
D --> D1[UI_VocabFluency_MatchImageToWord]
|
||||
D1 --> D2[例句重組練習]
|
||||
|
|
@ -103,7 +117,7 @@ graph TD
|
|||
D6 -->|是| D10[三顆星通關]
|
||||
D6 -->|否| D1
|
||||
D9 --> A
|
||||
D10 --> D11[詞彙加入複習清單] --> A
|
||||
D10 --> D11[詞彙加入複習清單] --> D12[今日任務檢查+獎勵] --> A
|
||||
|
||||
E --> E1[UI_ScenarioDialog_GoalDetail]
|
||||
E1 --> E2[UI_ScenarioDialog_Scene]
|
||||
|
|
@ -120,7 +134,11 @@ graph TD
|
|||
E10 --> E12[UI_DialogCorrection_GrammarRetry_Play]
|
||||
E12 --> E13[UI_DialogCorrection_GrammarPass_Result]
|
||||
E13 --> E6
|
||||
E7 --> E14[詞彙加入複習清單] --> A
|
||||
E7 --> E14[詞彙加入複習清單] --> E15{滿星檢查}
|
||||
E15 -->|滿星| E16[語言程度晉階進度+今日任務]
|
||||
E15 -->|非滿星| E17[今日任務檢查+獎勵]
|
||||
E16 --> A
|
||||
E17 --> A
|
||||
E11 --> A
|
||||
|
||||
F --> F1[UI_VocabReview_Main]
|
||||
|
|
@ -149,24 +167,29 @@ graph TD
|
|||
|
||||
#### 流程說明
|
||||
|
||||
1. **命條系統檢查**
|
||||
1. **訂閱狀態檢查** *(新增)*
|
||||
- 進入對話訓練關卡前檢查訂閱狀態
|
||||
- 未訂閱用戶自動跳轉到訂閱頁面 `UI_SubscriptionPlans`
|
||||
- 訂閱成功後解鎖對話訓練功能
|
||||
|
||||
2. **命條系統檢查**
|
||||
- 每次進入關卡前檢查命條數量(最大5個)
|
||||
- 命條不足時提示購買或等待自動回復(每5小時+1個)
|
||||
- 命條歸零時關卡失敗,獲得時光卷作為安慰獎勵
|
||||
|
||||
2. **詞彙認識關卡流程 (C)**
|
||||
3. **詞彙認識關卡流程 (C)**
|
||||
- `UI_VocabIntro_CardIntro`: 展示詞彙、詞義、例句、示意圖
|
||||
- `UI_VocabIntro_Choice`: 詞彙選擇題測試
|
||||
- 答錯扣除命條,題目移至最後重新測試
|
||||
- 全部正確獲得三顆星通關,詞彙加入複習清單
|
||||
|
||||
3. **詞彙熟悉關卡流程 (D)**
|
||||
4. **詞彙熟悉關卡流程 (D)**
|
||||
- `UI_VocabFluency_MatchImageToWord`: 圖片配對練習
|
||||
- `UI_VocabFluency_SentenceReorder`: 例句重組練習
|
||||
- 多種練習模式強化詞彙記憶
|
||||
- 完成後詞彙進入複習系統
|
||||
|
||||
4. **情境對話關卡流程 (E)**
|
||||
5. **情境對話關卡流程 (E)** *(需訂閱權限)*
|
||||
- `UI_ScenarioDialog_GoalDetail`: 顯示對話任務目標
|
||||
- `UI_ScenarioDialog_Scene`: 主要對話界面
|
||||
- **雙重完成條件**: 劇情任務完成 + 指定詞彙使用
|
||||
|
|
@ -174,18 +197,30 @@ graph TD
|
|||
- **AI評估系統**: 語法、語意、流暢度三維度即時評分
|
||||
- 需要訂正時扣除命條,提供解釋和重試機會
|
||||
|
||||
5. **間隔複習流程 (F)**
|
||||
6. **間隔複習流程 (F)**
|
||||
- `UI_VocabReview_Main`: 基於間隔複習算法選擇詞彙
|
||||
- 使用公式:下次複習時間 = 當日 + (2^複習次數)
|
||||
- `UI_VocabReview_Choice`: 複習測試界面
|
||||
- 答錯重複複習,正確則更新複習次數
|
||||
|
||||
6. **時光挑戰流程 (G)**
|
||||
7. **時光挑戰流程 (G)**
|
||||
- `UI_TimeWarpChallenge_Main`: 300秒限時挑戰
|
||||
- 快速詞彙或對話測試
|
||||
- 時間內完成獲得時光獎勵和經驗值
|
||||
- 挑戰失敗無懲罰,可重複嘗試
|
||||
|
||||
8. **特殊任務系統** *(新增)*
|
||||
- 每日00:00重置所有任務進度
|
||||
- 關卡結算時檢查任務完成狀態
|
||||
- 完成任務獲得經驗值獎勵並顯示結算頁面
|
||||
- 包含詞彙認識、熟悉、對話訓練、滿星對話四類任務
|
||||
|
||||
9. **語言程度晉階系統** *(新增)*
|
||||
- 13級語言程度系統(A1→A2→B1→B2→C1→C2→最高級C2)
|
||||
- 晉階條件:前階與後階累積滿星對話訓練次數
|
||||
- 晉階後解鎖更高難度關卡和內容
|
||||
- 多維度語言能力評估:語意合適度、語法錯誤率、表達流暢度、詞彙分數
|
||||
|
||||
### 3. 詞彙學習系統流程 (Vocabulary Learning System Flow)
|
||||
|
||||
```mermaid
|
||||
|
|
@ -345,6 +380,135 @@ graph TD
|
|||
F --> K[UI_Login_Main]
|
||||
```
|
||||
|
||||
### 8. 語言程度晉階流程 (Language Level Advancement Flow) *(新增)*
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[對話訓練滿星完成] --> B[更新晉階進度]
|
||||
B --> C{當前語言程度}
|
||||
C -->|1級A1| D[檢查後階進度10/10]
|
||||
C -->|2-3級A2| E[檢查前階15+後階10]
|
||||
C -->|4-6級B1| F[檢查前階15+後階10]
|
||||
C -->|7-8級B2| G[檢查前階15+後階10]
|
||||
C -->|9-11級C1| H[檢查前階15+後階10]
|
||||
C -->|12級C2| I[檢查前階15+後階10]
|
||||
C -->|13級最高級| J[已達最高級]
|
||||
|
||||
D --> K{後階完成?}
|
||||
E --> L{前階+後階完成?}
|
||||
F --> L
|
||||
G --> L
|
||||
H --> L
|
||||
I --> L
|
||||
|
||||
K -->|是| M[UI_LanguageLevel_LevelUp]
|
||||
K -->|否| N[更新進度顯示]
|
||||
L -->|是| M
|
||||
L -->|否| N
|
||||
|
||||
M --> O[程度提升+解鎖新關卡]
|
||||
N --> P[返回學習地圖]
|
||||
O --> P
|
||||
J --> P
|
||||
```
|
||||
|
||||
#### 語言程度系統規格
|
||||
|
||||
**13階層架構**:
|
||||
- **1級 (A1)**: 後階10次滿星對話訓練
|
||||
- **2-3級 (A2)**: 前階15次 + 後階10次滿星對話訓練
|
||||
- **4-6級 (B1)**: 前階15次 + 後階10次滿星對話訓練
|
||||
- **7-8級 (B2)**: 前階15次 + 後階10次滿星對話訓練
|
||||
- **9-11級 (C1)**: 前階15次 + 後階10次滿星對話訓練
|
||||
- **12級 (C2)**: 前階15次 + 後階10次滿星對話訓練
|
||||
- **13級 (最高級C2)**: 已達最高語言程度
|
||||
|
||||
**評估指標**:
|
||||
- 語意合適度
|
||||
- 語法錯誤率
|
||||
- 表達流暢度
|
||||
- 詞彙分數
|
||||
|
||||
### 9. 特殊任務系統流程 (Daily Mission System Flow) *(新增)*
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[關卡結算時] --> B[檢查今日任務進度]
|
||||
B --> C{任務類型}
|
||||
C -->|詞彙認識關卡通關| D[更新任務1進度]
|
||||
C -->|詞彙熟悉關卡通關| E[更新任務2進度]
|
||||
C -->|對話訓練關卡通關| F[更新任務3進度]
|
||||
C -->|對話訓練滿星| G[更新任務4進度]
|
||||
|
||||
D --> H[檢查任務完成狀態]
|
||||
E --> H
|
||||
F --> H
|
||||
G --> H
|
||||
|
||||
H --> I{任務完成?}
|
||||
I -->|是| J[UI_Mission_RewardResult]
|
||||
I -->|否| K[返回學習地圖]
|
||||
|
||||
J --> L[獲得經驗值獎勵]
|
||||
L --> K
|
||||
|
||||
M[每日00:00] --> N[重置所有任務進度]
|
||||
N --> O[任務狀態初始化]
|
||||
```
|
||||
|
||||
#### 今日任務規格
|
||||
|
||||
**任務清單**:
|
||||
1. **詞彙認識任務**: 成功闖關1次詞彙認識關卡 → 經驗值獎勵
|
||||
2. **詞彙熟悉任務**: 成功闖關1次詞彙熟悉關卡 → 經驗值獎勵
|
||||
3. **對話訓練任務**: 成功闖關1次對話訓練關卡 → 經驗值獎勵
|
||||
4. **完美對話任務**: 在對話訓練關卡獲得滿星分數1次 → 經驗值獎勵
|
||||
|
||||
**重置機制**: 每日00:00自動重置所有任務進度
|
||||
|
||||
**獎勵時機**: 關卡結束時進行任務完成判定,完成則顯示獎勵結算頁面
|
||||
|
||||
### 10. 訂閱會員系統流程 (Subscription System Flow) *(新增)*
|
||||
|
||||
```mermaid
|
||||
graph TD
|
||||
A[訂閱觸發條件] --> B{觸發情境}
|
||||
B -->|首次完成詞彙認識關卡| C[UI_SubscriptionPlans]
|
||||
B -->|設定中選擇訂閱| C
|
||||
B -->|對話訓練關卡權限檢查| D{會員狀態}
|
||||
|
||||
D -->|未訂閱| C
|
||||
D -->|已訂閱| E[進入對話訓練]
|
||||
|
||||
C --> F[顯示訂閱方案]
|
||||
F --> G[月費600元展示]
|
||||
G --> H[內部測試2折優惠]
|
||||
H --> I{用戶選擇}
|
||||
|
||||
I -->|確認訂閱| J[處理付款]
|
||||
I -->|取消/跳過| K[返回原功能]
|
||||
|
||||
J --> L{付款結果}
|
||||
L -->|成功| M[訂閱狀態更新]
|
||||
L -->|失敗| N[付款失敗提示]
|
||||
|
||||
M --> O[解鎖對話訓練功能]
|
||||
N --> C
|
||||
O --> E
|
||||
```
|
||||
|
||||
#### 訂閱系統規格
|
||||
|
||||
**訂閱方案**:
|
||||
- **月費訂閱**: 600元/月
|
||||
- **測試優惠**: 內部測試期間享2折優惠
|
||||
- **訪客支援**: 支援訪客透過設備ID直接訂閱
|
||||
|
||||
**權限控制**:
|
||||
- 對話訓練關卡需要訂閱權限
|
||||
- 詞彙認識和熟悉關卡免費開放
|
||||
- 其他功能按需設定權限
|
||||
|
||||
## 特殊流程處理
|
||||
|
||||
### 時間門票系統
|
||||
|
|
@ -427,13 +591,16 @@ graph TD
|
|||
## 關鍵轉換點 (Conversion Points)
|
||||
|
||||
1. **註冊轉換**: 訪客 → 註冊用戶
|
||||
2. **首次付費**: 免費用戶 → 付費用戶
|
||||
3. **命條系統轉換**: 體驗命條限制 → 購買命條/觀看廣告 → 持續付費
|
||||
4. **回覆輔助轉換**: 體驗回覆卡關 → 購買提示道具(30鑽石) → 重複使用輔助功能
|
||||
5. **詞彙學習循環**: 完成認識→熟悉→對話→複習的完整學習閉環
|
||||
6. **留存關鍵**: 建立間隔複習習慣,詞彙庫達到50個以上
|
||||
7. **社交激活**: 添加首個好友並進行時光挑戰競爭
|
||||
8. **習慣養成**: 連續7天使用應用,每日完成至少一個關卡
|
||||
2. **首次訂閱轉換** *(新增)*: 完成第一次詞彙認識關卡 → 觸發訂閱頁面 → 月費訂閱(600元/月)
|
||||
3. **對話訓練權限轉換** *(新增)*: 免費用戶嘗試對話訓練 → 訂閱提示 → 付費解鎖功能
|
||||
4. **命條系統轉換**: 體驗命條限制 → 購買命條/觀看廣告 → 持續付費
|
||||
5. **回覆輔助轉換**: 體驗回覆卡關 → 購買提示道具(30鑽石) → 重複使用輔助功能
|
||||
6. **特殊任務激勵** *(新增)*: 日常學習習慣 → 每日任務完成 → 經驗值獎勵 → 持續參與
|
||||
7. **語言程度晉階** *(新增)*: 達成滿星對話訓練 → 程度提升 → 解鎖新內容 → 長期留存
|
||||
8. **詞彙學習循環**: 完成認識→熟悉→對話→複習的完整學習閉環
|
||||
9. **留存關鍵**: 建立間隔複習習慣,詞彙庫達到50個以上
|
||||
10. **社交激活**: 添加首個好友並進行時光挑戰競爭
|
||||
11. **習慣養成**: 連續7天使用應用,每日完成至少一個關卡
|
||||
|
||||
## 效能考量
|
||||
|
||||
|
|
|
|||