496 lines
12 KiB
Markdown
496 lines
12 KiB
Markdown
# 用戶管理 API
|
||
|
||
## 📋 概述
|
||
用戶資料管理、個人檔案設定、學習統計等功能的 API 端點。
|
||
|
||
## 📌 API 端點
|
||
|
||
### 1. 獲取用戶資料
|
||
```http
|
||
GET /api/v1/users/profile
|
||
Authorization: Bearer <access_token>
|
||
```
|
||
|
||
#### 回應範例
|
||
```http
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"user_id": "USR_12345",
|
||
"username": "dramatic_learner",
|
||
"email": "user@example.com",
|
||
"avatar_url": "https://cdn.dramaling.com/avatars/12345.jpg",
|
||
"display_name": "學習者",
|
||
"level": "B1",
|
||
"level_progress": {
|
||
"current_level": "B1",
|
||
"progress_percentage": 65,
|
||
"total_perfect_dialogues": 23,
|
||
"required_perfect_dialogues": 30
|
||
},
|
||
"total_score": 15680,
|
||
"streak_days": 15,
|
||
"joined_date": "2024-01-15T08:00:00Z",
|
||
"last_active": "2024-09-05T14:30:00Z",
|
||
"preferences": {
|
||
"target_language": "en",
|
||
"native_language": "zh-TW",
|
||
"difficulty_preference": "adaptive",
|
||
"daily_goal_minutes": 30,
|
||
"notifications_enabled": true,
|
||
"push_notifications": {
|
||
"daily_reminder": true,
|
||
"streak_milestone": true,
|
||
"achievement_unlock": false
|
||
},
|
||
"theme": "light",
|
||
"auto_play_audio": true,
|
||
"subtitle_display": "always"
|
||
},
|
||
"subscription": {
|
||
"plan": "premium",
|
||
"status": "active",
|
||
"started_at": "2024-01-15T08:00:00Z",
|
||
"expires_at": "2025-01-15T08:00:00Z",
|
||
"auto_renewal": true,
|
||
"platform": "ios" // ios, android, web
|
||
}
|
||
},
|
||
"meta": {
|
||
"timestamp": "2024-09-07T12:00:00Z",
|
||
"cache_expires_at": "2024-09-07T12:05:00Z"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 2. 更新用戶資料
|
||
```http
|
||
PUT /api/v1/users/profile
|
||
Authorization: Bearer <access_token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"username": "new_username",
|
||
"display_name": "新暱稱",
|
||
"avatar_url": "https://cdn.dramaling.com/avatars/new_avatar.jpg",
|
||
"preferences": {
|
||
"daily_goal_minutes": 45,
|
||
"notifications_enabled": false,
|
||
"theme": "dark",
|
||
"push_notifications": {
|
||
"daily_reminder": false,
|
||
"streak_milestone": true
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 回應範例
|
||
```http
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"updated_fields": [
|
||
"username",
|
||
"display_name",
|
||
"preferences.daily_goal_minutes",
|
||
"preferences.notifications_enabled",
|
||
"preferences.theme"
|
||
],
|
||
"profile": {
|
||
"user_id": "USR_12345",
|
||
"username": "new_username",
|
||
"display_name": "新暱稱",
|
||
"preferences": {
|
||
"daily_goal_minutes": 45,
|
||
"notifications_enabled": false,
|
||
"theme": "dark"
|
||
}
|
||
}
|
||
},
|
||
"message": "Profile updated successfully"
|
||
}
|
||
```
|
||
|
||
#### 資料驗證規則
|
||
- **username**: 3-20字元,僅允許字母數字和底線
|
||
- **display_name**: 1-30字元,支援中英文
|
||
- **daily_goal_minutes**: 5-180分鐘
|
||
- **avatar_url**: 有效的URL格式
|
||
|
||
### 3. 上傳用戶頭像
|
||
```http
|
||
POST /api/v1/users/avatar
|
||
Authorization: Bearer <access_token>
|
||
Content-Type: multipart/form-data
|
||
|
||
Form Data:
|
||
- avatar: [Image File] (JPG, PNG, max 5MB)
|
||
```
|
||
|
||
#### 回應範例
|
||
```http
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"avatar_url": "https://cdn.dramaling.com/avatars/USR_12345_20240907.jpg",
|
||
"thumbnail_url": "https://cdn.dramaling.com/avatars/thumbs/USR_12345_20240907.jpg",
|
||
"upload_timestamp": "2024-09-07T12:00:00Z"
|
||
},
|
||
"message": "Avatar uploaded successfully"
|
||
}
|
||
```
|
||
|
||
### 4. 獲取用戶學習統計
|
||
```http
|
||
GET /api/v1/users/stats
|
||
Authorization: Bearer <access_token>
|
||
```
|
||
|
||
#### 查詢參數
|
||
- `period`: 統計週期 (`today`, `week`, `month`, `all`) - 預設 `all`
|
||
- `include_details`: 是否包含詳細分解 (`true`, `false`) - 預設 `false`
|
||
|
||
#### 回應範例
|
||
```http
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"summary": {
|
||
"total_dialogues": 245,
|
||
"total_study_time": 1280, // minutes
|
||
"vocabulary_learned": 890,
|
||
"vocabulary_mastered": 650,
|
||
"scenarios_completed": 35,
|
||
"achievements_unlocked": 18,
|
||
"perfect_dialogues": 89
|
||
},
|
||
"streaks": {
|
||
"current_streak": 15,
|
||
"longest_streak": 28,
|
||
"streak_start_date": "2024-08-23T00:00:00Z"
|
||
},
|
||
"weekly_progress": {
|
||
"dialogues_this_week": 12,
|
||
"minutes_this_week": 180,
|
||
"vocabulary_this_week": 45,
|
||
"daily_goal_minutes": 30,
|
||
"goal_completion_rate": 0.85,
|
||
"days_active_this_week": 6
|
||
},
|
||
"monthly_progress": {
|
||
"dialogues_this_month": 52,
|
||
"minutes_this_month": 780,
|
||
"vocabulary_this_month": 189,
|
||
"monthly_goal_completion": 0.92
|
||
},
|
||
"level_progression": {
|
||
"current_level": "B1",
|
||
"level_start_date": "2024-08-01T00:00:00Z",
|
||
"progress_in_current_level": 0.65,
|
||
"perfect_dialogues_in_level": 23,
|
||
"required_for_next_level": 30,
|
||
"estimated_days_to_next_level": 12
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 5. 獲取詳細學習歷史
|
||
```http
|
||
GET /api/v1/users/learning-history
|
||
Authorization: Bearer <access_token>
|
||
```
|
||
|
||
#### 查詢參數
|
||
- `start_date`: 開始日期 (ISO 8601)
|
||
- `end_date`: 結束日期 (ISO 8601)
|
||
- `activity_type`: 活動類型 (`dialogue`, `vocabulary`, `mission`, `all`)
|
||
- `page`: 頁碼 (預設 1)
|
||
- `limit`: 每頁筆數 (預設 20, 最大 100)
|
||
|
||
#### 回應範例
|
||
```http
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"activities": [
|
||
{
|
||
"activity_id": "ACT_12345",
|
||
"type": "dialogue",
|
||
"scenario_id": "restaurant_order",
|
||
"scenario_name": "餐廳點餐",
|
||
"score": 85,
|
||
"is_perfect": false,
|
||
"duration_minutes": 12,
|
||
"vocabulary_learned": 5,
|
||
"completed_at": "2024-09-07T11:30:00Z"
|
||
},
|
||
{
|
||
"activity_id": "ACT_12346",
|
||
"type": "vocabulary",
|
||
"practice_type": "spaced_repetition",
|
||
"words_reviewed": 20,
|
||
"words_mastered": 15,
|
||
"accuracy_rate": 0.75,
|
||
"completed_at": "2024-09-07T10:15:00Z"
|
||
},
|
||
{
|
||
"activity_id": "ACT_12347",
|
||
"type": "mission",
|
||
"mission_id": "daily_dialogue_3",
|
||
"mission_name": "今日對話練習 3次",
|
||
"progress": "3/3",
|
||
"reward_diamonds": 50,
|
||
"completed_at": "2024-09-07T09:45:00Z"
|
||
}
|
||
],
|
||
"pagination": {
|
||
"current_page": 1,
|
||
"total_pages": 5,
|
||
"total_items": 89,
|
||
"items_per_page": 20
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 6. 獲取成就系統
|
||
```http
|
||
GET /api/v1/users/achievements
|
||
Authorization: Bearer <access_token>
|
||
```
|
||
|
||
#### 回應範例
|
||
```http
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"unlocked_achievements": [
|
||
{
|
||
"achievement_id": "first_dialogue",
|
||
"name": "初次對話",
|
||
"description": "完成第一次對話練習",
|
||
"icon_url": "https://cdn.dramaling.com/achievements/first_dialogue.png",
|
||
"unlocked_at": "2024-01-15T10:30:00Z",
|
||
"rarity": "common"
|
||
},
|
||
{
|
||
"achievement_id": "week_streak_1",
|
||
"name": "週連擊手",
|
||
"description": "連續學習7天",
|
||
"icon_url": "https://cdn.dramaling.com/achievements/week_streak.png",
|
||
"unlocked_at": "2024-01-22T09:15:00Z",
|
||
"rarity": "uncommon"
|
||
}
|
||
],
|
||
"available_achievements": [
|
||
{
|
||
"achievement_id": "perfect_score_10",
|
||
"name": "完美十連",
|
||
"description": "獲得10次滿分對話",
|
||
"icon_url": "https://cdn.dramaling.com/achievements/perfect_10.png",
|
||
"progress": {
|
||
"current": 7,
|
||
"required": 10
|
||
},
|
||
"rarity": "rare"
|
||
}
|
||
],
|
||
"achievement_stats": {
|
||
"total_unlocked": 18,
|
||
"total_available": 45,
|
||
"completion_percentage": 0.4,
|
||
"rarity_breakdown": {
|
||
"common": 12,
|
||
"uncommon": 5,
|
||
"rare": 1,
|
||
"epic": 0,
|
||
"legendary": 0
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
### 7. 更新學習偏好設定
|
||
```http
|
||
PATCH /api/v1/users/preferences
|
||
Authorization: Bearer <access_token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"target_language": "en",
|
||
"difficulty_preference": "challenging",
|
||
"daily_goal_minutes": 60,
|
||
"auto_play_audio": false,
|
||
"push_notifications": {
|
||
"daily_reminder": true,
|
||
"streak_milestone": false,
|
||
"achievement_unlock": true
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 回應範例
|
||
```http
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"updated_preferences": {
|
||
"target_language": "en",
|
||
"difficulty_preference": "challenging",
|
||
"daily_goal_minutes": 60,
|
||
"auto_play_audio": false,
|
||
"push_notifications": {
|
||
"daily_reminder": true,
|
||
"streak_milestone": false,
|
||
"achievement_unlock": true
|
||
}
|
||
}
|
||
},
|
||
"message": "Preferences updated successfully"
|
||
}
|
||
```
|
||
|
||
### 8. 刪除用戶帳號
|
||
```http
|
||
DELETE /api/v1/users/account
|
||
Authorization: Bearer <access_token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"password": "current_password",
|
||
"confirmation": "DELETE_MY_ACCOUNT"
|
||
}
|
||
```
|
||
|
||
#### 回應範例
|
||
```http
|
||
Response 200 OK
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"deletion_scheduled_at": "2024-09-14T12:00:00Z",
|
||
"grace_period_days": 7,
|
||
"cancellation_token": "CANCEL_DEL_TOKEN_12345"
|
||
},
|
||
"message": "Account deletion scheduled. You have 7 days to cancel."
|
||
}
|
||
```
|
||
|
||
## 📊 資料結構
|
||
|
||
### 用戶偏好設定
|
||
```typescript
|
||
interface UserPreferences {
|
||
target_language: string; // ISO 639-1 語言碼
|
||
native_language: string; // ISO 639-1 語言碼
|
||
difficulty_preference: 'easy' | 'adaptive' | 'challenging';
|
||
daily_goal_minutes: number; // 5-180
|
||
notifications_enabled: boolean;
|
||
push_notifications: {
|
||
daily_reminder: boolean;
|
||
streak_milestone: boolean;
|
||
achievement_unlock: boolean;
|
||
};
|
||
theme: 'light' | 'dark' | 'auto';
|
||
auto_play_audio: boolean;
|
||
subtitle_display: 'always' | 'never' | 'learning_mode';
|
||
}
|
||
```
|
||
|
||
### 學習統計
|
||
```typescript
|
||
interface LearningStats {
|
||
total_dialogues: number;
|
||
total_study_time: number; // minutes
|
||
vocabulary_learned: number;
|
||
vocabulary_mastered: number;
|
||
scenarios_completed: number;
|
||
achievements_unlocked: number;
|
||
perfect_dialogues: number;
|
||
current_streak: number;
|
||
longest_streak: number;
|
||
}
|
||
```
|
||
|
||
## 🔧 錯誤處理
|
||
|
||
### 用戶管理相關錯誤
|
||
| 錯誤碼 | HTTP狀態 | 描述 |
|
||
|--------|----------|------|
|
||
| `USER_NOT_FOUND` | 404 | 用戶不存在 |
|
||
| `PROFILE_UPDATE_FAILED` | 400 | 個人資料更新失敗 |
|
||
| `AVATAR_UPLOAD_FAILED` | 400 | 頭像上傳失敗 |
|
||
| `INVALID_PREFERENCES` | 400 | 偏好設定無效 |
|
||
| `USERNAME_TAKEN` | 409 | 用戶名已被使用 |
|
||
| `AVATAR_TOO_LARGE` | 413 | 頭像檔案過大 |
|
||
| `ACCOUNT_DELETION_FAILED` | 400 | 帳號刪除失敗 |
|
||
|
||
### 錯誤回應範例
|
||
```http
|
||
Response 400 Bad Request
|
||
{
|
||
"success": false,
|
||
"error": {
|
||
"code": "PROFILE_UPDATE_FAILED",
|
||
"message": "個人資料更新失敗",
|
||
"details": {
|
||
"field": "username",
|
||
"reason": "Username must be 3-20 characters",
|
||
"provided_value": "ab"
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## 🛡️ 權限控制
|
||
|
||
### 資料存取權限
|
||
- **個人資料**: 只能存取和修改自己的資料
|
||
- **學習統計**: 只能查看自己的統計資料
|
||
- **成就系統**: 只能查看自己的成就進度
|
||
- **帳號刪除**: 需要密碼驗證
|
||
|
||
### 訂閱用戶特殊權限
|
||
- **詳細統計**: 可存取更詳細的學習分析
|
||
- **高級偏好**: 可設定進階學習偏好
|
||
- **資料導出**: 可導出完整學習歷史
|
||
|
||
## 🧪 測試範例
|
||
|
||
### 取得用戶資料
|
||
```bash
|
||
curl -X GET "https://api.dramaling.com/api/v1/users/profile" \
|
||
-H "Authorization: Bearer <access_token>" \
|
||
-H "Accept: application/json"
|
||
```
|
||
|
||
### 更新偏好設定
|
||
```bash
|
||
curl -X PATCH "https://api.dramaling.com/api/v1/users/preferences" \
|
||
-H "Authorization: Bearer <access_token>" \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"daily_goal_minutes": 45, "theme": "dark"}'
|
||
```
|
||
|
||
### 上傳頭像
|
||
```bash
|
||
curl -X POST "https://api.dramaling.com/api/v1/users/avatar" \
|
||
-H "Authorization: Bearer <access_token>" \
|
||
-F "avatar=@/path/to/avatar.jpg"
|
||
```
|
||
|
||
---
|
||
|
||
**模組負責人**: 後端團隊
|
||
**最後更新**: 2024年9月7日
|
||
**相關文檔**: [認證API](./authentication.md), [訂閱系統API](./subscription.md) |