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

579 lines
8.8 KiB
Markdown
Raw 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.

# DramaLing API 端點文檔
## API 概述
Base URL:
- 開發環境: `http://localhost:3000/api`
- 生產環境: `https://dramaling.com/api`
認證方式: Bearer Token (Supabase JWT)
## 認證相關 API
### 註冊
```http
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"
}
```
### 登入
```http
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"
}
```
### 登出
```http
POST /api/auth/logout
Authorization: Bearer <token>
Response 200:
{
"message": "Logged out successfully"
}
```
### 取得當前用戶
```http
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
### 取得詞卡列表
```http
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
}
}
```
### 取得單一詞卡
```http
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"
}
```
### 建立詞卡
```http
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"
}
```
### 更新詞卡
```http
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": "您好",
...
}
}
```
### 刪除詞卡
```http
DELETE /api/flashcards/:id
Authorization: Bearer <token>
Response 204: No Content
Response 404:
{
"error": "Flashcard not found"
}
```
### 批量操作
```http
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
### 生成詞卡
```http
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"
}
```
### 分析文本
```http
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
### 取得學習概覽
```http
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
}
}
}
```
### 取得學習進度
```http
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
},
...
]
}
```
### 記錄學習
```http
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
### 取得標籤列表
```http
GET /api/tags
Authorization: Bearer <token>
Response 200:
{
"tags": [
{
"id": "uuid",
"name": "business",
"card_count": 25,
"color": "#3B82F6"
},
...
]
}
```
### 建立標籤
```http
POST /api/tags
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "business",
"color": "#3B82F6"
}
Response 201:
{
"tag": {
"id": "uuid",
"name": "business",
"color": "#3B82F6"
}
}
```
### 更新標籤
```http
PUT /api/tags/:id
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "work",
"color": "#10B981"
}
Response 200:
{
"tag": {
"id": "uuid",
"name": "work",
"color": "#10B981"
}
}
```
### 刪除標籤
```http
DELETE /api/tags/:id
Authorization: Bearer <token>
Response 204: No Content
```
## 複習系統 API
### 取得今日複習
```http
GET /api/review/today
Authorization: Bearer <token>
Response 200:
{
"cards": [
{
"id": "uuid",
"word": "Hello",
"translation": "你好",
...
}
],
"total": 25,
"completed": 10,
"remaining": 15
}
```
### 提交複習結果
```http
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 支援分頁:
```json
{
"data": [...],
"pagination": {
"total": 100,
"page": 1,
"limit": 20,
"total_pages": 5,
"has_next": true,
"has_prev": false
}
}
```
## WebSocket 事件 (未來功能)
```javascript
// 連接
ws://localhost:3000/ws
// 事件類型
{
"type": "flashcard.created",
"data": { ... }
}
// 訂閱事件
{
"action": "subscribe",
"events": ["flashcard.*", "review.completed"]
}
```