12 KiB
12 KiB
DramaLing API 端點詳細規格
🌐 API 基礎設定
Base URL
Development: http://localhost:3000/api
Production: https://api.dramaling.com
認證方式
Authorization: Bearer <JWT_TOKEN>
響應格式
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
註冊新用戶
// 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
用戶登入
// 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
登出
// Request
interface LogoutRequest {
refreshToken?: string
allDevices?: boolean
}
// Response
interface LogoutResponse {
message: string
}
POST /api/auth/refresh
更新 Token
// Request
interface RefreshRequest {
refreshToken: string
}
// Response
interface RefreshResponse {
accessToken: string
refreshToken: string
expiresIn: number
}
POST /api/auth/verify-email
驗證 Email
// Request
interface VerifyEmailRequest {
token: string
}
// Response
interface VerifyEmailResponse {
message: string
user: User
}
POST /api/auth/forgot-password
忘記密碼
// Request
interface ForgotPasswordRequest {
email: string
}
// Response
interface ForgotPasswordResponse {
message: string
}
POST /api/auth/reset-password
重設密碼
// Request
interface ResetPasswordRequest {
token: string
newPassword: string
confirmPassword: string
}
// Response
interface ResetPasswordResponse {
message: string
}
POST /api/auth/google
Google OAuth
// Request
interface GoogleAuthRequest {
idToken: string
}
// Response
interface GoogleAuthResponse {
user: User
accessToken: string
refreshToken: string
isNewUser: boolean
}
🎃 用戶 API
GET /api/users/profile
獲取用戶資料
// Response
interface ProfileResponse {
user: User
profile: UserProfile
stats: UserStats
}
PUT /api/users/profile
更新用戶資料
// 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
更新用戶設定
// 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
刪除帳號
// Request
interface DeleteAccountRequest {
password: string
reason?: string
}
// Response
interface DeleteAccountResponse {
message: string
}
🎓 詞卡 API
GET /api/flashcard-sets
獲取卡組列表
// 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
創建卡組
// Request
interface CreateSetRequest {
name: string
description?: string
color?: string
tags?: string[]
isPublic?: boolean
}
// Response
interface CreateSetResponse {
set: FlashcardSet
}
GET /api/flashcard-sets/:setId
獲取卡組詳情
// Response
interface GetSetDetailResponse {
set: FlashcardSet
cards: Flashcard[]
stats: SetStats
}
PUT /api/flashcard-sets/:setId
更新卡組
// Request
interface UpdateSetRequest {
name?: string
description?: string
color?: string
tags?: string[]
isPublic?: boolean
}
DELETE /api/flashcard-sets/:setId
刪除卡組
// Response
interface DeleteSetResponse {
message: string
deletedCount: number
}
GET /api/flashcards
獲取詞卡列表
// 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
創建詞卡
// 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
更新詞卡
// Request - same as CreateCardRequest but all fields optional
DELETE /api/flashcards/:cardId
刪除詞卡
POST /api/flashcards/batch
批量操作
// 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 生成詞卡
// 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
分析文本難度
// 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 使用額度
// Response
interface QuotaResponse {
used: number
limit: number
resetAt: string
isPremium: boolean
}
📚 學習 API
GET /api/learning/due
獲取待複習詞卡
// 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
提交評分
// 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
獲取學習統計
// 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
開始學習會話
// Request
interface StartSessionRequest {
mode: 'review' | 'learn' | 'cram'
setId?: string
}
// Response
interface StartSessionResponse {
sessionId: string
cards: StudyCard[]
}
POST /api/learning/session/end
結束學習會話
// Request
interface EndSessionRequest {
sessionId: string
}
// Response
interface EndSessionResponse {
duration: number
cardsStudied: number
accuracy: number
xpEarned: number
achievements: Achievement[]
}
🏆 成就 API
GET /api/achievements
獲取成就列表
// Response
interface GetAchievementsResponse {
unlocked: Achievement[]
locked: Achievement[]
recent: Achievement[]
}
POST /api/achievements/:achievementId/claim
領取成就獎勵
// Response
interface ClaimAchievementResponse {
xpEarned: number
totalXp: number
newLevel?: number
}
🔔 通知 API
GET /api/notifications
獲取通知
// 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
匯出詞卡
// Query parameters
interface ExportQuery {
format: 'csv' | 'json' | 'anki'
setId?: string
cardIds?: string[]
}
// Response: File download
POST /api/import/cards
匯入詞卡
// 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[]
}
🔒 錯誤碼規範
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
user.created- 新用戶註冊user.deleted- 用戶刪除subscription.created- 訂閱創建subscription.updated- 訂閱更新achievement.unlocked- 成就解鎖
Webhook Payload
interface WebhookPayload {
event: string
timestamp: string
data: any
signature: string
}