593 lines
10 KiB
Markdown
593 lines
10 KiB
Markdown
# LinguaForge API 規格文件
|
||
|
||
## API 基礎資訊
|
||
|
||
### Base URL
|
||
```
|
||
Development: https://api-dev.linguaforge.com/v1
|
||
Production: https://api.linguaforge.com/v1
|
||
```
|
||
|
||
### 認證方式
|
||
```http
|
||
Authorization: Bearer <JWT_TOKEN>
|
||
```
|
||
|
||
### 通用回應格式
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": { ... },
|
||
"message": "操作成功",
|
||
"timestamp": "2024-01-15T10:30:00Z"
|
||
}
|
||
```
|
||
|
||
### 錯誤回應格式
|
||
```json
|
||
{
|
||
"success": false,
|
||
"error": {
|
||
"code": "ERROR_CODE",
|
||
"message": "錯誤描述",
|
||
"details": { ... }
|
||
},
|
||
"timestamp": "2024-01-15T10:30:00Z"
|
||
}
|
||
```
|
||
|
||
## 1. 認證相關 API
|
||
|
||
### 1.1 使用者註冊
|
||
```http
|
||
POST /auth/register
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"email": "user@example.com",
|
||
"password": "SecurePassword123!",
|
||
"username": "johndoe",
|
||
"acceptTerms": true
|
||
}
|
||
|
||
Response 201:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"userId": "uuid",
|
||
"email": "user@example.com",
|
||
"username": "johndoe",
|
||
"emailVerificationRequired": true
|
||
},
|
||
"message": "註冊成功,請查收驗證郵件"
|
||
}
|
||
```
|
||
|
||
### 1.2 使用者登入
|
||
```http
|
||
POST /auth/login
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"email": "user@example.com",
|
||
"password": "SecurePassword123!"
|
||
}
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"accessToken": "eyJhbGc...",
|
||
"refreshToken": "eyJhbGc...",
|
||
"expiresIn": 900,
|
||
"user": {
|
||
"id": "uuid",
|
||
"email": "user@example.com",
|
||
"username": "johndoe"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 1.3 重新整理 Token
|
||
```http
|
||
POST /auth/refresh
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"refreshToken": "eyJhbGc..."
|
||
}
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"accessToken": "eyJhbGc...",
|
||
"expiresIn": 900
|
||
}
|
||
}
|
||
```
|
||
|
||
### 1.4 登出
|
||
```http
|
||
POST /auth/logout
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"message": "登出成功"
|
||
}
|
||
```
|
||
|
||
## 2. 詞卡管理 API
|
||
|
||
### 2.1 取得詞卡列表
|
||
```http
|
||
GET /cards?page=1&limit=20&sort=createdAt&order=desc
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"cards": [
|
||
{
|
||
"id": "uuid",
|
||
"word": "abandon",
|
||
"definition": "放棄、遺棄",
|
||
"examples": ["He abandoned his car in the snow."],
|
||
"imageUrl": "https://...",
|
||
"audioUrl": "https://...",
|
||
"nextReviewDate": "2024-01-16T10:00:00Z",
|
||
"easinessFactor": 2.5,
|
||
"repetitionCount": 3,
|
||
"createdAt": "2024-01-10T10:00:00Z"
|
||
}
|
||
],
|
||
"pagination": {
|
||
"page": 1,
|
||
"limit": 20,
|
||
"total": 150,
|
||
"pages": 8
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2.2 取得單一詞卡
|
||
```http
|
||
GET /cards/:cardId
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"id": "uuid",
|
||
"word": "abandon",
|
||
"definition": "放棄、遺棄",
|
||
"examples": [
|
||
"He abandoned his car in the snow.",
|
||
"They had to abandon the ship."
|
||
],
|
||
"sourceSentence": "I need to abandon this bad habit.",
|
||
"imageUrl": "https://...",
|
||
"audioUrl": "https://...",
|
||
"pronunciation": "/əˈbændən/",
|
||
"partOfSpeech": "verb",
|
||
"difficulty": "medium",
|
||
"tags": ["常用", "動詞"],
|
||
"nextReviewDate": "2024-01-16T10:00:00Z",
|
||
"reviewHistory": [
|
||
{
|
||
"date": "2024-01-15T10:00:00Z",
|
||
"quality": 4,
|
||
"timeSpent": 15
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2.3 AI 生成詞卡
|
||
```http
|
||
POST /cards/generate
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"sentence": "I need to abandon this bad habit immediately.",
|
||
"targetWord": "abandon"
|
||
}
|
||
|
||
Response 201:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"id": "uuid",
|
||
"word": "abandon",
|
||
"definition": "to give up or discontinue something",
|
||
"examples": [
|
||
"He abandoned his car in the snow.",
|
||
"They had to abandon the ship."
|
||
],
|
||
"pronunciation": "/əˈbændən/",
|
||
"partOfSpeech": "verb",
|
||
"imageUrl": "https://...",
|
||
"audioUrl": "https://...",
|
||
"aiGenerated": true,
|
||
"generationMetadata": {
|
||
"model": "gemini-pro",
|
||
"confidence": 0.95
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2.4 更新詞卡
|
||
```http
|
||
PUT /cards/:cardId
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"definition": "放棄、拋棄",
|
||
"examples": ["新例句1", "新例句2"],
|
||
"tags": ["更新標籤"]
|
||
}
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": { ... },
|
||
"message": "詞卡更新成功"
|
||
}
|
||
```
|
||
|
||
### 2.5 刪除詞卡
|
||
```http
|
||
DELETE /cards/:cardId
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"message": "詞卡刪除成功"
|
||
}
|
||
```
|
||
|
||
## 3. 複習系統 API
|
||
|
||
### 3.1 取得今日複習詞卡
|
||
```http
|
||
GET /review/today?limit=20
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"reviewCards": [
|
||
{
|
||
"id": "uuid",
|
||
"word": "abandon",
|
||
"nextReviewDate": "2024-01-15T10:00:00Z",
|
||
"overduedays": 0,
|
||
"priority": "high"
|
||
}
|
||
],
|
||
"totalCount": 15,
|
||
"newCards": 5,
|
||
"reviewCards": 10
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.2 提交複習結果
|
||
```http
|
||
POST /review/submit
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"cardId": "uuid",
|
||
"quality": 4,
|
||
"timeSpent": 15,
|
||
"sessionId": "uuid"
|
||
}
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"nextReviewDate": "2024-01-17T10:00:00Z",
|
||
"newInterval": 3,
|
||
"newEasinessFactor": 2.6,
|
||
"streakDays": 7
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.3 開始複習會話
|
||
```http
|
||
POST /review/session/start
|
||
Authorization: Bearer <token>
|
||
|
||
Response 201:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"sessionId": "uuid",
|
||
"startedAt": "2024-01-15T10:00:00Z",
|
||
"cardsToReview": 15
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.4 結束複習會話
|
||
```http
|
||
POST /review/session/:sessionId/end
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"sessionId": "uuid",
|
||
"duration": 300,
|
||
"cardsReviewed": 15,
|
||
"accuracy": 0.87,
|
||
"stats": {
|
||
"perfect": 5,
|
||
"good": 8,
|
||
"hard": 2,
|
||
"again": 0
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 4. 語音評估 API
|
||
|
||
### 4.1 提交語音評估
|
||
```http
|
||
POST /speech/assess
|
||
Authorization: Bearer <token>
|
||
Content-Type: multipart/form-data
|
||
|
||
FormData:
|
||
- audio: <audio_file>
|
||
- text: "I need to abandon this bad habit"
|
||
- cardId: "uuid" (optional)
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"assessmentId": "uuid",
|
||
"scores": {
|
||
"accuracy": 85.5,
|
||
"fluency": 72.3,
|
||
"completeness": 100,
|
||
"pronunciation": 86.2
|
||
},
|
||
"phonemes": [
|
||
{
|
||
"phoneme": "aɪ",
|
||
"accuracy": 95
|
||
}
|
||
],
|
||
"words": [
|
||
{
|
||
"word": "abandon",
|
||
"accuracy": 82,
|
||
"errorType": null
|
||
}
|
||
],
|
||
"suggestions": [
|
||
"注意 'abandon' 的重音在第二個音節"
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 4.2 取得評估歷史
|
||
```http
|
||
GET /speech/history?cardId=uuid&page=1&limit=10
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"assessments": [
|
||
{
|
||
"id": "uuid",
|
||
"text": "I need to abandon this bad habit",
|
||
"pronunciationScore": 86.2,
|
||
"assessedAt": "2024-01-15T10:00:00Z"
|
||
}
|
||
],
|
||
"pagination": { ... }
|
||
}
|
||
}
|
||
```
|
||
|
||
## 5. 學習統計 API
|
||
|
||
### 5.1 取得學習統計
|
||
```http
|
||
GET /stats/overview?period=week
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"period": "week",
|
||
"stats": {
|
||
"totalCards": 150,
|
||
"cardsReviewed": 105,
|
||
"newCards": 15,
|
||
"studyTime": 3600,
|
||
"accuracy": 0.85,
|
||
"streakDays": 7
|
||
},
|
||
"dailyStats": [
|
||
{
|
||
"date": "2024-01-15",
|
||
"cardsReviewed": 20,
|
||
"newCards": 3,
|
||
"studyTime": 600,
|
||
"accuracy": 0.90
|
||
}
|
||
],
|
||
"achievements": [
|
||
{
|
||
"id": "7day_streak",
|
||
"name": "7天連續學習",
|
||
"unlockedAt": "2024-01-15T10:00:00Z"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5.2 取得學習進度
|
||
```http
|
||
GET /stats/progress
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"totalWords": 150,
|
||
"mastered": 45,
|
||
"learning": 80,
|
||
"new": 25,
|
||
"retention": {
|
||
"mature": 0.92,
|
||
"young": 0.85
|
||
},
|
||
"forecast": {
|
||
"tomorrow": 18,
|
||
"thisWeek": 126
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 6. 使用者設定 API
|
||
|
||
### 6.1 取得使用者偏好
|
||
```http
|
||
GET /user/preferences
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"dailyReviewGoal": 20,
|
||
"reviewReminderTime": "09:00",
|
||
"pushNotifications": true,
|
||
"uiLanguage": "zh-TW",
|
||
"learningLanguage": "en-US",
|
||
"studySettings": {
|
||
"autoPlay": true,
|
||
"showImages": true,
|
||
"reviewOrder": "random"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6.2 更新使用者偏好
|
||
```http
|
||
PUT /user/preferences
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"dailyReviewGoal": 30,
|
||
"pushNotifications": false
|
||
}
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"message": "偏好設定更新成功"
|
||
}
|
||
```
|
||
|
||
## 7. 訂閱管理 API
|
||
|
||
### 7.1 取得訂閱方案
|
||
```http
|
||
GET /subscriptions/plans
|
||
Authorization: Bearer <token>
|
||
|
||
Response 200:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"plans": [
|
||
{
|
||
"id": "uuid",
|
||
"name": "免費版",
|
||
"tier": "free",
|
||
"monthlyPrice": 0,
|
||
"features": ["每日20張詞卡", "基礎統計"]
|
||
},
|
||
{
|
||
"id": "uuid",
|
||
"name": "專業版",
|
||
"tier": "premium",
|
||
"monthlyPrice": 9.99,
|
||
"yearlyPrice": 99.99,
|
||
"features": ["無限詞卡", "進階統計", "語音評估", "離線使用"]
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
### 7.2 訂閱方案
|
||
```http
|
||
POST /subscriptions/subscribe
|
||
Authorization: Bearer <token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"planId": "uuid",
|
||
"billingPeriod": "monthly",
|
||
"paymentMethod": "credit_card"
|
||
}
|
||
|
||
Response 201:
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"subscriptionId": "uuid",
|
||
"status": "active",
|
||
"expiresAt": "2024-02-15T10:00:00Z",
|
||
"paymentUrl": "https://payment-gateway.com/..."
|
||
}
|
||
}
|
||
```
|
||
|
||
## 錯誤代碼對照表
|
||
|
||
| 錯誤代碼 | HTTP 狀態碼 | 說明 |
|
||
|---------|------------|------|
|
||
| AUTH_INVALID_CREDENTIALS | 401 | 無效的登入憑證 |
|
||
| AUTH_TOKEN_EXPIRED | 401 | Token 已過期 |
|
||
| AUTH_UNAUTHORIZED | 403 | 無權限存取 |
|
||
| VALIDATION_ERROR | 400 | 輸入資料驗證失敗 |
|
||
| RESOURCE_NOT_FOUND | 404 | 資源不存在 |
|
||
| DUPLICATE_RESOURCE | 409 | 資源已存在 |
|
||
| RATE_LIMIT_EXCEEDED | 429 | 超過請求頻率限制 |
|
||
| INTERNAL_SERVER_ERROR | 500 | 伺服器內部錯誤 |
|
||
| SERVICE_UNAVAILABLE | 503 | 服務暫時不可用 | |