# 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 Response 200: { "message": "Logged out successfully" } ``` ### 取得當前用戶 ```http GET /api/auth/me Authorization: Bearer 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 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 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 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 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 Response 204: No Content Response 404: { "error": "Flashcard not found" } ``` ### 批量操作 ```http POST /api/flashcards/batch Authorization: Bearer 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 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 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 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 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 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 Response 200: { "tags": [ { "id": "uuid", "name": "business", "card_count": 25, "color": "#3B82F6" }, ... ] } ``` ### 建立標籤 ```http POST /api/tags Authorization: Bearer Content-Type: application/json { "name": "business", "color": "#3B82F6" } Response 201: { "tag": { "id": "uuid", "name": "business", "color": "#3B82F6" } } ``` ### 更新標籤 ```http PUT /api/tags/:id Authorization: Bearer Content-Type: application/json { "name": "work", "color": "#10B981" } Response 200: { "tag": { "id": "uuid", "name": "work", "color": "#10B981" } } ``` ### 刪除標籤 ```http DELETE /api/tags/:id Authorization: Bearer Response 204: No Content ``` ## 複習系統 API ### 取得今日複習 ```http GET /api/review/today Authorization: Bearer Response 200: { "cards": [ { "id": "uuid", "word": "Hello", "translation": "你好", ... } ], "total": 25, "completed": 10, "remaining": 15 } ``` ### 提交複習結果 ```http POST /api/review/submit Authorization: Bearer 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"] } ```