dramaling-vocab-learning/docs/03_development/api/api-endpoints.md

8.8 KiB
Raw Blame History

DramaLing API 端點文檔

API 概述

Base URL:

  • 開發環境: http://localhost:3000/api
  • 生產環境: https://dramaling.com/api

認證方式: Bearer Token (Supabase JWT)

認證相關 API

註冊

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

{
  "email": "user@example.com",
  "password": "password123",
  "username": "johndoe"
}

Response 200:
{
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "username": "johndoe"
  },
  "session": {
    "access_token": "jwt_token",
    "refresh_token": "refresh_token"
  }
}

Response 400:
{
  "error": "Email already registered"
}

登入

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

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

Response 200:
{
  "user": {
    "id": "uuid",
    "email": "user@example.com"
  },
  "session": {
    "access_token": "jwt_token",
    "refresh_token": "refresh_token"
  }
}

Response 401:
{
  "error": "Invalid credentials"
}

登出

POST /api/auth/logout
Authorization: Bearer <token>

Response 200:
{
  "message": "Logged out successfully"
}

取得當前用戶

GET /api/auth/me
Authorization: Bearer <token>

Response 200:
{
  "user": {
    "id": "uuid",
    "email": "user@example.com",
    "username": "johndoe",
    "created_at": "2024-01-01T00:00:00Z"
  }
}

Response 401:
{
  "error": "Unauthorized"
}

詞卡管理 API

取得詞卡列表

GET /api/flashcards?page=1&limit=20&tag=business&search=hello
Authorization: Bearer <token>

Query Parameters:
- page: 頁碼 (預設: 1)
- limit: 每頁數量 (預設: 20, 最大: 100)
- tag: 標籤篩選
- search: 搜尋關鍵字
- sort: 排序方式 (created_at, difficulty, next_review_date)
- order: 排序順序 (asc, desc)

Response 200:
{
  "flashcards": [
    {
      "id": "uuid",
      "word": "Hello",
      "translation": "你好",
      "context": "Greeting",
      "example": "Hello, how are you?",
      "pronunciation": "/həˈloʊ/",
      "difficulty": 1,
      "next_review_date": "2024-01-02",
      "tags": ["greeting", "basic"],
      "created_at": "2024-01-01T00:00:00Z"
    }
  ],
  "pagination": {
    "total": 100,
    "page": 1,
    "limit": 20,
    "total_pages": 5
  }
}

取得單一詞卡

GET /api/flashcards/:id
Authorization: Bearer <token>

Response 200:
{
  "flashcard": {
    "id": "uuid",
    "word": "Hello",
    "translation": "你好",
    "context": "Greeting",
    "example": "Hello, how are you?",
    "pronunciation": "/həˈloʊ/",
    "difficulty": 1,
    "next_review_date": "2024-01-02",
    "review_count": 5,
    "ease_factor": 2.5,
    "interval": 1,
    "tags": ["greeting", "basic"],
    "created_at": "2024-01-01T00:00:00Z",
    "updated_at": "2024-01-01T00:00:00Z"
  }
}

Response 404:
{
  "error": "Flashcard not found"
}

建立詞卡

POST /api/flashcards
Authorization: Bearer <token>
Content-Type: application/json

{
  "word": "Hello",
  "translation": "你好",
  "context": "Greeting",
  "example": "Hello, how are you?",
  "pronunciation": "/həˈloʊ/",
  "difficulty": 1,
  "tags": ["greeting", "basic"]
}

Response 201:
{
  "flashcard": {
    "id": "uuid",
    "word": "Hello",
    ...
  }
}

Response 400:
{
  "error": "Invalid flashcard data"
}

更新詞卡

PUT /api/flashcards/:id
Authorization: Bearer <token>
Content-Type: application/json

{
  "translation": "您好",
  "difficulty": 2,
  "tags": ["greeting", "formal"]
}

Response 200:
{
  "flashcard": {
    "id": "uuid",
    "word": "Hello",
    "translation": "您好",
    ...
  }
}

刪除詞卡

DELETE /api/flashcards/:id
Authorization: Bearer <token>

Response 204: No Content

Response 404:
{
  "error": "Flashcard not found"
}

批量操作

POST /api/flashcards/batch
Authorization: Bearer <token>
Content-Type: application/json

{
  "action": "delete", // delete, update, add_tag, remove_tag
  "ids": ["uuid1", "uuid2", "uuid3"],
  "data": {
    // 僅 update 和 tag 操作需要
    "tags": ["new-tag"]
  }
}

Response 200:
{
  "success": true,
  "affected": 3
}

AI 生成 API

生成詞卡

POST /api/ai/generate-flashcard
Authorization: Bearer <token>
Content-Type: application/json

{
  "text": "I'm gonna grab a coffee, wanna come?",
  "type": "dialogue", // dialogue, topic, grammar
  "count": 5,
  "difficulty_range": [1, 3]
}

