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

742 lines
12 KiB
Markdown

# DramaLing API 端點詳細規格
## 🌐 API 基礎設定
### Base URL
```
Development: http://localhost:3000/api
Production: https://api.dramaling.com
```
### 認證方式
```http
Authorization: Bearer <JWT_TOKEN>
```
### 響應格式
```typescript
interface ApiResponse<T> {
success: boolean
data?: T
error?: {
code: string
message: string
details?: any
}
meta?: {
pagination?: {
page: number
limit: number
total: number
totalPages: number
}
}
}
```
## 🔐 認證 API
### POST /api/auth/register
**註冊新用戶**
```typescript
// Request
interface RegisterRequest {
email: string
username: string
password: string
confirmPassword: string
}
// Response
interface RegisterResponse {
user: {
id: string
email: string
username: string
}
message: string
}
// Validation
- email: valid email format
- username: 3-20 characters, alphanumeric and underscore
- password: min 8 chars, must contain uppercase, lowercase, number
- confirmPassword: must match password
```
### POST /api/auth/login
**用戶登入**
```typescript
// Request
interface LoginRequest {
email: string
password: string
rememberMe?: boolean
}
// Response
interface LoginResponse {
user: User
accessToken: string
refreshToken: string
expiresIn: number
}
// Error codes
- INVALID_CREDENTIALS: 帳號或密碼錯誤
- ACCOUNT_LOCKED: 帳號被鎖定
- EMAIL_NOT_VERIFIED: Email 未驗證
```
### POST /api/auth/logout
**登出**
```typescript
// Request
interface LogoutRequest {
refreshToken?: string
allDevices?: boolean
}
// Response
interface LogoutResponse {
message: string
}
```
### POST /api/auth/refresh
**更新 Token**
```typescript
// Request
interface RefreshRequest {
refreshToken: string
}
// Response
interface RefreshResponse {
accessToken: string
refreshToken: string
expiresIn: number
}
```
### POST /api/auth/verify-email
**驗證 Email**
```typescript
// Request
interface VerifyEmailRequest {
token: string
}
// Response
interface VerifyEmailResponse {
message: string
user: User
}
```
### POST /api/auth/forgot-password
**忘記密碼**
```typescript
// Request
interface ForgotPasswordRequest {
email: string
}
// Response
interface ForgotPasswordResponse {
message: string
}
```
### POST /api/auth/reset-password
**重設密碼**
```typescript
// Request
interface ResetPasswordRequest {
token: string
newPassword: string
confirmPassword: string
}
// Response
interface ResetPasswordResponse {
message: string
}
```
### POST /api/auth/google
**Google OAuth**
```typescript
// Request
interface GoogleAuthRequest {
idToken: string
}
// Response
interface GoogleAuthResponse {
user: User
accessToken: string
refreshToken: string
isNewUser: boolean
}
```
## 🎃 用戶 API
### GET /api/users/profile
**獲取用戶資料**
```typescript
// Response
interface ProfileResponse {
user: User
profile: UserProfile
stats: UserStats
}
```
### PUT /api/users/profile
**更新用戶資料**
```typescript
// Request
interface UpdateProfileRequest {
username?: string
displayName?: string
bio?: string
avatar?: File
preferredLanguage?: string
timezone?: string
}
// Response
interface UpdateProfileResponse {
user: User
message: string
}
```
### PUT /api/users/settings
**更新用戶設定**
```typescript
// Request
interface UpdateSettingsRequest {
dailyGoal?: number
reminderEnabled?: boolean
reminderTime?: string
emailNotifications?: boolean
pushNotifications?: boolean
theme?: 'light' | 'dark' | 'auto'
studyMode?: 'flip' | 'quiz' | 'typing'
}
```
### DELETE /api/users/account
**刪除帳號**
```typescript
// Request
interface DeleteAccountRequest {
password: string
reason?: string
}
// Response
interface DeleteAccountResponse {
message: string
}
```
## 🎓 詞卡 API
### GET /api/flashcard-sets
**獲取卡組列表**
```typescript
// Query parameters
interface GetSetsQuery {
page?: number
limit?: number
search?: string
tags?: string[]
orderBy?: 'created' | 'updated' | 'name' | 'progress'
order?: 'asc' | 'desc'
}
// Response
interface GetSetsResponse {
sets: FlashcardSet[]
pagination: Pagination
}
```
### POST /api/flashcard-sets
**創建卡組**
```typescript
// Request
interface CreateSetRequest {
name: string
description?: string
color?: string
tags?: string[]
isPublic?: boolean
}
// Response
interface CreateSetResponse {
set: FlashcardSet
}
```
### GET /api/flashcard-sets/:setId
**獲取卡組詳情**
```typescript
// Response
interface GetSetDetailResponse {
set: FlashcardSet
cards: Flashcard[]
stats: SetStats
}
```
### PUT /api/flashcard-sets/:setId
**更新卡組**
```typescript
// Request
interface UpdateSetRequest {
name?: string
description?: string
color?: string
tags?: string[]
isPublic?: boolean
}
```
### DELETE /api/flashcard-sets/:setId
**刪除卡組**
```typescript
// Response
interface DeleteSetResponse {
message: string
deletedCount: number
}
```
### GET /api/flashcards
**獲取詞卡列表**
```typescript
// Query parameters
interface GetCardsQuery {
setId?: string
search?: string
tags?: string[]
difficulty?: 'beginner' | 'intermediate' | 'advanced'
mastered?: boolean
favorite?: boolean
dueForReview?: boolean
page?: number
limit?: number
}
// Response
interface GetCardsResponse {
cards: Flashcard[]
pagination: Pagination
}
```
### POST /api/flashcards
**創建詞卡**
```typescript
// Request
interface CreateCardRequest {
setId: string
word: string
translation: string
partOfSpeech?: string
pronunciation?: string
definition?: string
exampleSentence?: string
exampleTranslation?: string
synonyms?: string[]
tags?: string[]
difficulty?: 'beginner' | 'intermediate' | 'advanced'
}
// Response
interface CreateCardResponse {
card: Flashcard
}
```
### PUT /api/flashcards/:cardId
**更新詞卡**
```typescript
// Request - same as CreateCardRequest but all fields optional
```
### DELETE /api/flashcards/:cardId
**刪除詞卡**
### POST /api/flashcards/batch
**批量操作**
```typescript
// Request
interface BatchOperationRequest {
operation: 'create' | 'update' | 'delete' | 'move'
cardIds?: string[]
data?: any
targetSetId?: string
}
// Response
interface BatchOperationResponse {
success: number
failed: number
errors?: any[]
}
```
## 🤖 AI 生成 API
### POST /api/ai/generate
**AI 生成詞卡**
```typescript
// Request
interface GenerateRequest {
mode: 'text' | 'theme'
input: string // text content or theme name
difficulty: 'beginner' | 'intermediate' | 'advanced'
count: number // 5-20
includeExamples?: boolean
includeSynonyms?: boolean
}
// Response
interface GenerateResponse {
cards: GeneratedCard[]
usage: {
promptTokens: number
completionTokens: number
totalTokens: number
}
}
interface GeneratedCard {
word: string
translation: string
partOfSpeech: string
pronunciation: string
definition: string
example: string
exampleTranslation: string
synonyms: string[]
difficulty: string
confidence: number // 0-1
}
```
### POST /api/ai/analyze-text
**分析文本難度**
```typescript
// Request
interface AnalyzeTextRequest {
text: string
}
// Response
interface AnalyzeTextResponse {
difficulty: 'beginner' | 'intermediate' | 'advanced'
wordCount: number
uniqueWords: number
averageSentenceLength: number
readabilityScore: number
suggestedWords: string[]
}
```
### GET /api/ai/quota
**查詢 AI 使用額度**
```typescript
// Response
interface QuotaResponse {
used: number
limit: number
resetAt: string
isPremium: boolean
}
```
## 📚 學習 API
### GET /api/learning/due
**獲取待複習詞卡**
```typescript
// Query parameters
interface GetDueCardsQuery {
setId?: string
limit?: number
}
// Response
interface GetDueCardsResponse {
cards: StudyCard[]
totalDue: number
}
interface StudyCard extends Flashcard {
learningRecord: LearningRecord
}
```
### POST /api/learning/review
**提交評分**
```typescript
// Request
interface ReviewRequest {
cardId: string
rating: 1 | 2 | 3 | 4 | 5
responseTime: number // milliseconds
mode: 'flip' | 'quiz' | 'typing'
}
// Response
interface ReviewResponse {
nextReviewDate: string
interval: number
easeFactor: number
masteryLevel: number
}
```
### GET /api/learning/stats
**獲取學習統計**
```typescript
// Query parameters
interface GetStatsQuery {
period: 'today' | 'week' | 'month' | 'year' | 'all'
setId?: string
}
// Response
interface StatsResponse {
cardsReviewed: number
cardsLearned: number
cardsMastered: number
studyTime: number // minutes
accuracy: number // percentage
streak: number
dailyGoalProgress: number
chart: {
dates: string[]
values: number[]
}
}
```
### POST /api/learning/session/start
**開始學習會話**
```typescript
// Request
interface StartSessionRequest {
mode: 'review' | 'learn' | 'cram'
setId?: string
}
// Response
interface StartSessionResponse {
sessionId: string
cards: StudyCard[]
}
```
### POST /api/learning/session/end
**結束學習會話**
```typescript
// Request
interface EndSessionRequest {
sessionId: string
}
// Response
interface EndSessionResponse {
duration: number
cardsStudied: number
accuracy: number
xpEarned: number
achievements: Achievement[]
}
```
## 🏆 成就 API
### GET /api/achievements
**獲取成就列表**
```typescript
// Response
interface GetAchievementsResponse {
unlocked: Achievement[]
locked: Achievement[]
recent: Achievement[]
}
```
### POST /api/achievements/:achievementId/claim
**領取成就獎勵**
```typescript
// Response
interface ClaimAchievementResponse {
xpEarned: number
totalXp: number
newLevel?: number
}
```
## 🔔 通知 API
### GET /api/notifications
**獲取通知**
```typescript
// Query parameters
interface GetNotificationsQuery {
unreadOnly?: boolean
type?: string
page?: number
limit?: number
}
// Response
interface GetNotificationsResponse {
notifications: Notification[]
unreadCount: number
pagination: Pagination
}
```
### PUT /api/notifications/:notificationId/read
**標記已讀**
### PUT /api/notifications/read-all
**全部標記已讀**
### DELETE /api/notifications/:notificationId
**刪除通知**
## 📁 匯出/匯入 API
### GET /api/export/cards
**匯出詞卡**
```typescript
// Query parameters
interface ExportQuery {
format: 'csv' | 'json' | 'anki'
setId?: string
cardIds?: string[]
}
// Response: File download
```
### POST /api/import/cards
**匯入詞卡**
```typescript
// Request: FormData with file
interface ImportRequest {
file: File
setId: string
format: 'csv' | 'json' | 'anki'
duplicateStrategy: 'skip' | 'replace' | 'create'
}
// Response
interface ImportResponse {
imported: number
skipped: number
errors: any[]
}
```
## 🔒 錯誤碼規範
```typescript
enum ErrorCode {
// Authentication
AUTH_INVALID_TOKEN = 'AUTH001',
AUTH_TOKEN_EXPIRED = 'AUTH002',
AUTH_UNAUTHORIZED = 'AUTH003',
// Validation
VALIDATION_ERROR = 'VAL001',
INVALID_INPUT = 'VAL002',
// Resource
NOT_FOUND = 'RES001',
ALREADY_EXISTS = 'RES002',
// Rate Limit
RATE_LIMIT_EXCEEDED = 'RATE001',
QUOTA_EXCEEDED = 'RATE002',
// Server
INTERNAL_ERROR = 'SRV001',
SERVICE_UNAVAILABLE = 'SRV002',
}
```
## 📊 Rate Limiting
| Endpoint | Free User | Premium User |
|----------|-----------|-------------|
| AI Generate | 50/day | Unlimited |
| API Calls | 1000/hour | 10000/hour |
| File Upload | 10MB | 50MB |
| Export | 5/day | Unlimited |
## 🔧 Webhooks
### 可用 Webhooks
1. `user.created` - 新用戶註冊
2. `user.deleted` - 用戶刪除
3. `subscription.created` - 訂閱創建
4. `subscription.updated` - 訂閱更新
5. `achievement.unlocked` - 成就解鎖
### Webhook Payload
```typescript
interface WebhookPayload {
event: string
timestamp: string
data: any
signature: string
}
```