dramaling-vocab-learning/docs/02_design/api-specification.md

801 lines
20 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 互動式單字查詢 API 規格書
## 1. API 概覽
### 1.1 基本資訊
- **Base URL**: `https://api.dramaling.com/v1`
- **認證方式**: Bearer Token (JWT)
- **請求格式**: JSON
- **響應格式**: JSON
- **字元編碼**: UTF-8
### 1.2 通用響應格式
#### 成功響應
```json
{
"success": true,
"data": { /* 實際資料 */ },
"message": "操作成功描述",
"timestamp": "2025-09-17T09:48:00Z",
"requestId": "uuid"
}
```
#### 錯誤響應
```json
{
"success": false,
"error": {
"code": "ERROR_CODE",
"message": "錯誤描述",
"details": "詳細錯誤資訊",
"field": "相關欄位" // 如適用
},
"timestamp": "2025-09-17T09:48:00Z",
"requestId": "uuid"
}
```
### 1.3 HTTP 狀態碼
- `200 OK`: 請求成功
- `201 Created`: 資源創建成功
- `400 Bad Request`: 請求參數錯誤
- `401 Unauthorized`: 未認證或認證失效
- `403 Forbidden`: 無權限訪問
- `404 Not Found`: 資源不存在
- `429 Too Many Requests`: 超過使用限制
- `500 Internal Server Error`: 伺服器內部錯誤
## 2. 認證 API
### 2.1 獲取 Access Token
```http
POST /auth/login
Content-Type: application/json
{
"email": "user@example.com",
"password": "user_password"
}
```
**響應**:
```json
{
"success": true,
"data": {
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"refreshToken": "eyJhbGciOiJIUzI1NiIs...",
"expiresIn": 900,
"user": {
"id": "uuid",
"email": "user@example.com",
"name": "User Name",
"subscription": "free" | "premium",
"createdAt": "2025-09-17T09:48:00Z"
}
}
}
```
## 3. 句子分析 API
### 3.1 分析句子
#### 請求
```http
POST /ai/analyze-sentence
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"inputText": "He brought this thing up during our meeting and no one agreed.",
"options": {
"forceRefresh": false,
"includeExamples": true,
"includeAudio": true,
"difficultyLevel": "auto", // auto, A1, A2, B1, B2, C1, C2
"analysisMode": "full" // full: 完整分析並標記高價值詞彙
}
}
```
#### 響應
```json
{
"success": true,
"data": {
"analysisId": "uuid",
"inputText": "He brought this thing up during our meeting and no one agreed.",
"textHash": "sha256_hash",
"grammarCorrection": {
"hasErrors": false,
"originalText": "He brought this thing up during our meeting and no one agreed.",
"correctedText": null,
"corrections": [],
"confidenceScore": 0.98
},
"sentenceMeaning": {
"translation": "他在我們的會議中提出了這件事,但沒有人同意。",
"explanation": "這句話表達了在會議中有人提出某個議題或想法,但得不到其他與會者的認同。",
"context": "正式會議場合",
"tone": "中性陳述"
},
"finalAnalysisText": "He brought this thing up during our meeting and no one agreed.", // 用於後續分析的文本(修正後)
"wordAnalysis": {
"he": {
"word": "he",
"lemma": "he",
"translation": "他",
"definition": "Used to refer to a male person or animal previously mentioned",
"partOfSpeech": "pronoun",
"pronunciation": {
"ipa": "/hiː/",
"us": "/hiː/",
"uk": "/hiː/"
},
"synonyms": ["him", "that man"],
"antonyms": [],
"isPhrase": false,
"phraseInfo": null,
"examples": {
"original": {
"sentence": "He brought this thing up during our meeting",
"translation": "他在我們的會議中提出了這件事",
"highlightWord": "He"
},
"generated": {
"sentence": "He went to the store yesterday",
"translation": "他昨天去了商店",
"imageUrl": "/images/examples/he_store.png",
"audioUrl": "/audio/examples/he_store.mp3"
}
},
"difficultyLevel": "A1",
"frequency": "very_high",
"tags": ["basic", "pronoun"]
},
"brought": {
"word": "brought",
"lemma": "bring",
"translation": "帶來、提出",
"definition": "Past tense of bring; to take or carry something to a place",
"partOfSpeech": "verb",
"pronunciation": {
"ipa": "/brɔːt/",
"us": "/brɔːt/",
"uk": "/brɔːt/"
},
"synonyms": ["carried", "took", "delivered"],
"antonyms": ["removed", "took away"],
"isPhrase": true,
"isHighValue": true, // 高學習價值標記
"learningPriority": "high", // high, medium, low
"phraseInfo": {
"phrase": "bring up",
"meaning": "提出(話題)、養育",
"type": "phrasal_verb",
"warning": "在這個句子中,\"brought up\" 是一個片語動詞,意思是\"提出話題\",而不是單純的\"帶來\"",
"colorCode": "#F59E0B", // 片語顏色代碼
"examples": [
{
"sentence": "She brought up an important point",
"translation": "她提出了一個重要觀點"
}
]
},
"examples": {
"original": {
"sentence": "He brought this thing up during our meeting",
"translation": "他在我們的會議中提出了這件事",
"highlightWord": "brought"
},
"generated": {
"sentence": "She brought up the topic in yesterday's discussion",
"translation": "她在昨天的討論中提出了這個話題",
"imageUrl": "/images/examples/bring_up_meeting.png",
"audioUrl": "/audio/examples/bring_up_meeting.mp3"
}
},
"difficultyLevel": "B1",
"frequency": "high",
"tags": ["phrasal_verb", "meeting", "communication"]
}
// ... 其他單字
},
"highValueWords": ["brought", "up", "meeting"], // 高學習價值詞彙列表
"phrases": [
{
"phrase": "bring up",
"words": ["brought", "up"],
"meaning": "提出(話題)、養育",
"type": "phrasal_verb",
"definition": "To mention or introduce a topic in conversation; to raise a child",
"colorCode": "#F59E0B",
"isHighValue": true,
"examples": [
{
"sentence": "Don't bring up that topic again",
"translation": "不要再提起那個話題了"
}
]
}
],
"metadata": {
"analysisTime": 2.5,
"wordsCount": 12,
"phrasesCount": 1,
"highValueWordsCount": 3, // 高價值詞彙數量
"averageDifficulty": "B1",
"detectedLanguage": "en",
"confidence": 0.98
},
"usageStatistics": {
"remainingAnalyses": 4,
"totalUsedToday": 1,
"dailyLimit": 5,
"resetTime": "2025-09-17T12:48:00Z",
"subscription": "free"
},
"cache": {
"cached": false,
"cacheKey": "sha256_hash",
"expiresAt": "2025-09-18T09:48:00Z",
"ttl": 86400
}
},
"message": "句子分析完成"
}
```
### 3.2 單字點擊查詢
#### 請求
```http
POST /ai/query-word
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"word": "thing",
"sentence": "He brought this thing up during our meeting and no one agreed.",
"analysisId": "uuid", // 來自預分析結果
"context": {
"position": 3, // 單字在句子中的位置
"surroundingWords": ["this", "thing", "up"] // 周圍單字上下文
}
}
```
#### 響應
```json
{
"success": true,
"data": {
"word": "thing",
"isHighValue": false, // 非高價值詞彙
"wasPreAnalyzed": false, // 未在預分析中包含
"costIncurred": 1, // 扣除1次使用次數
"analysis": {
"word": "thing",
"translation": "事情、東西",
"definition": "An object, fact, or situation",
"partOfSpeech": "noun",
"pronunciation": {
"ipa": "/θɪŋ/",
"us": "/θɪŋ/",
"uk": "/θɪŋ/"
},
"synonyms": ["object", "matter", "item"],
"antonyms": [],
"isPhrase": false,
"isHighValue": false,
"learningPriority": "low",
"examples": {
"original": {
"sentence": "He brought this thing up during our meeting",
"translation": "他在會議中提出了這件事",
"highlightWord": "thing"
},
"generated": {
"sentence": "That's an important thing to remember",
"translation": "那是需要記住的重要事情",
"imageUrl": "/images/examples/important_thing.png",
"audioUrl": "/audio/examples/important_thing.mp3"
}
},
"difficultyLevel": "A1"
},
"usageStatistics": {
"remainingAnalyses": 3,
"totalUsedToday": 2,
"costType": "word_query" // sentence_analysis, word_query
}
},
"message": "單字查詢完成"
}
```
### 3.3 獲取快取分析結果
#### 請求
```http
GET /ai/analysis-cache/{textHash}
Authorization: Bearer {accessToken}
```
#### 響應
```json
{
"success": true,
"data": {
// 與分析句子相同的結構
}
}
```
### 3.4 語法錯誤修正示例
#### 有錯誤句子的分析響應
```json
{
"success": true,
"data": {
"analysisId": "uuid",
"inputText": "I go to school yesterday and meet my friends.",
"grammarCorrection": {
"hasErrors": true,
"originalText": "I go to school yesterday and meet my friends.",
"correctedText": "I went to school yesterday and met my friends.",
"corrections": [
{
"position": {"start": 2, "end": 4}, // "go" 的位置
"errorType": "tense_mismatch",
"original": "go",
"corrected": "went",
"reason": "過去式時態修正:句子中有 'yesterday',應使用過去式",
"severity": "high"
},
{
"position": {"start": 29, "end": 33}, // "meet" 的位置
"errorType": "tense_mismatch",
"original": "meet",
"corrected": "met",
"reason": "過去式時態修正:與 'went' 保持時態一致",
"severity": "high"
}
],
"confidenceScore": 0.95
},
"sentenceMeaning": {
"translation": "我昨天去學校遇見了我的朋友們。",
"explanation": "這句話描述了過去發生的事情,表達了去學校並遇到朋友的經歷。"
},
"finalAnalysisText": "I went to school yesterday and met my friends.", // 後續分析使用修正版本
"wordAnalysis": {
// 基於修正後句子的分析結果
"went": {
"word": "went",
"translation": "去、前往",
"definition": "Past tense of go; to move or travel to a place",
"isHighValue": true,
"learningPriority": "high"
// ... 其他詳情
}
// ... 其他單字
}
}
}
```
### 3.5 清除快取
#### 請求
```http
DELETE /ai/analysis-cache/{analysisId}
Authorization: Bearer {accessToken}
```
#### 響應
```json
{
"success": true,
"message": "快取已清除"
}
```
## 4. 使用統計 API
### 4.1 獲取使用統計
#### 請求
```http
GET /users/usage-stats
Authorization: Bearer {accessToken}
```
#### 響應
```json
{
"success": true,
"data": {
"daily": {
"date": "2025-09-17",
"analysisCount": 1,
"wordClickCount": 15,
"uniqueWordsQueried": 8,
"totalTimeSpent": 320,
"remainingAnalyses": 4
},
"weekly": {
"startDate": "2025-09-11",
"endDate": "2025-09-17",
"analysisCount": 12,
"wordClickCount": 180,
"uniqueWordsQueried": 95,
"totalTimeSpent": 2400
},
"monthly": {
"month": "2025-09",
"analysisCount": 45,
"wordClickCount": 720,
"uniqueWordsQueried": 350,
"totalTimeSpent": 9600
},
"limits": {
"subscription": "free",
"dailyAnalysisLimit": 5,
"dailyImageGenerationLimit": 0,
"resetTime": "2025-09-17T12:48:00Z"
}
}
}
```
### 4.2 記錄單字點擊
#### 請求
```http
POST /users/word-interactions
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"analysisId": "uuid",
"word": "brought",
"action": "click", // click, audio_play, image_view
"timestamp": "2025-09-17T09:48:00Z",
"context": {
"sentencePosition": 2,
"isPhrase": true,
"difficultyLevel": "B1"
}
}
```
#### 響應
```json
{
"success": true,
"message": "互動記錄已保存"
}
```
## 5. 詞卡生成 API
### 5.1 從分析結果生成詞卡
#### 請求
```http
POST /flashcards/generate-from-analysis
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"analysisId": "uuid",
"selectedWords": ["brought", "meeting", "agreed"],
"cardSetId": "uuid", // 可選,不提供則創建新卡組
"options": {
"includePhrasesOnly": false,
"difficultyFilter": ["B1", "B2"],
"generateImages": true // 付費用戶才能使用
}
}
```
#### 響應
```json
{
"success": true,
"data": {
"cardSetId": "uuid",
"cardsGenerated": 3,
"cards": [
{
"id": "uuid",
"word": "brought",
"translation": "帶來、提出",
"definition": "Past tense of bring; to take or carry something to a place",
"partOfSpeech": "verb",
"pronunciation": "/brɔːt/",
"example": "He brought this thing up during our meeting",
"exampleTranslation": "他在我們的會議中提出了這件事",
"difficultyLevel": "B1",
"isPhrase": true,
"phraseInfo": {
"phrase": "bring up",
"meaning": "提出(話題)、養育"
},
"createdAt": "2025-09-17T09:48:00Z"
}
// ... 其他詞卡
]
},
"message": "詞卡生成成功"
}
```
## 6. 音頻服務 API
### 6.1 生成單字發音
#### 請求
```http
POST /audio/generate-pronunciation
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"text": "brought",
"accent": "us", // us, uk
"speed": "normal", // slow, normal, fast
"format": "mp3" // mp3, wav, ogg
}
```
#### 響應
```json
{
"success": true,
"data": {
"audioUrl": "/audio/pronunciation/brought_us_normal.mp3",
"duration": 0.8,
"fileSize": 12480,
"expiresAt": "2025-09-24T09:48:00Z"
}
}
```
### 6.2 生成例句發音
#### 請求
```http
POST /audio/generate-sentence
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"text": "He brought this thing up during our meeting",
"accent": "us",
"speed": "normal",
"highlightWord": "brought", // 可選,高亮某個單字
"format": "mp3"
}
```
#### 響應
```json
{
"success": true,
"data": {
"audioUrl": "/audio/sentences/sentence_hash_us_normal.mp3",
"duration": 3.2,
"fileSize": 51200,
"wordTimestamps": [
{"word": "He", "start": 0.0, "end": 0.2},
{"word": "brought", "start": 0.2, "end": 0.6},
// ... 其他單字時間戳
],
"expiresAt": "2025-09-24T09:48:00Z"
}
}
```
## 7. 圖片服務 API
### 7.1 生成例句圖片 (付費功能)
#### 請求
```http
POST /images/generate-example
Authorization: Bearer {accessToken}
Content-Type: application/json
{
"word": "brought",
"phrase": "bring up",
"example": "She brought up an important point in the meeting",
"context": "business meeting",
"style": "illustration", // illustration, photo, cartoon
"prompt": "A professional woman raising her hand in a business meeting"
}
```
#### 響應
```json
{
"success": true,
"data": {
"imageId": "uuid",
"imageUrl": "/images/examples/brought_up_meeting_123.png",
"thumbnailUrl": "/images/examples/thumbs/brought_up_meeting_123.png",
"width": 1024,
"height": 768,
"fileSize": 245760,
"style": "illustration",
"prompt": "A professional woman raising her hand in a business meeting",
"generatedAt": "2025-09-17T09:48:00Z",
"expiresAt": "2025-12-17T09:48:00Z"
}
}
```
### 7.2 獲取現有例句圖片
#### 請求
```http
GET /images/examples
Authorization: Bearer {accessToken}
Query Parameters:
- word: string (可選)
- phrase: string (可選)
- context: string (可選)
- limit: number (預設 20)
- offset: number (預設 0)
```
#### 響應
```json
{
"success": true,
"data": {
"images": [
{
"imageId": "uuid",
"word": "brought",
"phrase": "bring up",
"imageUrl": "/images/examples/brought_up_meeting_123.png",
"thumbnailUrl": "/images/examples/thumbs/brought_up_meeting_123.png",
"context": "business meeting",
"usage": "free", // free, premium
"downloads": 1250
}
],
"total": 150,
"hasMore": true
}
}
```
## 8. 錯誤代碼定義
### 8.1 認證錯誤 (AUTH_*)
- `AUTH_INVALID_TOKEN`: 無效的 Token
- `AUTH_TOKEN_EXPIRED`: Token 已過期
- `AUTH_INSUFFICIENT_PERMISSIONS`: 權限不足
### 8.2 使用限制錯誤 (LIMIT_*)
- `LIMIT_DAILY_ANALYSIS_EXCEEDED`: 超過每日分析次數限制
- `LIMIT_TEXT_TOO_LONG`: 文字長度超過限制
- `LIMIT_RATE_EXCEEDED`: 請求頻率過高
### 8.3 AI 服務錯誤 (AI_*)
- `AI_SERVICE_UNAVAILABLE`: AI 服務暫時不可用
- `AI_ANALYSIS_FAILED`: 句子分析失敗
- `AI_INVALID_LANGUAGE`: 不支援的語言
### 8.4 資源錯誤 (RESOURCE_*)
- `RESOURCE_NOT_FOUND`: 資源不存在
- `RESOURCE_CACHE_MISS`: 快取未命中
- `RESOURCE_GENERATION_FAILED`: 資源生成失敗
### 8.5 語法修正錯誤 (GRAMMAR_*)
- `GRAMMAR_CORRECTION_FAILED`: 語法修正失敗
- `GRAMMAR_TOO_MANY_ERRORS`: 錯誤過多無法修正
- `GRAMMAR_AMBIGUOUS_MEANING`: 語意模糊無法確定修正方向
### 8.6 語法錯誤類型定義
- `tense_mismatch`: 時態錯誤
- `subject_verb_disagreement`: 主謂不一致
- `wrong_preposition`: 介詞錯誤
- `word_order`: 詞序錯誤
- `spelling_error`: 拼寫錯誤
- `article_error`: 冠詞錯誤
- `plural_singular`: 單複數錯誤
- `missing_word`: 缺少詞彙
- `redundant_word`: 冗餘詞彙
## 9. SDK 和範例
### 9.1 JavaScript SDK 範例
```javascript
import { DramaLingClient } from '@dramaling/sdk';
const client = new DramaLingClient({
apiKey: 'your-api-key',
baseURL: 'https://api.dramaling.com/v1'
});
// 分析句子
async function analyzeSentence(text) {
try {
const result = await client.analyzeSentence({
inputText: text,
options: {
includeExamples: true,
includeAudio: true
}
});
return result.data;
} catch (error) {
console.error('Analysis failed:', error);
throw error;
}
}
// 使用範例
const analysis = await analyzeSentence(
"He brought this thing up during our meeting and no one agreed."
);
console.log('句子意思:', analysis.sentenceMeaning.translation);
console.log('單字分析:', analysis.wordAnalysis);
```
### 9.2 cURL 範例
```bash
# 分析句子
curl -X POST https://api.dramaling.com/v1/ai/analyze-sentence \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"inputText": "He brought this thing up during our meeting and no one agreed.",
"options": {
"includeExamples": true,
"includeAudio": true
}
}'
# 獲取使用統計
curl -X GET https://api.dramaling.com/v1/users/usage-stats \
-H "Authorization: Bearer YOUR_TOKEN"
```
## 10. API 版本管理
### 10.1 版本策略
- **當前版本**: v1
- **版本格式**: `/v{major}`
- **向後相容**: 保持至少 6 個月
- **棄用通知**: 提前 3 個月通知
### 10.2 版本變更日誌
#### v1.0.0 (2025-09-17)
- 初始版本發布
- 句子分析 API
- 使用統計 API
- 音頻服務 API
- 基礎圖片服務 API
#### v1.1.0 (計劃中)
- 批量分析 API
- 進階圖片生成選項
- 詞彙學習追蹤 API
- WebSocket 即時通知
這份 API 規格書提供了完整的介面定義,包括請求/響應格式、錯誤處理、使用範例和 SDK 說明,為前端開發和第三方整合提供了詳細的參考文檔。