Response 200:
{
  "flashcards": [
    {
      "word": "gonna",
      "translation": "將要going to 的口語形式)",
      "context": "非正式對話",
      "example": "I'm gonna grab a coffee",
      "pronunciation": "/ˈɡɔnə/",
      "difficulty": 2,
      "usage": "非常口語化的表達,用於非正式場合"
    },
    ...
  ],
  "tokens_used": 1250,
  "remaining_quota": 8750
}

Response 429:
{
  "error": "Rate limit exceeded",
  "retry_after": 60
}

Response 402:
{
  "error": "Quota exceeded",
  "upgrade_url": "/pricing"
}

分析文本

POST /api/ai/analyze-text
Authorization: Bearer <token>
Content-Type: application/json

{
  "text": "Long dialogue from TV show...",
  "analysis_type": "vocabulary" // vocabulary, grammar, culture
}

Response 200:
{
  "analysis": {
    "key_vocabulary": [...],
    "difficulty_level": "intermediate",
    "cultural_notes": [...],
    "recommended_flashcards": [...]
  }
}

學習統計 API

取得學習概覽

GET /api/stats/overview
Authorization: Bearer <token>

Response 200:
{
  "stats": {
    "total_flashcards": 150,
    "cards_due_today": 25,
    "cards_reviewed_today": 15,
    "streak_days": 7,
    "total_study_time": 3600, // 秒
    "average_accuracy": 0.85,
    "cards_by_difficulty": {
      "1": 30,
      "2": 50,
      "3": 40,
      "4": 20,
      "5": 10
    }
  }
}

取得學習進度

GET /api/stats/progress?period=week
Authorization: Bearer <token>

Query Parameters:
- period: week, month, year, all

Response 200:
{
  "progress": [
    {
      "date": "2024-01-01",
      "cards_reviewed": 20,
      "new_cards": 5,
      "study_time": 1800,
      "accuracy": 0.9
    },
    ...
  ]
}

記錄學習

POST /api/stats/study-session
Authorization: Bearer <token>
Content-Type: application/json

{
  "flashcard_id": "uuid",
  "rating": 4, // 1-5
  "response_time": 3500 // 毫秒
}

Response 200:
{
  "next_review": {
    "date": "2024-01-05",
    "interval": 4,
    "ease_factor": 2.6
  }
}

標籤管理 API

取得標籤列表

GET /api/tags
Authorization: Bearer <token>

Response 200:
{
  "tags": [
    {
      "id": "uuid",
      "name": "business",
      "card_count": 25,
      "color": "#3B82F6"
    },
    ...
  ]
}

建立標籤

POST /api/tags
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "business",
  "color": "#3B82F6"
}

Response 201:
{
  "tag": {
    "id": "uuid",
    "name": "business",
    "color": "#3B82F6"
  }
}

更新標籤

PUT /api/tags/:id
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "work",
  "color": "#10B981"
}

Response 200:
{
  "tag": {
    "id": "uuid",
    "name": "work",
    "color": "#10B981"
  }
}

刪除標籤

DELETE /api/tags/:id
Authorization: Bearer <token>

Response 204: No Content

複習系統 API

取得今日複習

GET /api/review/today
Authorization: Bearer <token>

Response 200:
{
  "cards": [
    {
      "id": "uuid",
      "word": "Hello",
      "translation": "你好",
      ...
    }
  ],
  "total": 25,
  "completed": 10,
  "remaining": 15
}

提交複習結果

POST /api/review/submit
Authorization: Bearer <token>
Content-Type: application/json

{
  "flashcard_id": "uuid",
  "rating": 4, // 1: 完全忘記, 2: 錯誤, 3: 困難, 4: 猶豫, 5: 簡單
  "time_spent": 5000 // 毫秒
}

Response 200:
{
  "next_review": "2024-01-05",
  "interval": 4,
  "ease_factor": 2.6,
  "progress": {
    "completed": 11,
    "remaining": 14
  }
}

錯誤碼說明

狀態碼 說明
200 成功
201 建立成功
204 無內容(刪除成功)
400 請求參數錯誤
401 未認證
403 無權限
404 資源不存在
409 資源衝突
429 請求過於頻繁
500 伺服器錯誤

Rate Limiting

  • 一般 API: 100 請求/分鐘
  • AI 生成 API: 10 請求/分鐘
  • 批量操作: 10 請求/分鐘

超過限制時返回 429 狀態碼,並在 Retry-After header 中指示等待時間。

分頁規範

所有列表 API 支援分頁:

{
  "data": [...],
  "pagination": {
    "total": 100,
    "page": 1,
    "limit": 20,
    "total_pages": 5,
    "has_next": true,
    "has_prev": false
  }
}

WebSocket 事件 (未來功能)

// 連接
ws://localhost:3000/ws

// 事件類型
{
  "type": "flashcard.created",
  "data": { ... }
}

// 訂閱事件
{
  "action": "subscribe",
  "events": ["flashcard.*", "review.completed"]
}