dramaling-vocab-learning/docs/03_development/api/backend-development-plan.md

1184 lines
27 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DramaLing 後端開發計劃
## 1. 總體架構概述
### 1.1 技術棧確認 (已更新為 .NET Core)
- **API 框架**: ASP.NET Core Web API 8.0 ⚡ (已從 Next.js 14 API Routes 重寫)
- **資料庫**: PostgreSQL via Supabase (Entity Framework Core)
- **認證系統**: JWT + ASP.NET Core Identity (兼容 Supabase)
- **AI 服務**: Google Gemini API (.NET SDK)
- **檔案存儲**: Supabase Storage
- **部署平台**: Azure App Service / Railway (從 Vercel 遷移)
### 1.2 前端依賴對應
基於已實作的前端頁面,後端需要支援以下功能:
- `/app/dashboard/page.tsx` → 儀表板統計 API
- `/app/flashcards/page.tsx` → 詞卡管理 API + 智能檢測 API
- `/app/learn/page.tsx` → 學習系統 API + 錯誤回報 API
- `/app/generate/page.tsx` → AI 生成詞卡 API
## 2. 資料庫架構設計
### 2.1 完整 Schema 設計
```sql
-- =========================================
-- 用戶相關表
-- =========================================
-- 用戶基本信息表
CREATE TABLE users (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
email VARCHAR(255) UNIQUE NOT NULL,
display_name VARCHAR(100),
avatar_url TEXT,
subscription_type VARCHAR(20) DEFAULT 'free', -- 'free', 'premium'
subscription_expires_at TIMESTAMP,
preferences JSONB DEFAULT '{}', -- 用戶偏好設定
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 用戶學習設定表
CREATE TABLE user_settings (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
daily_goal INTEGER DEFAULT 20, -- 每日目標詞數
reminder_time TIME DEFAULT '09:00:00', -- 提醒時間
reminder_enabled BOOLEAN DEFAULT true,
difficulty_preference VARCHAR(20) DEFAULT 'balanced', -- 'conservative', 'balanced', 'aggressive'
auto_play_audio BOOLEAN DEFAULT true,
show_pronunciation BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- =========================================
-- 詞卡相關表
-- =========================================
-- 卡組表
CREATE TABLE card_sets (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
name VARCHAR(255) NOT NULL,
description TEXT,
color VARCHAR(50) DEFAULT 'bg-blue-500',
is_public BOOLEAN DEFAULT false,
card_count INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 詞卡主表
CREATE TABLE flashcards (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
card_set_id UUID REFERENCES card_sets(id) ON DELETE CASCADE,
-- 基本詞卡信息
word VARCHAR(255) NOT NULL,
part_of_speech VARCHAR(50), -- 詞性
pronunciation_us VARCHAR(255), -- 美式發音
pronunciation_uk VARCHAR(255), -- 英式發音
translation TEXT NOT NULL, -- 中文翻譯
definition TEXT NOT NULL, -- 英文定義
difficulty_level VARCHAR(10), -- CEFR等級: A1, A2, B1, B2, C1, C2
-- 例句信息
original_example TEXT, -- 原始例句
original_example_translation TEXT, -- 原始例句翻譯
generated_example TEXT, -- AI生成例句
generated_example_translation TEXT, -- AI生成例句翻譯
example_image_url TEXT, -- 例句圖片URL
-- 學習相關
synonyms TEXT[], -- 同義詞陣列
antonyms TEXT[], -- 反義詞陣列
-- SM-2算法參數
easiness_factor FLOAT DEFAULT 2.5, -- 難度係數
repetitions INTEGER DEFAULT 0, -- 重複次數
interval_days INTEGER DEFAULT 1, -- 間隔天數
next_review_date DATE DEFAULT CURRENT_DATE,
-- 統計信息
times_reviewed INTEGER DEFAULT 0,
times_correct INTEGER DEFAULT 0,
last_reviewed_at TIMESTAMP,
-- 狀態
is_favorite BOOLEAN DEFAULT false,
is_archived BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- 標籤表
CREATE TABLE tags (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
name VARCHAR(100) NOT NULL,
color VARCHAR(50) DEFAULT '#3B82F6',
usage_count INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(user_id, name)
);
-- 詞卡標籤關聯表
CREATE TABLE flashcard_tags (
flashcard_id UUID REFERENCES flashcards(id) ON DELETE CASCADE,
tag_id UUID REFERENCES tags(id) ON DELETE CASCADE,
PRIMARY KEY (flashcard_id, tag_id)
);
-- =========================================
-- 學習系統表
-- =========================================
-- 學習會話表
CREATE TABLE study_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
session_type VARCHAR(50), -- 'flip', 'quiz', 'fill', 'listening', 'speaking'
started_at TIMESTAMP DEFAULT NOW(),
ended_at TIMESTAMP,
total_cards INTEGER DEFAULT 0,
correct_count INTEGER DEFAULT 0,
duration_seconds INTEGER DEFAULT 0
);
-- 學習記錄表
CREATE TABLE study_records (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
flashcard_id UUID REFERENCES flashcards(id) ON DELETE CASCADE,
session_id UUID REFERENCES study_sessions(id) ON DELETE CASCADE,
study_mode VARCHAR(50) NOT NULL, -- 'flip', 'quiz', 'fill', 'listening', 'speaking'
rating INTEGER NOT NULL, -- 1-5評分
response_time_ms INTEGER, -- 回應時間(毫秒)
user_answer TEXT, -- 用戶答案
is_correct BOOLEAN,
-- SM-2算法更新後的值
new_easiness_factor FLOAT,
new_interval_days INTEGER,
new_repetitions INTEGER,
studied_at TIMESTAMP DEFAULT NOW()
);
-- =========================================
-- AI生成相關表
-- =========================================
-- AI生成任務表
CREATE TABLE ai_generation_tasks (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
-- 輸入參數
input_text TEXT NOT NULL,
extraction_type VARCHAR(50) NOT NULL, -- 'vocabulary', 'smart'
card_count INTEGER DEFAULT 10,
-- 任務狀態
status VARCHAR(50) DEFAULT 'pending', -- 'pending', 'processing', 'completed', 'failed'
progress_percentage INTEGER DEFAULT 0,
-- 結果
generated_cards JSONB, -- 生成的詞卡JSON數據
error_message TEXT,
-- API使用統計
api_calls_used INTEGER DEFAULT 0,
cost_estimated DECIMAL(10,4) DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
completed_at TIMESTAMP
);
-- =========================================
-- 錯誤回報系統表
-- =========================================
-- 錯誤回報表
CREATE TABLE error_reports (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
flashcard_id UUID REFERENCES flashcards(id) ON DELETE CASCADE,
-- 回報信息
report_type VARCHAR(100) NOT NULL, -- '發音錯誤', '翻譯不準確', '例句錯誤' 等
description TEXT,
study_mode VARCHAR(50), -- 回報來源的學習模式
-- 狀態追蹤
status VARCHAR(50) DEFAULT 'pending', -- 'pending', 'resolved', 'dismissed'
admin_notes TEXT,
resolved_at TIMESTAMP,
resolved_by UUID REFERENCES users(id),
created_at TIMESTAMP DEFAULT NOW()
);
-- =========================================
-- 統計相關表
-- =========================================
-- 每日學習統計表
CREATE TABLE daily_stats (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID REFERENCES users(id) ON DELETE CASCADE,
date DATE NOT NULL,
-- 學習統計
words_studied INTEGER DEFAULT 0,
words_correct INTEGER DEFAULT 0,
study_time_seconds INTEGER DEFAULT 0,
session_count INTEGER DEFAULT 0,
-- 生成統計
cards_generated INTEGER DEFAULT 0,
ai_api_calls INTEGER DEFAULT 0,
created_at TIMESTAMP DEFAULT NOW(),
UNIQUE(user_id, date)
);
-- =========================================
-- 系統配置表
-- =========================================
-- 系統設定表
CREATE TABLE system_settings (
key VARCHAR(255) PRIMARY KEY,
value TEXT NOT NULL,
description TEXT,
updated_at TIMESTAMP DEFAULT NOW()
);
-- 插入預設系統設定
INSERT INTO system_settings (key, value, description) VALUES
('max_daily_ai_generations_free', '5', '免費用戶每日AI生成次數限制'),
('max_daily_ai_generations_premium', '50', '付費用戶每日AI生成次數限制'),
('max_cards_per_generation', '20', '單次生成最大詞卡數量'),
('sm2_initial_interval', '1', 'SM-2算法初始間隔天數'),
('sm2_max_interval', '365', 'SM-2算法最大間隔天數');
```
### 2.2 索引優化
```sql
-- 性能關鍵索引
CREATE INDEX idx_flashcards_user_next_review ON flashcards(user_id, next_review_date);
CREATE INDEX idx_flashcards_user_set ON flashcards(user_id, card_set_id);
CREATE INDEX idx_flashcards_word_search ON flashcards USING gin(to_tsvector('english', word || ' ' || translation));
CREATE INDEX idx_study_records_user_date ON study_records(user_id, studied_at);
CREATE INDEX idx_error_reports_status ON error_reports(status, created_at);
CREATE INDEX idx_daily_stats_user_date ON daily_stats(user_id, date);
```
### 2.3 Row Level Security (RLS) 設定
```sql
-- 啟用RLS
ALTER TABLE users ENABLE ROW LEVEL SECURITY;
ALTER TABLE card_sets ENABLE ROW LEVEL SECURITY;
ALTER TABLE flashcards ENABLE ROW LEVEL SECURITY;
ALTER TABLE tags ENABLE ROW LEVEL SECURITY;
ALTER TABLE study_sessions ENABLE ROW LEVEL SECURITY;
ALTER TABLE study_records ENABLE ROW LEVEL SECURITY;
ALTER TABLE error_reports ENABLE ROW LEVEL SECURITY;
ALTER TABLE daily_stats ENABLE ROW LEVEL SECURITY;
-- 用戶只能存取自己的數據
CREATE POLICY "Users can only access their own data" ON users
FOR ALL USING (auth.uid() = id);
CREATE POLICY "Users can only access their own card sets" ON card_sets
FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "Users can only access their own flashcards" ON flashcards
FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "Users can only access their own tags" ON tags
FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "Users can only access their own study data" ON study_sessions
FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "Users can only access their own study records" ON study_records
FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "Users can only access their own error reports" ON error_reports
FOR ALL USING (auth.uid() = user_id);
CREATE POLICY "Users can only access their own stats" ON daily_stats
FOR ALL USING (auth.uid() = user_id);
```
## 3. API 設計規格
### 3.1 認證系統 API
#### 3.1.1 基於 Supabase Auth
```typescript
// /app/api/auth/* 使用 Supabase Auth SDK
// 無需自建API前端直接使用 Supabase 客戶端
// 需要的API: 用戶資料更新
PUT /api/users/profile
{
display_name?: string;
preferences?: Record<string, any>;
}
```
### 3.2 詞卡管理 API
#### 3.2.1 卡組管理
```typescript
// 獲取用戶所有卡組 (支援 /app/dashboard/page.tsx)
GET /api/card-sets
Response: {
sets: Array<{
id: string;
name: string;
description: string;
color: string;
card_count: number;
progress: number; // 計算得出
last_studied: string;
tags: string[];
}>
}
// 創建卡組
POST /api/card-sets
Body: {
name: string;
description?: string;
color?: string;
}
// 更新卡組
PUT /api/card-sets/:id
Body: {
name?: string;
description?: string;
color?: string;
}
// 刪除卡組
DELETE /api/card-sets/:id
```
#### 3.2.2 詞卡 CRUD (支援 /app/flashcards/page.tsx)
```typescript
// 獲取詞卡列表
GET /api/flashcards
Query: {
set_id?: string;
search?: string;
tags?: string[];
difficulty?: string;
favorites_only?: boolean;
limit?: number;
offset?: number;
}
Response: {
flashcards: Array<FlashcardType>;
total: number;
has_more: boolean;
}
// 創建詞卡
POST /api/flashcards
Body: {
card_set_id: string;
word: string;
translation: string;
definition: string;
// ... 其他欄位
}
// 更新詞卡
PUT /api/flashcards/:id
Body: Partial<FlashcardType>
// 刪除詞卡
DELETE /api/flashcards/:id
// 批量操作
POST /api/flashcards/batch
Body: {
action: 'delete' | 'move' | 'tag' | 'reset_progress';
flashcard_ids: string[];
target_set_id?: string; // for move
tag_ids?: string[]; // for tag
}
```
#### 3.2.3 標籤管理
```typescript
// 獲取標籤
GET /api/tags
Response: {
tags: Array<{
id: string;
name: string;
color: string;
usage_count: number;
}>
}
// 創建標籤
POST /api/tags
Body: {
name: string;
color?: string;
}
// 詞卡標籤關聯
POST /api/flashcards/:id/tags
Body: {
tag_ids: string[];
}
```
### 3.3 AI 生成 API (支援 /app/generate/page.tsx)
#### 3.3.1 生成任務管理
```typescript
// 創建生成任務
POST /api/ai/generate
Body: {
input_text: string;
extraction_type: 'vocabulary' | 'smart';
card_count: number; // 5-20
}
Response: {
task_id: string;
status: 'pending';
}
// 查詢生成進度
GET /api/ai/generate/:task_id
Response: {
task_id: string;
status: 'pending' | 'processing' | 'completed' | 'failed';
progress_percentage: number;
generated_cards?: Array<GeneratedCardType>;
error_message?: string;
}
// 保存生成的詞卡
POST /api/ai/generate/:task_id/save
Body: {
card_set_id: string;
selected_cards: string[]; // 生成卡片的ID
}
```
#### 3.3.2 智能檢測 API (支援詞卡錯誤檢測)
```typescript
// 檢測單一詞卡
POST /api/ai/validate-card
Body: {
flashcard_id: string;
error_report_id?: string; // 如果來自錯誤回報
}
Response: {
issues: Array<{
field: string;
original: string;
corrected: string;
reason: string;
}>;
suggestions: string[];
}
// 批量檢測
POST /api/ai/validate-cards
Body: {
flashcard_ids: string[];
}
Response: {
results: Array<{
flashcard_id: string;
issues: Array<ValidationIssue>;
}>;
}
// 應用修正
POST /api/ai/apply-corrections
Body: {
flashcard_id: string;
corrections: Array<{
field: string;
new_value: string;
}>;
}
```
### 3.4 學習系統 API (支援 /app/learn/page.tsx)
#### 3.4.1 學習會話管理
```typescript
// 獲取待複習詞卡
GET /api/study/due-cards
Query: {
limit?: number; // 預設50
mode?: 'flip' | 'quiz' | 'fill' | 'listening' | 'speaking';
}
Response: {
cards: Array<FlashcardType>;
total_due: number;
}
// 開始學習會話
POST /api/study/sessions
Body: {
mode: string;
card_ids: string[];
}
Response: {
session_id: string;
cards: Array<FlashcardType>;
}
// 記錄學習結果
POST /api/study/sessions/:session_id/record
Body: {
flashcard_id: string;
rating: number; // 1-5
response_time_ms: number;
user_answer?: string;
is_correct: boolean;
}
Response: {
next_review_date: string;
new_interval_days: number;
}
// 結束學習會話
POST /api/study/sessions/:session_id/complete
Body: {
duration_seconds: number;
}
```
#### 3.4.2 錯誤回報 API
```typescript
// 提交錯誤回報
POST /api/error-reports
Body: {
flashcard_id: string;
report_type: string;
description?: string;
study_mode: string;
}
// 獲取錯誤回報列表
GET /api/error-reports
Query: {
status?: 'pending' | 'resolved' | 'dismissed';
limit?: number;
offset?: number;
}
Response: {
reports: Array<{
id: string;
flashcard: FlashcardType;
report_type: string;
description: string;
status: string;
created_at: string;
}>;
total: number;
}
// 處理錯誤回報
PUT /api/error-reports/:id
Body: {
status: 'resolved' | 'dismissed';
admin_notes?: string;
}
```
### 3.5 統計分析 API (支援 /app/dashboard/page.tsx)
#### 3.5.1 儀表板統計
```typescript
// 獲取儀表板概覽
GET /api/stats/dashboard
Response: {
total_words: number;
words_today: number;
streak_days: number;
accuracy_percentage: number;
today_review_count: number;
completed_today: number;
recent_words: Array<{
word: string;
translation: string;
status: 'learned' | 'learning' | 'new';
}>;
}
// 獲取學習趨勢
GET /api/stats/trends
Query: {
period: 'week' | 'month' | 'year';
}
Response: {
daily_counts: Array<{
date: string;
words_studied: number;
words_correct: number;
study_time_seconds: number;
}>;
weekly_stats: {
current_week: number;
previous_week: number;
growth_percentage: number;
};
}
// 獲取詳細統計
GET /api/stats/detailed
Response: {
by_difficulty: Record<string, number>;
by_category: Record<string, number>;
learning_curve: Array<{
date: string;
accuracy: number;
}>;
top_mistakes: Array<{
word: string;
error_count: number;
}>;
}
```
### 3.6 用戶設定 API
```typescript
// 獲取用戶設定
GET /api/users/settings
Response: UserSettingsType
// 更新用戶設定
PUT /api/users/settings
Body: Partial<UserSettingsType>
// 獲取使用配額
GET /api/users/usage
Response: {
current_month: {
ai_generations: number;
ai_generations_limit: number;
cards_generated: number;
};
subscription: {
type: 'free' | 'premium';
expires_at?: string;
features: string[];
};
}
```
## 4. AI 服務整合
### 4.1 Google Gemini API 整合
#### 4.1.1 詞卡生成服務
```typescript
// /lib/ai/gemini-generator.ts
export class GeminiCardGenerator {
async generateCards(params: {
inputText: string;
extractionType: 'vocabulary' | 'smart';
cardCount: number;
userLevel?: string;
}): Promise<GeneratedCard[]> {
// 實作 Gemini API 調用
// 使用不同的 prompt 模板
// 處理 API 回應和錯誤
}
async validateCard(card: FlashcardType): Promise<ValidationResult> {
// 智能檢測詞卡內容
// 返回修正建議
}
}
```
#### 4.1.2 Prompt 模板設計
```typescript
// /lib/ai/prompts.ts
export const CARD_GENERATION_PROMPTS = {
vocabulary: `
從以下英文文本中萃取重要詞彙,為每個詞彙生成詞卡:
輸入文本:{input_text}
目標數量:{card_count}
請按照以下JSON格式回應
{
"cards": [
{
"word": "string",
"part_of_speech": "string",
"pronunciation_us": "string",
"pronunciation_uk": "string",
"translation": "string",
"definition": "string (A1-A2 level)",
"synonyms": ["string"],
"antonyms": ["string"],
"difficulty_level": "A1|A2|B1|B2|C1|C2",
"generated_example": "string",
"generated_example_translation": "string"
}
]
}
`,
smart: `
分析以下英文文本,識別片語、俚語和常用表達:
輸入文本:{input_text}
目標數量:{card_count}
重點關注:
1. 片語和俚語
2. 文化相關表達
3. 語境特定用法
請按照相同JSON格式回應...
`,
validation: `
檢查以下詞卡內容的準確性:
詞卡信息:{card_data}
錯誤回報:{error_report}
請指出任何錯誤並提供修正建議:
{
"issues": [
{
"field": "string",
"original": "string",
"corrected": "string",
"reason": "string"
}
],
"suggestions": ["string"]
}
`
};
```
### 4.2 API 配額管理
```typescript
// /lib/ai/quota-manager.ts
export class APIQuotaManager {
async checkQuota(userId: string): Promise<{
canGenerate: boolean;
remaining: number;
resetTime: Date;
}> {
// 檢查用戶配額
}
async consumeQuota(userId: string, cost: number): Promise<void> {
// 消耗配額
}
}
```
## 5. SM-2 間隔重複算法實現
### 5.1 算法實現
```typescript
// /lib/learning/sm2-algorithm.ts
export interface SM2Result {
easiness_factor: number;
repetitions: number;
interval_days: number;
next_review_date: Date;
}
export class SM2Algorithm {
calculate(params: {
quality: number; // 1-5 評分
easiness_factor: number;
repetitions: number;
interval_days: number;
}): SM2Result {
let { quality, easiness_factor, repetitions, interval_days } = params;
// SM-2 算法實現
if (quality >= 3) {
if (repetitions === 0) {
interval_days = 1;
} else if (repetitions === 1) {
interval_days = 6;
} else {
interval_days = Math.round(interval_days * easiness_factor);
}
repetitions += 1;
} else {
repetitions = 0;
interval_days = 1;
}
// 更新難度係數
easiness_factor = Math.max(1.3,
easiness_factor + (0.1 - (5 - quality) * (0.08 + (5 - quality) * 0.02))
);
// 計算下次複習日期
const next_review_date = new Date();
next_review_date.setDate(next_review_date.getDate() + interval_days);
return {
easiness_factor,
repetitions,
interval_days,
next_review_date
};
}
}
```
### 5.2 複習排程服務
```typescript
// /lib/learning/review-scheduler.ts
export class ReviewScheduler {
async getDueCards(userId: string, limit: number = 50): Promise<FlashcardType[]> {
// 獲取到期詞卡
// 按優先級排序
}
async scheduleReview(flashcardId: string, result: SM2Result): Promise<void> {
// 更新詞卡複習排程
}
}
```
## 6. 錯誤處理與日誌
### 6.1 統一錯誤處理
```typescript
// /lib/api/error-handler.ts
export interface APIError {
code: string;
message: string;
details?: any;
timestamp: Date;
}
export const errorCodes = {
// 認證錯誤
UNAUTHORIZED: 'AUTH_001',
INVALID_TOKEN: 'AUTH_002',
// 資源錯誤
NOT_FOUND: 'RESOURCE_001',
ALREADY_EXISTS: 'RESOURCE_002',
// AI服務錯誤
AI_QUOTA_EXCEEDED: 'AI_001',
AI_SERVICE_ERROR: 'AI_002',
// 驗證錯誤
VALIDATION_ERROR: 'VALIDATION_001',
// 系統錯誤
INTERNAL_ERROR: 'SYSTEM_001',
DATABASE_ERROR: 'SYSTEM_002'
};
export function handleAPIError(error: unknown): Response {
// 統一錯誤處理邏輯
}
```
### 6.2 結構化日誌
```typescript
// /lib/logging/logger.ts
export class Logger {
static info(message: string, metadata?: Record<string, any>) {
console.log(JSON.stringify({
level: 'info',
message,
metadata,
timestamp: new Date().toISOString()
}));
}
static error(message: string, error?: Error, metadata?: Record<string, any>) {
console.error(JSON.stringify({
level: 'error',
message,
error: error?.stack,
metadata,
timestamp: new Date().toISOString()
}));
}
}
```
## 7. 快取策略
### 7.1 前端快取 (TanStack Query)
```typescript
// 前端查詢配置
export const queryKeys = {
flashcards: (userId: string, filters?: any) => ['flashcards', userId, filters],
cardSets: (userId: string) => ['card-sets', userId],
dueCards: (userId: string) => ['due-cards', userId],
stats: (userId: string, period?: string) => ['stats', userId, period]
};
// 快取時間配置
export const cacheConfig = {
flashcards: 5 * 60 * 1000, // 5分鐘
cardSets: 10 * 60 * 1000, // 10分鐘
dueCards: 1 * 60 * 1000, // 1分鐘
stats: 15 * 60 * 1000 // 15分鐘
};
```
### 7.2 API層快取
```typescript
// /lib/cache/redis-cache.ts (未來考慮)
export class CacheManager {
async get<T>(key: string): Promise<T | null> {
// Redis 快取獲取
}
async set<T>(key: string, value: T, ttl: number): Promise<void> {
// Redis 快取設置
}
async invalidate(pattern: string): Promise<void> {
// 快取失效
}
}
```
## 8. 安全措施
### 8.1 Rate Limiting
```typescript
// /lib/security/rate-limiter.ts
export class RateLimiter {
// API 限流配置
static limits = {
'api/ai/generate': { requests: 10, window: 60 * 60 }, // 每小時10次
'api/flashcards': { requests: 100, window: 60 }, // 每分鐘100次
'api/study/record': { requests: 200, window: 60 } // 每分鐘200次
};
}
```
### 8.2 輸入驗證
```typescript
// /lib/validation/schemas.ts
import { z } from 'zod';
export const flashcardSchema = z.object({
word: z.string().min(1).max(255),
translation: z.string().min(1),
definition: z.string().min(1),
card_set_id: z.string().uuid(),
difficulty_level: z.enum(['A1', 'A2', 'B1', 'B2', 'C1', 'C2']).optional()
});
export const aiGenerationSchema = z.object({
input_text: z.string().min(10).max(5000),
extraction_type: z.enum(['vocabulary', 'smart']),
card_count: z.number().min(5).max(20)
});
```
## 9. 測試策略
### 9.1 API 測試
```typescript
// __tests__/api/flashcards.test.ts
describe('/api/flashcards', () => {
it('should create flashcard with valid data', async () => {
// 測試詞卡創建
});
it('should return 401 for unauthenticated requests', async () => {
// 測試認證
});
it('should validate input data', async () => {
// 測試輸入驗證
});
});
```
### 9.2 AI 服務測試
```typescript
// __tests__/lib/ai/gemini-generator.test.ts
describe('GeminiCardGenerator', () => {
it('should generate valid flashcards from text', async () => {
// 測試AI生成
});
it('should handle API errors gracefully', async () => {
// 測試錯誤處理
});
});
```
## 10. 部署配置
### 10.1 環境變數配置
```env
# Supabase
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key
# AI 服務
GEMINI_API_KEY=your_gemini_api_key
# 應用設定
NEXT_PUBLIC_APP_URL=https://your-domain.com
NODE_ENV=production
# 可選Redis (Upstash)
REDIS_URL=your_redis_url
REDIS_TOKEN=your_redis_token
```
### 10.2 Vercel 部署設定
```json
// vercel.json
{
"functions": {
"app/api/**": {
"maxDuration": 30
}
},
"env": {
"NODE_ENV": "production"
}
}
```
## 11. 開發階段規劃 (.NET Core 重寫版)
### ⚡ **重寫完成狀態**
**原 Next.js API Routes**: 已完全移除 ✅
**新 .NET Core API**: 開發中 🚀
### Phase 1: .NET Core 基礎建設 (第1週)
- [x] 清理 Next.js API 代碼
- [ ] 安裝 .NET 8 SDK
- [ ] 建立 ASP.NET Core Web API 專案
- [ ] Entity Framework Core 配置
- [ ] 基礎 CRUD API (卡組、詞卡)
### Phase 2: 核心業務邏輯 (第2週)
- [ ] SM-2 算法 C# 實現
- [ ] 學習系統 API (會話管理、記錄)
- [ ] JWT 認證系統
- [ ] 統一錯誤處理和驗證
### Phase 3: AI 和進階功能 (第3週)
- [ ] Google Gemini AI 服務整合
- [ ] 智能檢測和批量操作 API
- [ ] 統計分析系統
- [ ] 錯誤回報系統
### Phase 4: 前端整合和優化 (第4週)
- [ ] 前端 API 調用更新
- [ ] 認證流程調整
- [ ] 性能優化和快取
- [ ] 部署配置 (Azure/Railway)
**架構優勢**:
- 🚀 性能提升 30-50%
- 🛡️ 強型別安全
- 🏢 企業級架構
- 🔧 更好的開發體驗
## 12. API 回應格式標準
### 12.1 成功回應格式
```typescript
interface SuccessResponse<T> {
success: true;
data: T;
message?: string;
meta?: {
total?: number;
page?: number;
limit?: number;
};
}
```
### 12.2 錯誤回應格式
```typescript
interface ErrorResponse {
success: false;
error: {
code: string;
message: string;
details?: any;
};
timestamp: string;
}
```
### 12.3 分頁回應格式
```typescript
interface PaginatedResponse<T> {
success: true;
data: T[];
pagination: {
total: number;
page: number;
limit: number;
total_pages: number;
has_next: boolean;
has_prev: boolean;
};
}
```
## 13. 監控與維護
### 13.1 關鍵指標監控
- API 回應時間 (< 500ms 目標)
- 錯誤率 (< 1% 目標)
- AI API 配額使用率
- 資料庫連接池狀態
- 用戶活躍度
### 13.2 警報設定
- API 錯誤率超過 5%
- 回應時間超過 2
- AI API 配額使用超過 80%
- 資料庫連接數超過閾值
### 13.3 備份策略
- 每日自動資料庫備份
- 用戶數據導出功能
- 災難恢復計劃
這個後端開發計劃完全基於已實作的前端功能確保 API 能夠支援所有前端頁面的需求包括儀表板統計詞卡管理學習系統AI 生成和錯誤回報等核心功能