# 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; } ``` ### 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; 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 // 刪除詞卡 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; 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; }>; } // 應用修正 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; total_due: number; } // 開始學習會話 POST /api/study/sessions Body: { mode: string; card_ids: string[]; } Response: { session_id: string; cards: Array; } // 記錄學習結果 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; by_category: Record; 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 // 獲取使用配額 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 { // 實作 Gemini API 調用 // 使用不同的 prompt 模板 // 處理 API 回應和錯誤 } async validateCard(card: FlashcardType): Promise { // 智能檢測詞卡內容 // 返回修正建議 } } ``` #### 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 { // 消耗配額 } } ``` ## 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 { // 獲取到期詞卡 // 按優先級排序 } async scheduleReview(flashcardId: string, result: SM2Result): Promise { // 更新詞卡複習排程 } } ``` ## 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) { console.log(JSON.stringify({ level: 'info', message, metadata, timestamp: new Date().toISOString() })); } static error(message: string, error?: Error, metadata?: Record) { 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(key: string): Promise { // Redis 快取獲取 } async set(key: string, value: T, ttl: number): Promise { // Redis 快取設置 } async invalidate(pattern: string): Promise { // 快取失效 } } ``` ## 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 { 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 { 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 生成和錯誤回報等核心功能。