15 KiB
15 KiB
DramaLing API 規格文檔
1. API 概述
1.1 基本資訊
- Base URL:
- 開發:
http://localhost:3000/api - 生產:
https://api.dramaling.com
- 開發:
- 版本: v1
- 協議: HTTPS
- 格式: JSON
- 認證: Bearer Token (JWT)
1.2 通用規範
請求標頭
Content-Type: application/json
Authorization: Bearer <token>
Accept-Language: zh-TW
X-Request-ID: <uuid>
響應格式
interface SuccessResponse<T> {
success: true;
data: T;
meta?: {
page?: number;
limit?: number;
total?: number;
hasMore?: boolean;
};
}
interface ErrorResponse {
success: false;
error: {
code: string;
message: string;
details?: any;
};
timestamp: string;
}
HTTP 狀態碼
200 OK- 請求成功201 Created- 資源創建成功204 No Content- 刪除成功400 Bad Request- 請求參數錯誤401 Unauthorized- 未認證403 Forbidden- 無權限404 Not Found- 資源不存在409 Conflict- 資源衝突422 Unprocessable Entity- 驗證失敗429 Too Many Requests- 請求過多500 Internal Server Error- 伺服器錯誤
2. 認證 API
2.1 註冊
POST /api/auth/register
請求
{
"email": "user@example.com",
"password": "SecurePass123!",
"username": "johndoe"
}
響應 (201)
{
"success": true,
"data": {
"user": {
"id": "uuid",
"email": "user@example.com",
"username": "johndoe",
"emailVerified": false,
"createdAt": "2024-03-15T10:00:00Z"
},
"tokens": {
"accessToken": "eyJ...",
"refreshToken": "eyJ...",
"expiresIn": 900
}
}
}
錯誤響應 (409)
{
"success": false,
"error": {
"code": "EMAIL_EXISTS",
"message": "Email already registered"
}
}
2.2 登入
POST /api/auth/login
請求
{
"email": "user@example.com",
"password": "SecurePass123!",
"rememberMe": true
}
響應 (200)
{
"success": true,
"data": {
"user": {
"id": "uuid",
"email": "user@example.com",
"username": "johndoe",
"avatarUrl": "https://...",
"lastLoginAt": "2024-03-15T10:00:00Z"
},
"tokens": {
"accessToken": "eyJ...",
"refreshToken": "eyJ...",
"expiresIn": 2592000
}
}
}
2.3 Google OAuth
POST /api/auth/google
請求
{
"idToken": "google_id_token"
}
響應 (200)
{
"success": true,
"data": {
"user": {
"id": "uuid",
"email": "user@gmail.com",
"username": "user",
"provider": "google",
"avatarUrl": "https://..."
},
"tokens": {
"accessToken": "eyJ...",
"refreshToken": "eyJ..."
},
"isNewUser": false
}
}
2.4 重新整理 Token
POST /api/auth/refresh
請求
{
"refreshToken": "eyJ..."
}
響應 (200)
{
"success": true,
"data": {
"accessToken": "eyJ...",
"refreshToken": "eyJ...",
"expiresIn": 900
}
}
2.5 登出
POST /api/auth/logout
請求
{
"refreshToken": "eyJ..."
}
響應 (200)
{
"success": true,
"data": {
"message": "Logged out successfully"
}
}
2.6 忘記密碼
POST /api/auth/forgot-password
請求
{
"email": "user@example.com"
}
響應 (200)
{
"success": true,
"data": {
"message": "Password reset email sent"
}
}
2.7 重設密碼
POST /api/auth/reset-password
請求
{
"token": "reset_token",
"newPassword": "NewSecurePass123!"
}
響應 (200)
{
"success": true,
"data": {
"message": "Password reset successfully"
}
}
3. 用戶 API
3.1 取得個人資料
GET /api/users/me
響應 (200)
{
"success": true,
"data": {
"id": "uuid",
"email": "user@example.com",
"username": "johndoe",
"avatarUrl": "https://...",
"emailVerified": true,
"createdAt": "2024-03-01T00:00:00Z",
"stats": {
"totalFlashcards": 150,
"totalDecks": 5,
"studyStreak": 7,
"level": 3,
"experience": 1250
},
"preferences": {
"dailyGoal": 20,
"reminderTime": "09:00",
"reminderEnabled": true,
"theme": "light",
"language": "zh-TW"
}
}
}
3.2 更新個人資料
PATCH /api/users/me
請求
{
"username": "newusername",
"avatarUrl": "https://..."
}
響應 (200)
{
"success": true,
"data": {
"id": "uuid",
"username": "newusername",
"avatarUrl": "https://...",
"updatedAt": "2024-03-15T10:00:00Z"
}
}
3.3 更新偏好設定
PUT /api/users/me/preferences
請求
{
"dailyGoal": 30,
"reminderTime": "20:00",
"reminderEnabled": true,
"theme": "dark",
"language": "zh-TW",
"soundEnabled": true,
"autoPlayAudio": false
}
4. 卡組 API
4.1 取得卡組列表
GET /api/decks
查詢參數
page(number): 頁數,預設 1limit(number): 每頁數量,預設 20sort(string): 排序方式created_at|updated_at|nameorder(string): 排序順序asc|desc
響應 (200)
{
"success": true,
"data": [
{
"id": "uuid",
"name": "Business English",
"description": "Common business vocabulary",
"coverImage": "https://...",
"flashcardCount": 45,
"isPublic": false,
"tags": ["business", "professional"],
"createdAt": "2024-03-01T00:00:00Z",
"updatedAt": "2024-03-15T00:00:00Z"
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 5,
"hasMore": false
}
}
4.2 取得單一卡組
GET /api/decks/{deckId}
響應 (200)
{
"success": true,
"data": {
"id": "uuid",
"name": "Business English",
"description": "Common business vocabulary",
"coverImage": "https://...",
"flashcardCount": 45,
"isPublic": false,
"tags": ["business", "professional"],
"flashcards": [
{
"id": "uuid",
"word": "negotiate",
"translation": "協商",
"difficulty": "intermediate"
}
],
"createdAt": "2024-03-01T00:00:00Z"
}
}
4.3 創建卡組
POST /api/decks
請求
{
"name": "TOEFL Vocabulary",
"description": "Essential TOEFL words",
"coverImage": "https://...",
"isPublic": false,
"tags": ["toefl", "exam"]
}
響應 (201)
{
"success": true,
"data": {
"id": "uuid",
"name": "TOEFL Vocabulary",
"description": "Essential TOEFL words",
"flashcardCount": 0,
"createdAt": "2024-03-15T10:00:00Z"
}
}
4.4 更新卡組
PATCH /api/decks/{deckId}
請求
{
"name": "Updated Name",
"description": "Updated description"
}
4.5 刪除卡組
DELETE /api/decks/{deckId}
響應 (204)
無內容
5. 詞卡 API
5.1 取得詞卡列表
GET /api/flashcards
查詢參數
deckId(string): 卡組 IDsearch(string): 搜尋關鍵字tags(string[]): 標籤篩選difficulty(string): 難度篩選status(string): 學習狀態new|learning|review|masteredpage(number): 頁數limit(number): 每頁數量
響應 (200)
{
"success": true,
"data": [
{
"id": "uuid",
"deckId": "uuid",
"word": "negotiate",
"translation": "協商",
"definition": "To discuss something with someone in order to reach an agreement",
"partOfSpeech": "verb",
"pronunciation": "/nɪˈɡoʊʃieɪt/",
"exampleSentence": "We need to negotiate a better deal.",
"exampleTranslation": "我們需要協商一個更好的交易。",
"difficulty": "intermediate",
"tags": ["business", "communication"],
"learningStatus": {
"status": "learning",
"nextReviewDate": "2024-03-16T00:00:00Z",
"accuracy": 75
}
}
],
"meta": {
"page": 1,
"limit": 20,
"total": 150,
"hasMore": true
}
}
5.2 取得單一詞卡
GET /api/flashcards/{flashcardId}
5.3 創建詞卡
POST /api/flashcards
請求
{
"deckId": "uuid",
"word": "negotiate",
"translation": "協商",
"definition": "To discuss something with someone in order to reach an agreement",
"partOfSpeech": "verb",
"pronunciation": "/nɪˈɡoʊʃieɪt/",
"exampleSentence": "We need to negotiate a better deal.",
"exampleTranslation": "我們需要協商一個更好的交易。",
"difficulty": "intermediate",
"memoryTip": "Think of 'go' + 'she' + 'ate' = negotiate",
"tags": ["business", "communication"]
}
5.4 更新詞卡
PATCH /api/flashcards/{flashcardId}
5.5 刪除詞卡
DELETE /api/flashcards/{flashcardId}
5.6 批量操作
POST /api/flashcards/bulk
請求
{
"flashcardIds": ["uuid1", "uuid2", "uuid3"],
"operation": "move",
"targetDeckId": "uuid"
}
6. AI 生成 API
6.1 生成詞卡
POST /api/ai/generate
請求
{
"text": "The quick brown fox jumps over the lazy dog...",
"theme": "daily_conversation",
"count": 10,
"difficulty": "intermediate",
"includeExamples": true,
"targetDeckId": "uuid"
}
響應 (200)
{
"success": true,
"data": {
"requestId": "uuid",
"status": "processing",
"estimatedTime": 5000,
"flashcards": [
{
"word": "negotiate",
"translation": "協商",
"definition": "To discuss...",
"pronunciation": "/nɪˈɡoʊʃieɪt/",
"example": "We need to negotiate...",
"difficulty": "intermediate"
}
],
"metadata": {
"tokensUsed": 1500,
"processingTime": 3200,
"model": "gemini-pro"
}
}
}
6.2 取得生成狀態
GET /api/ai/generate/{requestId}
響應 (200)
{
"success": true,
"data": {
"requestId": "uuid",
"status": "completed",
"flashcards": [...],
"completedAt": "2024-03-15T10:00:05Z"
}
}
6.3 取得用戶配額
GET /api/ai/quota
響應 (200)
{
"success": true,
"data": {
"daily": {
"used": 25,
"limit": 50,
"resetsAt": "2024-03-16T00:00:00Z"
},
"monthly": {
"used": 500,
"limit": 1500
},
"isPremium": false
}
}
7. 學習 API
7.1 開始學習會話
POST /api/learning/sessions
請求
{
"deckId": "uuid",
"mode": "flashcard",
"cardLimit": 20
}
響應 (200)
{
"success": true,
"data": {
"sessionId": "uuid",
"cards": [...],
"totalCards": 20,
"newCards": 5,
"reviewCards": 15
}
}
7.2 提交學習結果
POST /api/learning/reviews
請求
{
"sessionId": "uuid",
"flashcardId": "uuid",
"rating": 4,
"timeSpent": 15,
"isCorrect": true
}
響應 (200)
{
"success": true,
"data": {
"nextReviewDate": "2024-03-18T00:00:00Z",
"interval": 3,
"easeFactor": 2.5,
"repetitions": 2
}
}
7.3 取得待複習詞卡
GET /api/learning/due
查詢參數
deckId(string): 特定卡組limit(number): 數量限制
響應 (200)
{
"success": true,
"data": {
"dueCards": [...],
"newCards": [...],
"totalDue": 25,
"totalNew": 10
}
}
7.4 結束學習會話
POST /api/learning/sessions/{sessionId}/complete
響應 (200)
{
"success": true,
"data": {
"summary": {
"cardsStudied": 20,
"correctAnswers": 18,
"accuracy": 90,
"timeSpent": 600,
"experience": 100,
"streakDays": 8
}
}
}
8. 統計 API
8.1 取得學習統計
GET /api/stats
查詢參數
period(string):daily|weekly|monthly|yearlystartDate(string): YYYY-MM-DDendDate(string): YYYY-MM-DD
響應 (200)
{
"success": true,
"data": {
"overview": {
"totalCards": 500,
"masteredCards": 200,
"learningCards": 250,
"newCards": 50,
"studyStreak": 15,
"totalStudyTime": 12000
},
"daily": [
{
"date": "2024-03-15",
"cardsStudied": 30,
"newCards": 5,
"reviewCards": 25,
"accuracy": 85,
"studyTime": 45
}
],
"heatmap": {
"2024-03-15": 3,
"2024-03-14": 2,
"2024-03-13": 4
}
}
}
8.2 取得成就列表
GET /api/stats/achievements
響應 (200)
{
"success": true,
"data": {
"unlocked": [
{
"id": "first_card",
"name": "First Step",
"description": "Create your first flashcard",
"icon": "🎯",
"unlockedAt": "2024-03-01T00:00:00Z",
"points": 10
}
],
"inProgress": [
{
"id": "week_streak",
"name": "Week Warrior",
"description": "Study for 7 days in a row",
"progress": 85,
"target": 7,
"current": 6
}
],
"totalPoints": 250
}
}
9. 錯誤處理
9.1 錯誤碼列表
| 錯誤碼 | HTTP 狀態 | 描述 |
|---|---|---|
UNAUTHORIZED |
401 | 未認證 |
FORBIDDEN |
403 | 無權限 |
NOT_FOUND |
404 | 資源不存在 |
VALIDATION_ERROR |
422 | 驗證失敗 |
EMAIL_EXISTS |
409 | Email 已存在 |
USERNAME_EXISTS |
409 | 用戶名已存在 |
INVALID_CREDENTIALS |
401 | 認證資訊錯誤 |
TOKEN_EXPIRED |
401 | Token 過期 |
RATE_LIMIT_EXCEEDED |
429 | 請求過多 |
QUOTA_EXCEEDED |
402 | 配額超限 |
AI_SERVICE_ERROR |
503 | AI 服務錯誤 |
DATABASE_ERROR |
500 | 資料庫錯誤 |
9.2 錯誤響應範例
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"email": "Invalid email format",
"password": "Password must be at least 8 characters"
}
},
"timestamp": "2024-03-15T10:00:00Z"
}
10. Rate Limiting
10.1 限制規則
- 一般 API: 100 requests/minute
- AI 生成: 10 requests/minute
- 認證相關: 5 requests/minute
10.2 響應標頭
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1710496800
10.3 超限響應 (429)
{
"success": false,
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Too many requests",
"retryAfter": 60
}
}
11. Webhook
11.1 事件類型
user.created- 新用戶註冊flashcard.generated- AI 生成完成achievement.unlocked- 成就解鎖subscription.updated- 訂閱更新
11.2 Webhook 格式
{
"id": "evt_uuid",
"type": "flashcard.generated",
"created": "2024-03-15T10:00:00Z",
"data": {
"requestId": "uuid",
"userId": "uuid",
"flashcardCount": 10
}
}
11.3 簽名驗證
const signature = req.headers['x-webhook-signature'];
const payload = JSON.stringify(req.body);
const expected = crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(payload)
.digest('hex');
if (signature !== expected) {
throw new Error('Invalid signature');
}