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

20 KiB
Raw Blame History

互動式單字查詢 API 規格書

1. API 概覽

1.1 基本資訊

  • Base URL: https://api.dramaling.com/v1
  • 認證方式: Bearer Token (JWT)
  • 請求格式: JSON
  • 響應格式: JSON
  • 字元編碼: UTF-8

1.2 通用響應格式

成功響應

{
  "success": true,
  "data": { /* 實際資料 */ },
  "message": "操作成功描述",
  "timestamp": "2025-09-17T09:48:00Z",
  "requestId": "uuid"
}

錯誤響應

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

POST /auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "user_password"
}

響應:

{
  "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 分析句子

請求

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: 完整分析並標記高價值詞彙
  }
}

響應

{
  "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 單字點擊查詢

請求

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"] // 周圍單字上下文
  }
}

響應

{
  "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 獲取快取分析結果

請求

GET /ai/analysis-cache/{textHash}
Authorization: Bearer {accessToken}

響應

{
  "success": true,
  "data": {
    // 與分析句子相同的結構
  }
}

3.4 語法錯誤修正示例

有錯誤句子的分析響應

{
  "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 清除快取

請求

DELETE /ai/analysis-cache/{analysisId}
Authorization: Bearer {accessToken}

響應

{
  "success": true,
  "message": "快取已清除"
}

4. 使用統計 API

4.1 獲取使用統計

請求

GET /users/usage-stats
Authorization: Bearer {accessToken}

響應

{
  "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 記錄單字點擊

請求

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

響應

{
  "success": true,
  "message": "互動記錄已保存"
}

5. 詞卡生成 API

5.1 從分析結果生成詞卡

請求

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 // 付費用戶才能使用
  }
}

響應

{
  "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 生成單字發音

請求

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
}

響應

{
  "success": true,
  "data": {
    "audioUrl": "/audio/pronunciation/brought_us_normal.mp3",
    "duration": 0.8,
    "fileSize": 12480,
    "expiresAt": "2025-09-24T09:48:00Z"
  }
}

6.2 生成例句發音

請求

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

響應

{
  "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 生成例句圖片 (付費功能)

請求

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

響應

{
  "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 獲取現有例句圖片

請求

GET /images/examples
Authorization: Bearer {accessToken}
Query Parameters:
- word: string (可選)
- phrase: string (可選)
- context: string (可選)
- limit: number (預設 20)
- offset: number (預設 0)

響應

{
  "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 範例

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 範例

# 分析句子
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 說明,為前端開發和第三方整合提供了詳細的參考文檔。