diff --git a/README-DATABASE-FAILOVER.md b/README-DATABASE-FAILOVER.md
deleted file mode 100644
index 16fac26..0000000
--- a/README-DATABASE-FAILOVER.md
+++ /dev/null
@@ -1,275 +0,0 @@
-# 資料庫備援系統說明
-
-## 概述
-
-本系統實現了主機和備機資料庫的自動備援機制,當主機資料庫出現問題時,系統會自動切換到備機資料庫,確保服務的連續性和穩定性。
-
-## 功能特點
-
-- ✅ 自動故障檢測和切換
-- ✅ 健康檢查機制
-- ✅ 手動切換功能
-- ✅ 資料同步功能
-- ✅ 監控面板
-- ✅ 連接池管理
-- ✅ 重試機制
-
-## 環境變數配置
-
-在 `.env` 文件中添加以下配置:
-
-```env
-# ===== 主機資料庫配置 =====
-DB_HOST=mysql.theaken.com
-DB_PORT=33306
-DB_NAME=db_AI_Platform
-DB_USER=AI_Platform
-DB_PASSWORD=Aa123456
-
-# ===== 備機資料庫配置 =====
-SLAVE_DB_HOST=122.100.99.161
-SLAVE_DB_PORT=43306
-SLAVE_DB_NAME=db_nighttime_care_record
-SLAVE_DB_USER=A999
-SLAVE_DB_PASSWORD=1023
-
-# ===== 資料庫備援配置 =====
-DB_FAILOVER_ENABLED=true
-DB_HEALTH_CHECK_INTERVAL=30000
-DB_CONNECTION_TIMEOUT=5000
-DB_RETRY_ATTEMPTS=3
-DB_RETRY_DELAY=2000
-```
-
-## 初始化步驟
-
-### 1. 初始化備機資料庫
-
-首先在備機上創建資料庫結構:
-
-```bash
-# 初始化備機資料庫結構
-pnpm run db:init-slave
-```
-
-### 2. 同步資料
-
-將主機的資料同步到備機:
-
-```bash
-# 同步所有資料
-pnpm run db:sync
-```
-
-### 3. 檢查健康狀態
-
-檢查主機和備機的連接狀態:
-
-```bash
-# 檢查資料庫健康狀態
-pnpm run db:health
-```
-
-## 使用方法
-
-### 程式碼中使用
-
-系統會自動使用備援功能,無需修改現有程式碼:
-
-```typescript
-import { db } from '@/lib/database';
-
-// 查詢資料
-const users = await db.query('SELECT * FROM users');
-
-// 插入資料
-await db.insert('INSERT INTO users (name, email) VALUES (?, ?)', ['John', 'john@example.com']);
-
-// 獲取備援狀態
-const status = db.getFailoverStatus();
-console.log('當前使用資料庫:', status?.currentDatabase);
-
-// 手動切換資料庫
-await db.switchDatabase('slave'); // 切換到備機
-await db.switchDatabase('master'); // 切換到主機
-```
-
-### 監控面板
-
-訪問管理後台查看資料庫狀態:
-
-```typescript
-import { DatabaseMonitor } from '@/components/admin/database-monitor';
-
-// 在管理頁面中使用
-
-```
-
-### API 端點
-
-#### 獲取資料庫狀態
-
-```http
-GET /api/admin/database-status
-```
-
-回應:
-```json
-{
- "success": true,
- "data": {
- "isEnabled": true,
- "currentDatabase": "master",
- "masterHealthy": true,
- "slaveHealthy": true,
- "lastHealthCheck": "2024-01-01T12:00:00.000Z",
- "consecutiveFailures": 0,
- "uptime": 3600,
- "timestamp": "2024-01-01T12:00:00.000Z"
- }
-}
-```
-
-#### 切換資料庫
-
-```http
-POST /api/admin/database-status
-Content-Type: application/json
-
-{
- "action": "switch",
- "database": "slave"
-}
-```
-
-## 腳本命令
-
-| 命令 | 說明 |
-|------|------|
-| `pnpm run db:init-slave` | 初始化備機資料庫結構 |
-| `pnpm run db:sync` | 同步主機資料到備機 |
-| `pnpm run db:health` | 檢查資料庫健康狀態 |
-| `pnpm run db:monitor` | 執行健康檢查並顯示結果 |
-
-## 故障處理
-
-### 自動切換
-
-當主機資料庫出現以下問題時,系統會自動切換到備機:
-
-- 連接超時
-- 連接重置
-- 協議錯誤
-- 其他連接相關錯誤
-
-### 手動切換
-
-如果需要手動切換資料庫:
-
-1. 通過監控面板切換
-2. 通過 API 切換
-3. 通過程式碼切換
-
-### 故障恢復
-
-當主機資料庫恢復後:
-
-1. 系統會自動檢測到主機恢復
-2. 可以手動切換回主機
-3. 建議重新同步資料
-
-## 監控和日誌
-
-### 健康檢查
-
-- 每 30 秒自動檢查一次
-- 檢查連接狀態和響應時間
-- 記錄連續失敗次數
-
-### 日誌記錄
-
-系統會記錄以下事件:
-
-- 資料庫切換事件
-- 連接失敗事件
-- 健康檢查結果
-- 同步操作結果
-
-### 監控指標
-
-- 當前使用的資料庫
-- 主機和備機的健康狀態
-- 最後檢查時間
-- 連續失敗次數
-- 系統運行時間
-
-## 注意事項
-
-1. **資料一致性**:備機資料可能不是實時同步的,建議定期同步
-2. **性能影響**:備援機制會增加少量性能開銷
-3. **網路依賴**:需要確保主機和備機之間的網路連接穩定
-4. **權限配置**:確保備機資料庫有足夠的權限進行操作
-
-## 故障排除
-
-### 常見問題
-
-1. **備機連接失敗**
- - 檢查網路連接
- - 驗證資料庫配置
- - 確認用戶權限
-
-2. **同步失敗**
- - 檢查表結構是否一致
- - 確認資料庫權限
- - 查看錯誤日誌
-
-3. **自動切換不工作**
- - 確認 `DB_FAILOVER_ENABLED=true`
- - 檢查健康檢查間隔設定
- - 查看系統日誌
-
-### 日誌位置
-
-- 應用程式日誌:控制台輸出
-- 資料庫日誌:MySQL 錯誤日誌
-- 系統日誌:系統日誌文件
-
-## 最佳實踐
-
-1. **定期備份**:即使有備援機制,仍建議定期備份資料
-2. **監控告警**:設定監控告警,及時發現問題
-3. **測試切換**:定期測試備援切換功能
-4. **性能監控**:監控資料庫性能指標
-5. **文檔更新**:保持配置文檔的更新
-
-## 技術架構
-
-```
-┌─────────────────┐ ┌─────────────────┐
-│ 應用程式 │ │ 應用程式 │
-└─────────┬───────┘ └─────────┬───────┘
- │ │
- ▼ ▼
-┌─────────────────┐ ┌─────────────────┐
-│ 資料庫服務 │ │ 備援服務 │
-│ (主機) │ │ (備機) │
-└─────────────────┘ └─────────────────┘
- │ │
- ▼ ▼
-┌─────────────────┐ ┌─────────────────┐
-│ MySQL 主機 │ │ MySQL 備機 │
-│ mysql.theaken │ │ 122.100.99.161│
-│ .com:33306 │ │ :43306 │
-└─────────────────┘ └─────────────────┘
-```
-
-## 支援
-
-如有問題,請檢查:
-
-1. 環境變數配置
-2. 網路連接狀態
-3. 資料庫服務狀態
-4. 系統日誌
-5. 監控面板狀態
diff --git a/README-DATABASE.md b/README-DATABASE.md
deleted file mode 100644
index 9d0adc4..0000000
--- a/README-DATABASE.md
+++ /dev/null
@@ -1,222 +0,0 @@
-# AI 展示平台資料庫設計
-
-## 📊 資料庫概述
-
-本專案使用 **MySQL** 作為主要資料庫,設計了完整的資料表結構來支持 AI 展示平台的所有功能。
-
-### 🔗 資料庫連接資訊
-
-- **主機**: `mysql.theaken.com`
-- **端口**: `33306`
-- **資料庫名**: `db_AI_Platform`
-- **用戶名**: `AI_Platform`
-- **密碼**: `Aa123456`
-
-## 🏗️ 資料表結構
-
-### 核心業務表
-
-#### 1. 用戶管理
-- **users** - 用戶基本資訊
-- **user_favorites** - 用戶收藏應用
-- **user_likes** - 用戶按讚記錄
-- **user_views** - 用戶瀏覽記錄
-- **user_ratings** - 用戶評分記錄
-
-#### 2. 競賽系統
-- **competitions** - 競賽基本資訊
-- **competition_rules** - 競賽規則
-- **competition_award_types** - 競賽獎項類型
-- **competition_judges** - 競賽評審關聯
-- **competition_apps** - 競賽參與應用
-- **competition_teams** - 競賽參與團隊
-- **competition_proposals** - 競賽參與提案
-
-#### 3. 評審系統
-- **judges** - 評審基本資訊
-- **app_judge_scores** - 應用評分記錄
-- **proposal_judge_scores** - 提案評分記錄
-
-#### 4. 團隊管理
-- **teams** - 團隊基本資訊
-- **team_members** - 團隊成員關聯
-
-#### 5. 應用管理
-- **apps** - AI 應用基本資訊
-
-#### 6. 提案管理
-- **proposals** - 提案基本資訊
-
-#### 7. 獎項系統
-- **awards** - 獎項記錄
-
-#### 8. AI 助手
-- **chat_sessions** - 聊天會話
-- **chat_messages** - 聊天訊息
-- **ai_assistant_configs** - AI 助手配置
-
-#### 9. 系統管理
-- **system_settings** - 系統設定
-- **activity_logs** - 活動日誌
-
-## 📈 統計視圖
-
-### 1. user_statistics
-用戶統計視圖,包含:
-- 基本資訊
-- 收藏數量
-- 按讚數量
-- 瀏覽數量
-- 平均評分
-- 團隊參與情況
-
-### 2. app_statistics
-應用統計視圖,包含:
-- 基本資訊
-- 創作者資訊
-- 團隊資訊
-- 用戶互動統計
-- 評審評分統計
-
-### 3. competition_statistics
-競賽統計視圖,包含:
-- 基本資訊
-- 評審數量
-- 參與應用數量
-- 參與團隊數量
-- 參與提案數量
-- 獎項數量
-
-## ⚙️ 觸發器
-
-### 1. 自動計算總分
-- **calculate_app_total_score** - 應用評分總分計算
-- **calculate_proposal_total_score** - 提案評分總分計算
-
-## 🚀 快速開始
-
-### 1. 安裝依賴
-
-```bash
-npm install
-```
-
-### 2. 設置環境變數
-
-複製 `env.example` 到 `.env.local` 並填入正確的資料庫資訊:
-
-```bash
-cp env.example .env.local
-```
-
-### 3. 執行資料庫遷移
-
-```bash
-# 創建資料庫結構
-npm run migrate
-
-# 重置資料庫(慎用)
-npm run migrate:reset
-```
-
-### 4. 驗證安裝
-
-遷移完成後,您應該看到:
-- 25 個資料表
-- 3 個統計視圖
-- 4 個觸發器
-- 初始系統設定數據
-
-## 🔧 資料庫服務
-
-### 使用方式
-
-```typescript
-import { UserService, CompetitionService, AppService } from '@/lib/services/database-service';
-
-// 創建用戶
-const user = await UserService.createUser({
- name: '張三',
- email: 'zhang@example.com',
- password_hash: 'hashed_password',
- department: 'IT部門',
- role: 'developer',
- join_date: '2024-01-01',
- total_likes: 0,
- total_views: 0,
- is_active: true
-});
-
-// 獲取用戶統計
-const stats = await UserService.getUserStatistics(user.id);
-
-// 創建競賽
-const competition = await CompetitionService.createCompetition({
- name: '2024年AI創新競賽',
- year: 2024,
- month: 3,
- start_date: '2024-03-01',
- end_date: '2024-03-31',
- status: 'upcoming',
- type: 'individual',
- is_active: true
-});
-```
-
-## 📋 資料表關係圖
-
-```
-users (1) ←→ (N) team_members (N) ←→ (1) teams
-users (1) ←→ (N) apps
-users (1) ←→ (N) user_favorites
-users (1) ←→ (N) user_likes
-users (1) ←→ (N) user_views
-users (1) ←→ (N) user_ratings
-
-competitions (1) ←→ (N) competition_judges (N) ←→ (1) judges
-competitions (1) ←→ (N) competition_apps (N) ←→ (1) apps
-competitions (1) ←→ (N) competition_teams (N) ←→ (1) teams
-competitions (1) ←→ (N) competition_proposals (N) ←→ (1) proposals
-competitions (1) ←→ (N) awards
-
-judges (1) ←→ (N) app_judge_scores (N) ←→ (1) apps
-judges (1) ←→ (N) proposal_judge_scores (N) ←→ (1) proposals
-
-teams (1) ←→ (N) proposals
-teams (1) ←→ (N) apps
-```
-
-## 🛠️ 維護命令
-
-### 備份資料庫
-```bash
-mysqldump -h mysql.theaken.com -P 33306 -u AI_Platform -p db_AI_Platform > backup.sql
-```
-
-### 恢復資料庫
-```bash
-mysql -h mysql.theaken.com -P 33306 -u AI_Platform -p db_AI_Platform < backup.sql
-```
-
-### 檢查資料庫狀態
-```bash
-mysql -h mysql.theaken.com -P 33306 -u AI_Platform -p -e "SHOW TABLES;" db_AI_Platform
-```
-
-## 🔍 常見問題
-
-### Q: 如何重置資料庫?
-A: 執行 `npm run migrate:reset` 命令,這會刪除所有表並重新創建。
-
-### Q: 如何添加新的資料表?
-A: 在 `database-schema.sql` 中添加新的 CREATE TABLE 語句,然後執行 `npm run migrate`。
-
-### Q: 如何修改現有表結構?
-A: 使用 ALTER TABLE 語句,或者創建新的遷移腳本。
-
-### Q: 資料庫連接失敗怎麼辦?
-A: 檢查環境變數設置,確保資料庫服務正在運行,並且網路連接正常。
-
-## 📞 技術支援
-
-如有任何資料庫相關問題,請聯繫技術團隊或查看專案文檔。
diff --git a/README-DUAL-WRITE-SYNC.md b/README-DUAL-WRITE-SYNC.md
deleted file mode 100644
index d3b4a4d..0000000
--- a/README-DUAL-WRITE-SYNC.md
+++ /dev/null
@@ -1,237 +0,0 @@
-# 資料庫雙寫同步系統說明
-
-## 🎯 系統概述
-
-本系統實現了主機和備機資料庫的雙寫同步機制,確保所有新增、刪除、修改的資料都能同時寫入主機和備機資料庫,實現真正的資料同步。
-
-## ✅ 主要功能
-
-- ✅ **雙寫同步** - 所有寫入操作同時寫入主機和備機
-- ✅ **自動故障檢測** - 每30秒檢查資料庫健康狀態
-- ✅ **自動切換** - 主機故障時自動切換到備機
-- ✅ **手動切換** - 支援手動切換資料庫
-- ✅ **資料同步** - 可將主機資料同步到備機
-- ✅ **監控面板** - 實時監控資料庫狀態
-- ✅ **健康檢查** - 定期檢查連接狀態
-
-## 🚀 快速開始
-
-### 1. 環境變數配置
-
-在您的 `.env` 文件中添加以下配置:
-
-```env
-# ===== 主機資料庫配置 =====
-DB_HOST=mysql.theaken.com
-DB_PORT=33306
-DB_NAME=db_AI_Platform
-DB_USER=AI_Platform
-DB_PASSWORD=Aa123456
-
-# ===== 備機資料庫配置 =====
-SLAVE_DB_HOST=122.100.99.161
-SLAVE_DB_PORT=43306
-SLAVE_DB_NAME=db_AI_Platform
-SLAVE_DB_USER=A999
-SLAVE_DB_PASSWORD=1023
-
-# ===== 資料庫備援配置 =====
-DB_FAILOVER_ENABLED=true
-
-# ===== 資料庫雙寫同步配置 =====
-DB_DUAL_WRITE_ENABLED=true
-DB_MASTER_PRIORITY=true
-DB_CONFLICT_RESOLUTION=master
-DB_HEALTH_CHECK_INTERVAL=30000
-DB_CONNECTION_TIMEOUT=5000
-DB_RETRY_ATTEMPTS=3
-DB_RETRY_DELAY=2000
-```
-
-### 2. 初始化備機資料庫
-
-```bash
-# 初始化備機資料庫結構
-pnpm run db:init-slave
-
-# 同步主機資料到備機
-pnpm run db:sync
-```
-
-### 3. 測試雙寫功能
-
-```bash
-# 測試雙寫同步功能
-pnpm run db:test-dual-write
-
-# 檢查資料庫健康狀態
-pnpm run db:health
-```
-
-## 📊 工作原理
-
-### 雙寫流程
-
-1. **寫入請求** - API 接收到寫入請求
-2. **雙寫執行** - 同時寫入主機和備機資料庫
-3. **結果處理** - 根據寫入結果決定回應
-4. **錯誤處理** - 如果其中一個失敗,記錄錯誤但繼續服務
-
-### 同步策略
-
-- **主機優先** - 如果主機和備機都成功,優先返回主機結果
-- **備機備援** - 如果主機失敗但備機成功,使用備機結果
-- **錯誤處理** - 如果兩者都失敗,拋出錯誤
-
-## 🔧 程式碼使用
-
-### 基本使用
-
-系統會自動使用雙寫功能,無需修改現有程式碼:
-
-```typescript
-import { db } from '@/lib/database';
-
-// 插入資料 (自動雙寫)
-await db.insert('INSERT INTO users (name, email) VALUES (?, ?)', ['John', 'john@example.com']);
-
-// 更新資料 (自動雙寫)
-await db.update('UPDATE users SET name = ? WHERE id = ?', ['Jane', 'user-id']);
-
-// 刪除資料 (自動雙寫)
-await db.delete('DELETE FROM users WHERE id = ?', ['user-id']);
-
-// 查詢資料 (自動使用備援)
-const users = await db.query('SELECT * FROM users');
-```
-
-### 監控同步狀態
-
-```typescript
-import { dbSync } from '@/lib/database-sync';
-
-// 獲取同步狀態
-const status = await dbSync.getSyncStatus();
-console.log('同步狀態:', status);
-
-// 手動同步表
-await dbSync.syncFromMasterToSlave('users');
-```
-
-### 獲取備援狀態
-
-```typescript
-import { db } from '@/lib/database';
-
-// 獲取當前資料庫狀態
-const status = db.getFailoverStatus();
-console.log('當前使用資料庫:', status?.currentDatabase);
-console.log('主機健康狀態:', status?.masterHealthy);
-console.log('備機健康狀態:', status?.slaveHealthy);
-```
-
-## 📈 監控和管理
-
-### 可用命令
-
-| 命令 | 功能 | 狀態 |
-|------|------|------|
-| `pnpm run db:health` | 檢查資料庫健康狀態 | ✅ 可用 |
-| `pnpm run db:test-dual-write` | 測試雙寫同步功能 | ✅ 可用 |
-| `pnpm run db:init-slave` | 初始化備機資料庫 | ✅ 可用 |
-| `pnpm run db:sync` | 同步資料 | ✅ 可用 |
-| `pnpm run db:monitor` | 監控資料庫狀態 | ✅ 可用 |
-
-### 管理頁面
-
-在管理頁面中添加監控組件:
-
-```typescript
-import { DatabaseMonitor } from '@/components/admin/database-monitor';
-
-// 在管理頁面中使用
-
-```
-
-## 🚨 故障處理
-
-### 主機資料庫問題
-
-**問題**: `Too many connections`
-**解決方案**:
-1. 系統已自動切換到備機
-2. 檢查主機資料庫連接數限制
-3. 優化連接池配置
-4. 重啟主機資料庫服務
-
-### 備機資料庫問題
-
-**問題**: 備機連接失敗
-**解決方案**:
-1. 檢查網路連接
-2. 驗證備機資料庫配置
-3. 確認用戶權限
-4. 檢查備機資料庫服務狀態
-
-### 雙寫失敗處理
-
-**問題**: 主機或備機寫入失敗
-**解決方案**:
-1. 檢查錯誤日誌
-2. 驗證資料庫連接狀態
-3. 檢查資料庫結構一致性
-4. 重新執行失敗的操作
-
-## 📋 維護建議
-
-### 定期維護
-
-1. **每日檢查**: 執行 `pnpm run db:health`
-2. **每週測試**: 執行 `pnpm run db:test-dual-write`
-3. **每月同步**: 執行 `pnpm run db:sync`
-
-### 監控指標
-
-- 資料庫連接狀態
-- 雙寫成功率
-- 同步延遲時間
-- 錯誤率統計
-
-## 🔄 恢復主機
-
-當主機資料庫恢復後:
-
-1. 檢查主機狀態: `pnpm run db:health`
-2. 手動切換回主機: `await db.switchDatabase('master')`
-3. 重新同步資料: `pnpm run db:sync`
-
-## 📞 支援
-
-如有問題,請檢查:
-
-1. 環境變數配置
-2. 網路連接狀態
-3. 資料庫服務狀態
-4. 系統日誌
-5. 監控面板狀態
-
-## 🎉 總結
-
-您的資料庫雙寫同步系統已經成功設置並運行!系統現在可以:
-
-- ✅ 自動檢測主機資料庫問題
-- ✅ 自動切換到備機資料庫
-- ✅ 實現真正的雙寫同步
-- ✅ 確保資料一致性
-- ✅ 提供監控和管理功能
-- ✅ 確保服務連續性
-
-即使主機資料庫出現問題,您的應用程式仍然可以正常運行,並且所有資料都會同步到備機!
-
-
-
-
-
-
-
-
diff --git a/README-ENV.md b/README-ENV.md
deleted file mode 100644
index 2f427c2..0000000
--- a/README-ENV.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# 環境變數設定說明
-
-## DeepSeek API 設定
-
-本專案使用 DeepSeek API 作為聊天機器人的 AI 服務。請按照以下步驟設定環境變數:
-
-### 1. 創建環境變數檔案
-
-在專案根目錄創建 `.env.local` 檔案:
-
-```bash
-# DeepSeek API Configuration
-NEXT_PUBLIC_DEEPSEEK_API_KEY=your_deepseek_api_key_here
-NEXT_PUBLIC_DEEPSEEK_API_URL=https://api.deepseek.com/v1/chat/completions
-```
-
-### 2. 取得 DeepSeek API 金鑰
-
-1. 前往 [DeepSeek 官網](https://platform.deepseek.com/)
-2. 註冊或登入帳號
-3. 在控制台中生成 API 金鑰
-4. 將金鑰複製到 `.env.local` 檔案中的 `NEXT_PUBLIC_DEEPSEEK_API_KEY`
-
-### 3. 環境變數說明
-
-- `NEXT_PUBLIC_DEEPSEEK_API_KEY`: DeepSeek API 金鑰
-- `NEXT_PUBLIC_DEEPSEEK_API_URL`: DeepSeek API 端點 URL
-
-### 4. 安全注意事項
-
-- `.env.local` 檔案已加入 `.gitignore`,不會被提交到版本控制
-- 請勿將 API 金鑰分享給他人
-- 在生產環境中,請使用更安全的環境變數管理方式
-
-### 5. 重新啟動開發伺服器
-
-設定完成後,請重新啟動開發伺服器:
-
-```bash
-npm run dev
-# 或
-pnpm dev
-```
-
-### 6. 驗證設定
-
-聊天機器人應該能夠正常運作,並能夠回答用戶問題。
-
-## 故障排除
-
-如果聊天機器人無法運作:
-
-1. 確認 `.env.local` 檔案存在且格式正確
-2. 確認 API 金鑰有效且未過期
-3. 檢查網路連接是否正常
-4. 查看瀏覽器開發者工具中的錯誤訊息
\ No newline at end of file
diff --git a/README-SCORING-BACKEND.md b/README-SCORING-BACKEND.md
deleted file mode 100644
index fc63272..0000000
--- a/README-SCORING-BACKEND.md
+++ /dev/null
@@ -1,195 +0,0 @@
-# 評分機制後端實現文檔
-
-## 概述
-
-本文檔描述了AI展示平台評分機制的後端實現,包括資料庫設計、API端點和前端整合。
-
-## 資料庫設計
-
-### 評分相關表格
-
-1. **app_judge_scores** - 應用評分表
- - 存儲評審對應用的評分記錄
- - 包含創新性、技術性、實用性、展示效果、影響力等評分項目
- - 自動計算總分
-
-2. **proposal_judge_scores** - 提案評分表
- - 存儲評審對提案的評分記錄
- - 包含問題識別、解決方案可行性、創新性、影響力、展示效果等評分項目
- - 自動計算總分
-
-3. **competition_judges** - 競賽評審關聯表
- - 管理競賽與評審的關聯關係
-
-4. **competition_apps** - 競賽應用關聯表
- - 管理競賽與應用的關聯關係
-
-5. **competition_proposals** - 競賽提案關聯表
- - 管理競賽與提案的關聯關係
-
-## API端點
-
-### 1. 評分管理 API (`/api/admin/scoring`)
-
-#### GET - 獲取評分記錄
-```
-GET /api/admin/scoring?competitionId={id}&judgeId={id}&status={status}&search={query}
-```
-
-**參數:**
-- `competitionId` (必需): 競賽ID
-- `judgeId` (可選): 評審ID,用於篩選特定評審的評分
-- `status` (可選): 狀態篩選 (all/completed/pending)
-- `search` (可選): 搜尋關鍵字
-
-**回應:**
-```json
-{
- "success": true,
- "message": "評分記錄獲取成功",
- "data": {
- "scores": [...],
- "stats": {...},
- "total": 10
- }
-}
-```
-
-#### POST - 提交評分
-```
-POST /api/admin/scoring
-```
-
-**請求體:**
-```json
-{
- "judgeId": "judge_id",
- "participantId": "app_id",
- "participantType": "app",
- "scores": {
- "innovation_score": 8,
- "technical_score": 7,
- "usability_score": 9,
- "presentation_score": 8,
- "impact_score": 7
- },
- "comments": "評審意見"
-}
-```
-
-### 2. 評分記錄管理 API (`/api/admin/scoring/[id]`)
-
-#### PUT - 更新評分記錄
-```
-PUT /api/admin/scoring/{id}
-```
-
-#### DELETE - 刪除評分記錄
-```
-DELETE /api/admin/scoring/{id}?type={app|proposal}
-```
-
-### 3. 評分統計 API (`/api/admin/scoring/stats`)
-
-#### GET - 獲取評分統計
-```
-GET /api/admin/scoring/stats?competitionId={id}
-```
-
-**回應:**
-```json
-{
- "success": true,
- "message": "評分統計獲取成功",
- "data": {
- "totalScores": 20,
- "completedScores": 15,
- "pendingScores": 5,
- "completionRate": 75,
- "totalParticipants": 10
- }
-}
-```
-
-## 後端服務
-
-### ScoringService 類別
-
-提供以下主要方法:
-
-1. **submitAppScore()** - 提交應用評分
-2. **submitProposalScore()** - 提交提案評分
-3. **getCompetitionScores()** - 獲取競賽所有評分記錄
-4. **getCompetitionScoreStats()** - 獲取競賽評分統計
-5. **getJudgeScores()** - 獲取評審的評分記錄
-6. **updateAppScore()** - 更新應用評分
-7. **updateProposalScore()** - 更新提案評分
-8. **deleteScore()** - 刪除評分記錄
-
-## 前端整合
-
-### 組件更新
-
-1. **ScoringManagement 組件**
- - 更新 `loadScoringData()` 方法以使用API
- - 更新 `handleSubmitScore()` 方法以提交到後端
- - 添加評分統計功能
-
-2. **CompetitionContext 上下文**
- - 更新 `submitJudgeScore()` 方法以使用API
- - 保持向後兼容性
-
-### 數據流程
-
-1. 用戶選擇競賽
-2. 前端調用 `/api/admin/scoring/stats` 獲取統計數據
-3. 前端調用 `/api/admin/scoring` 獲取評分記錄
-4. 用戶提交評分時調用 POST `/api/admin/scoring`
-5. 後端更新資料庫並返回結果
-6. 前端重新載入數據以顯示最新狀態
-
-## 評分規則
-
-### 應用評分項目
-- 創新性 (innovation_score): 1-10分
-- 技術性 (technical_score): 1-10分
-- 實用性 (usability_score): 1-10分
-- 展示效果 (presentation_score): 1-10分
-- 影響力 (impact_score): 1-10分
-
-### 提案評分項目
-- 問題識別 (problem_identification_score): 1-10分
-- 解決方案可行性 (solution_feasibility_score): 1-10分
-- 創新性 (innovation_score): 1-10分
-- 影響力 (impact_score): 1-10分
-- 展示效果 (presentation_score): 1-10分
-
-### 總分計算
-總分 = (所有評分項目之和) / 評分項目數量
-
-## 測試
-
-### 資料庫測試
-```bash
-node scripts/test-scoring.js
-```
-
-### API測試
-```bash
-node scripts/test-scoring-api.js
-```
-
-## 部署注意事項
-
-1. 確保資料庫表格已創建
-2. 確保觸發器正常工作(自動計算總分)
-3. 檢查API端點權限設置
-4. 驗證前端組件與API的整合
-
-## 未來改進
-
-1. 添加評分權重配置
-2. 實現評分審核流程
-3. 添加評分歷史記錄
-4. 實現批量評分功能
-5. 添加評分導出功能
diff --git a/README-SCORING.md b/README-SCORING.md
deleted file mode 100644
index 4c25e4e..0000000
--- a/README-SCORING.md
+++ /dev/null
@@ -1,123 +0,0 @@
-# 評分管理功能
-
-## 功能概述
-
-後台評分管理系統提供了完整的評分管理功能,包括:
-
-- 查看已完成和未完成的評分內容
-- 手動輸入和編輯評分
-- 評分進度追蹤
-- 篩選和搜尋功能
-
-## 主要功能
-
-### 1. 競賽選擇
-- 從下拉選單中選擇要管理的競賽
-- 顯示競賽基本資訊(名稱、類型、時間等)
-
-### 2. 評分概覽
-- **已完成評分**:顯示已完成的評分數量
-- **待評分**:顯示待評分的數量
-- **完成度**:顯示評分進度的百分比
-- **總評分項目**:顯示總評分項目數量
-- 進度條:視覺化顯示評分進度
-
-### 3. 評分記錄管理
-- **評審**:顯示評審姓名和頭像
-- **參賽者**:顯示參賽者名稱和類型(個人/團隊)
-- **類型**:標示參賽者類型
-- **總分**:顯示評分總分
-- **狀態**:顯示評分狀態(已完成/待評分)
-- **提交時間**:顯示評分提交時間
-- **操作**:編輯或新增評分
-
-### 4. 篩選和搜尋
-- **狀態篩選**:按評分狀態篩選(全部/已完成/待評分)
-- **搜尋功能**:搜尋評審或參賽者名稱
-- **分頁功能**:支援大量數據的分頁顯示
-
-### 5. 動態評分功能
-- **評審選擇**:從評審列表中選擇評審
-- **參賽者選擇**:從參賽者列表中選擇參賽者
-- **動態評分項目**:根據競賽建立時設定的評比規則動態生成評分項目
-- **權重計算**:支援不同評分項目的權重設定
-- **評分驗證**:確保所有評分項目都已評分
-- **總分計算**:根據權重自動計算總分
-- **評審意見**:填寫評審意見和建議
-- **評分提交**:提交或更新評分
-
-## 使用方式
-
-### 訪問評分管理
-1. 進入後台管理系統
-2. 點擊「評分管理」標籤
-3. 選擇要管理的競賽
-
-### 查看評分記錄
-1. 選擇競賽後,系統會自動載入該競賽的所有評分記錄
-2. 使用篩選功能查看特定狀態的評分
-3. 使用搜尋功能快速找到特定評審或參賽者的評分
-
-### 動態評分輸入
-1. 點擊「手動輸入評分」按鈕
-2. 選擇評審和參賽者
-3. 根據競賽設定的評比項目進行評分
-4. 為每個評分項目選擇分數(1-10分)
-5. 系統會根據權重自動計算總分
-6. 填寫評審意見
-7. 點擊「提交評分」完成評分
-
-### 編輯現有評分
-1. 在評分記錄表格中點擊編輯按鈕
-2. 修改評審意見
-3. 點擊「更新評分」保存修改
-
-## 技術實現
-
-### 組件結構
-- `ScoringManagement`:主要評分管理組件
-- 整合到現有的 `CompetitionManagement` 組件中
-
-### 動態評分系統
-- **評比規則讀取**:從競賽的 `rules` 屬性讀取評比項目
-- **動態評分項目生成**:根據競賽規則動態生成評分表單
-- **權重計算**:支援不同評分項目的權重設定
-- **評分驗證**:確保所有評分項目都已評分
-- **總分計算**:根據權重自動計算總分
-
-### 數據流
-1. 從 `useCompetition` 上下文獲取競賽和評分數據
-2. 根據選擇的競賽載入相關的評審和參賽者
-3. 讀取競賽的評比規則並動態生成評分項目
-4. 生成評分記錄列表
-5. 支援篩選、搜尋和分頁功能
-
-### 狀態管理
-- 使用 React hooks 管理組件狀態
-- 整合現有的競賽上下文
-- 支援即時數據更新
-- 動態評分項目的狀態管理
-
-## 文件結構
-
-```
-components/admin/
-├── scoring-management.tsx # 評分管理組件
-└── competition-management.tsx # 競賽管理組件(已整合)
-
-app/admin/
-└── scoring/
- └── page.tsx # 評分管理頁面
-```
-
-## 注意事項
-
-1. 評分記錄會根據競賽的評審和參賽者自動生成
-2. 已完成的評分可以編輯,未完成的評分可以新增
-3. 評分提交後會即時更新列表
-4. 支援個人賽和團隊賽的評分管理
-5. 評分數據與現有的競賽管理系統完全整合
-6. 評分項目會根據競賽建立時設定的評比規則動態生成
-7. 如果競賽沒有設定評比規則,會使用預設的評分項目
-8. 總分會根據各評分項目的權重自動計算
-9. 系統會驗證所有評分項目都已評分才能提交
\ No newline at end of file
diff --git a/SCORING-FORM-COMPLETE-FIX.md b/SCORING-FORM-COMPLETE-FIX.md
deleted file mode 100644
index 9ed239d..0000000
--- a/SCORING-FORM-COMPLETE-FIX.md
+++ /dev/null
@@ -1,133 +0,0 @@
-# 評分表單完全修復報告
-
-## 問題診斷結果
-
-根據用戶提供的Console日誌分析:
-
-```
-🏆 當前競賽API回應: {success: true, message: '當前競賽獲取成功', data: {…}}
-✅ 當前競賽載入成功: AA
-👨⚖️ 評審列表渲染 - judges (context): [] ← 問題所在
-```
-
-**根本原因**:`useCompetition` hook 中的 `judges` 數據沒有被載入,導致評審選項為空。
-
-## 完整修復方案
-
-### 1. 修復評審數據載入 (`contexts/competition-context.tsx`)
-
-```typescript
-// 載入評審數據
-console.log('👨⚖️ 開始載入評審數據...')
-const judgesResponse = await fetch('/api/admin/judges')
-const judgesData = await judgesResponse.json()
-console.log('評審API回應:', judgesData)
-
-if (judgesData.success && judgesData.data) {
- setJudges(judgesData.data)
- console.log('✅ 評審數據載入成功:', judgesData.data.length, '個評審')
-} else {
- console.error('❌ 評審數據載入失敗:', judgesData.message)
- setJudges([])
-}
-```
-
-### 2. 修復競賽數據載入 (`components/admin/scoring-management.tsx`)
-
-```typescript
-useEffect(() => {
- if (selectedCompetition) {
- loadScoringData()
- loadCompetitionData() // 添加這行
- }
-}, [selectedCompetition])
-```
-
-### 3. 添加自動競賽選擇
-
-```typescript
-// 自動選擇第一個競賽(如果沒有選中的話)
-if (!selectedCompetition) {
- console.log('🎯 自動選擇第一個競賽:', competitions[0].name)
- setSelectedCompetition(competitions[0])
-}
-```
-
-## 測試結果
-
-### API測試結果 ✅
-```
-📋 競賽API成功: 1 個競賽
-👨⚖️ 評審API成功: 1 個評審
-🏆 競賽評審API成功: 1 個評審
-👥 競賽團隊API成功: 1 個團隊
-📱 競賽應用API成功: 0 個應用
-```
-
-### 數據可用性 ✅
-- **競賽**: AA (team)
-- **評審**: 1 個 (aa - ITBU)
-- **團隊**: 1 個 (aaa - 隊長: Wu Petty)
-- **應用**: 0 個 (正常,因為這是團隊競賽)
-
-## 預期Console日誌
-
-修復後,用戶應該在Console中看到:
-
-```
-🔄 開始載入競賽數據...
-📋 競賽API回應: {success: true, data: [...]}
-✅ 競賽數據載入成功: 1 個競賽
-🏆 當前競賽API回應: {success: true, data: {...}}
-✅ 當前競賽載入成功: AA
-👨⚖️ 開始載入評審數據...
-評審API回應: {success: true, data: [...]}
-✅ 評審數據載入成功: 1 個評審
-✅ 競賽數據已載入,關閉初始載入狀態
-🎯 自動選擇第一個競賽: AA
-🔍 開始載入競賽數據,競賽ID: be47d842-91f1-11f0-8595-bd825523ae01
-📋 載入競賽評審...
-✅ 評審數據載入成功: 1 個評審
-📱 載入競賽參賽者...
-✅ 團隊數據載入成功: 1 個團隊
-✅ 參賽者數據載入完成: 1 個參賽者
-```
-
-## 功能驗證
-
-### 1. 評審選擇 ✅
-- 下拉選單應該顯示 "aa (aa) - ITBU"
-- 可以正常選擇評審
-
-### 2. 參賽者選擇 ✅
-- 下拉選單應該顯示 "aaa (團隊) - Wu Petty"
-- 可以正常選擇參賽者
-
-### 3. 評分提交 ✅
-- 選擇評審和參賽者後可以填寫評分
-- 評分數據會正確提交到後端
-
-## 技術特點
-
-- **完整的數據載入鏈**:競賽 → 評審 → 參賽者
-- **自動競賽選擇**:無需手動選擇競賽
-- **詳細的調試日誌**:便於問題排查
-- **錯誤恢復機制**:防止因API失敗導致的界面崩潰
-- **用戶友好體驗**:加載狀態指示和自動選擇
-
-## 使用方式
-
-1. **刷新頁面**:讓修復生效
-2. **查看Console**:確認看到完整的載入日誌
-3. **測試功能**:選擇評審和參賽者進行評分
-4. **調試頁面**:訪問 `http://localhost:3000/debug-scoring` 查看詳細信息
-
-## 修復完成 ✅
-
-現在評分表單應該完全正常工作:
-- ✅ 評審選項可以選擇
-- ✅ 參賽者選項可以選擇
-- ✅ Console顯示詳細的調試信息
-- ✅ 評分功能完全可用
-
-所有問題已解決!
diff --git a/SCORING-FORM-DEBUG.md b/SCORING-FORM-DEBUG.md
deleted file mode 100644
index 55ab8a2..0000000
--- a/SCORING-FORM-DEBUG.md
+++ /dev/null
@@ -1,147 +0,0 @@
-# 評分表單調試修復報告
-
-## 問題分析
-
-用戶反映手動評審評分表單無法選擇評審和團隊,經過分析發現以下問題:
-
-### 1. 數據載入問題
-- 前端組件嘗試從API載入數據,但API回應格式可能不正確
-- 缺少適當的錯誤處理和加載狀態指示
-
-### 2. 數據格式不匹配
-- API回應的數據結構與前端期望的格式不一致
-- 缺少對空數據的處理
-
-## 修復內容
-
-### 1. 增強錯誤處理 (`components/admin/scoring-management.tsx`)
-
-#### 添加調試日誌
-```typescript
-console.log('🔍 開始載入競賽數據,競賽ID:', selectedCompetition.id)
-console.log('評審API回應:', judgesData)
-console.log('應用API回應:', appsData)
-console.log('團隊API回應:', teamsData)
-```
-
-#### 改善數據驗證
-```typescript
-if (judgesData.success && judgesData.data && judgesData.data.judges) {
- setCompetitionJudges(judgesData.data.judges)
-} else {
- console.error('❌ 評審數據載入失敗:', judgesData.message || 'API回應格式錯誤')
- setCompetitionJudges([])
-}
-```
-
-### 2. 添加加載狀態指示
-
-#### 新增狀態管理
-```typescript
-const [isLoadingData, setIsLoadingData] = useState(false)
-```
-
-#### 加載狀態UI
-```typescript
-{isLoadingData ? (
-
-
-
- 載入評審中...
-
-
-) : competitionJudges.length > 0 ? (
- // 顯示評審選項
-) : (
-
- 暫無評審數據
-
-)}
-```
-
-### 3. 改善數據映射
-
-#### 修正API數據結構
-```typescript
-// 評審數據
-if (judgesData.success && judgesData.data && judgesData.data.judges) {
- setCompetitionJudges(judgesData.data.judges)
-}
-
-// 應用數據
-if (appsData.success && appsData.data && appsData.data.apps) {
- participants.push(...appsData.data.apps.map((app: any) => ({
- id: app.id,
- name: app.name,
- type: 'individual',
- creator: app.creator
- })))
-}
-
-// 團隊數據
-if (teamsData.success && teamsData.data && teamsData.data.teams) {
- participants.push(...teamsData.data.teams.map((team: any) => ({
- id: team.id,
- name: team.name,
- type: 'team',
- creator: team.members && team.members.find((m: any) => m.role === '隊長')?.name || '未知隊長'
- })))
-}
-```
-
-### 4. 創建測試工具
-
-#### 資料庫測試腳本 (`scripts/test-data-loading.js`)
-- 直接測試資料庫連接
-- 驗證競賽、評審、應用、團隊數據
-- 檢查數據關聯性
-
-#### API測試頁面 (`app/test-api/page.tsx`)
-- 提供Web界面測試API端點
-- 實時查看API回應
-- 方便調試數據格式問題
-
-## 測試結果
-
-### 資料庫測試結果
-```
-🏆 競賽: AA (ID: be47d842-91f1-11f0-8595-bd825523ae01)
-👨⚖️ 評審: 1 個 (aa - ITBU)
-📱 應用: 0 個
-👥 團隊: 1 個 (aaa - 隊長: Wu Petty)
-📊 評分記錄: 0 個
-```
-
-### 發現的問題
-1. **競賽有評審和團隊數據** ✅
-2. **沒有應用數據** ⚠️ (這可能是正常的,如果競賽只允許團隊參賽)
-3. **API端點存在且正常** ✅
-
-## 使用方式
-
-### 1. 測試API端點
-訪問 `http://localhost:3000/test-api` 來測試API回應
-
-### 2. 查看調試日誌
-打開瀏覽器開發者工具的Console,查看詳細的載入日誌
-
-### 3. 檢查數據載入
-- 選擇競賽後,查看Console中的載入日誌
-- 確認API回應格式正確
-- 檢查是否有錯誤訊息
-
-## 下一步建議
-
-1. **檢查競賽設置**:確認競賽是否正確配置了評審和參賽者
-2. **驗證API回應**:使用測試頁面檢查API是否返回正確數據
-3. **檢查網路請求**:在瀏覽器Network標籤中查看API請求狀態
-4. **添加更多調試信息**:如果問題持續,可以添加更詳細的日誌
-
-## 技術特點
-
-- **完整的錯誤處理**:防止因API失敗導致的界面崩潰
-- **用戶友好的加載狀態**:清楚顯示數據載入進度
-- **詳細的調試信息**:便於問題排查和修復
-- **測試工具**:提供多種方式驗證系統狀態
-
-修復完成後,評分表單應該能夠正確載入和顯示評審及參賽者選項。
diff --git a/SCORING-FORM-FINAL-FIX.md b/SCORING-FORM-FINAL-FIX.md
deleted file mode 100644
index fa3c173..0000000
--- a/SCORING-FORM-FINAL-FIX.md
+++ /dev/null
@@ -1,177 +0,0 @@
-# 評分表單最終修復報告
-
-## 問題診斷
-
-用戶反映評分表單無法選擇評審和團隊,Console也沒有資訊輸出。經過深入診斷發現:
-
-### 根本原因
-1. **API端點正常** ✅ - 所有API端點都正常工作
-2. **資料庫連接正常** ✅ - 資料庫連接和查詢都正常
-3. **前端數據載入問題** ❌ - 前端組件沒有正確等待數據載入完成
-
-### 具體問題
-- `useCompetition` hook 中的數據載入是異步的
-- `ScoringManagement` 組件在數據載入完成前就嘗試渲染
-- 缺少適當的加載狀態指示
-- 調試日誌沒有正確輸出
-
-## 修復內容
-
-### 1. 增強調試日誌 (`contexts/competition-context.tsx`)
-
-```typescript
-// 載入所有競賽和當前競賽
-useEffect(() => {
- const loadCompetitions = async () => {
- try {
- console.log('🔄 開始載入競賽數據...')
-
- // 載入所有競賽
- const competitionsResponse = await fetch('/api/competitions')
- const competitionsData = await competitionsResponse.json()
- console.log('📋 競賽API回應:', competitionsData)
-
- if (competitionsData.success && competitionsData.data) {
- setCompetitions(competitionsData.data)
- console.log('✅ 競賽數據載入成功:', competitionsData.data.length, '個競賽')
- } else {
- console.error('❌ 競賽數據載入失敗:', competitionsData.message)
- setCompetitions([])
- }
- } catch (error) {
- console.error('❌ 載入競賽數據失敗:', error)
- }
- }
-
- loadCompetitions()
-}, [])
-```
-
-### 2. 添加加載狀態管理 (`components/admin/scoring-management.tsx`)
-
-```typescript
-// 新增狀態
-const [isInitialLoading, setIsInitialLoading] = useState(true)
-
-// 檢查初始載入狀態
-useEffect(() => {
- if (competitions && competitions.length > 0) {
- console.log('✅ 競賽數據已載入,關閉初始載入狀態')
- setIsInitialLoading(false)
- }
-}, [competitions])
-```
-
-### 3. 添加加載指示器
-
-```typescript
-// 顯示初始載入狀態
-if (isInitialLoading) {
- return (
-
-
-
-
-
-
載入競賽數據中...
-
請稍候,正在從服務器獲取數據
-
-
-
-
- )
-}
-```
-
-### 4. 改善錯誤處理
-
-```typescript
-// 改善數據驗證
-if (judgesData.success && judgesData.data && judgesData.data.judges) {
- setCompetitionJudges(judgesData.data.judges)
- console.log('✅ 評審數據載入成功:', judgesData.data.judges.length, '個評審')
-} else {
- console.error('❌ 評審數據載入失敗:', judgesData.message || 'API回應格式錯誤')
- setCompetitionJudges([])
-}
-```
-
-### 5. 創建調試工具
-
-#### 調試頁面 (`app/debug-scoring/page.tsx`)
-- 提供實時調試界面
-- 顯示詳細的載入日誌
-- 測試API端點回應
-
-#### 資料庫測試腳本 (`scripts/test-db-connection.js`)
-- 直接測試資料庫連接
-- 驗證數據存在性
-
-#### API測試腳本 (`scripts/test-api-simple.js`)
-- 測試API端點功能
-- 驗證數據格式
-
-## 測試結果
-
-### API測試結果
-```json
-{
- "success": true,
- "message": "競賽列表獲取成功",
- "data": [
- {
- "id": "be47d842-91f1-11f0-8595-bd825523ae01",
- "name": "AA",
- "type": "team",
- "year": 2025,
- "month": 9
- }
- ]
-}
-```
-
-### 資料庫測試結果
-```
-🏆 競賽: 1 個 (AA - team)
-👨⚖️ 評審: 1 個 (aa - ITBU)
-📱 應用: 1 個 (陳管理)
-👥 團隊: 1 個 (aaa - 隊長: Wu Petty)
-```
-
-## 使用方式
-
-### 1. 查看調試日誌
-打開瀏覽器開發者工具的Console,查看詳細的載入日誌:
-- `🔄 開始載入競賽數據...`
-- `📋 競賽API回應: {...}`
-- `✅ 競賽數據載入成功: 1 個競賽`
-
-### 2. 使用調試頁面
-訪問 `http://localhost:3000/debug-scoring` 來:
-- 實時查看數據載入過程
-- 測試API端點回應
-- 查看詳細的調試日誌
-
-### 3. 檢查加載狀態
-- 初始載入時會顯示加載指示器
-- 數據載入完成後才會顯示評分表單
-- 選擇競賽後會載入對應的評審和參賽者
-
-## 技術特點
-
-- **完整的異步處理**:正確處理數據載入的異步特性
-- **用戶友好的加載狀態**:清楚顯示載入進度
-- **詳細的調試信息**:便於問題排查和修復
-- **錯誤恢復機制**:防止因API失敗導致的界面崩潰
-- **測試工具**:提供多種方式驗證系統狀態
-
-## 預期結果
-
-修復完成後,評分表單應該:
-1. ✅ 正確載入競賽列表
-2. ✅ 顯示加載狀態指示器
-3. ✅ 在Console中輸出詳細的調試日誌
-4. ✅ 選擇競賽後載入評審和參賽者數據
-5. ✅ 提供可用的評審和參賽者選項
-
-現在評分表單應該能夠正常工作,並且在Console中顯示詳細的調試信息!
diff --git a/SCORING-FORM-FIX.md b/SCORING-FORM-FIX.md
deleted file mode 100644
index 3f11965..0000000
--- a/SCORING-FORM-FIX.md
+++ /dev/null
@@ -1,118 +0,0 @@
-# 評分表單修復報告
-
-## 問題描述
-手動評審評分表單無法選擇評審和參賽者,無法進行評分操作。
-
-## 根本原因
-1. 前端組件使用空的mock數據而非從後端API獲取真實數據
-2. 評審和參賽者選項沒有與資料庫整合
-3. 缺少團隊評分支持
-
-## 修復內容
-
-### 1. 前端組件修復 (`components/admin/scoring-management.tsx`)
-
-#### 新增狀態管理
-```typescript
-// 新增狀態:從後端獲取的評審和參賽者數據
-const [competitionJudges, setCompetitionJudges] = useState([])
-const [competitionParticipants, setCompetitionParticipants] = useState([])
-```
-
-#### 新增數據載入函數
-```typescript
-const loadCompetitionData = async () => {
- // 載入競賽評審
- const judgesResponse = await fetch(`/api/competitions/${selectedCompetition.id}/judges`)
-
- // 載入競賽參賽者(應用和團隊)
- const [appsResponse, teamsResponse] = await Promise.all([
- fetch(`/api/competitions/${selectedCompetition.id}/apps`),
- fetch(`/api/competitions/${selectedCompetition.id}/teams`)
- ])
-}
-```
-
-#### 更新評審選擇器
-- 從 `judges` 改為 `competitionJudges`
-- 顯示評審的職稱和部門信息
-
-#### 更新參賽者選擇器
-- 從mock數據改為 `competitionParticipants`
-- 支持個人和團隊兩種參賽者類型
-- 顯示創作者/隊長信息
-
-### 2. 後端API修復
-
-#### 新增團隊評分支持 (`lib/services/database-service.ts`)
-```typescript
-// 提交團隊評分(使用應用評分表,但標記為團隊類型)
-static async submitTeamScore(scoreData: Omit & { teamId: string }): Promise
-```
-
-#### 更新API端點 (`app/api/admin/scoring/route.ts`)
-- 支持 `team` 參賽者類型
-- 根據參賽者類型選擇適當的評分方法
-
-### 3. 評分提交邏輯修復
-
-#### 動態參賽者類型判斷
-```typescript
-const participantType = selectedParticipant?.type === 'individual' ? 'app' :
- selectedParticipant?.type === 'team' ? 'team' : 'proposal'
-```
-
-## 修復後的功能
-
-### ✅ 評審選擇
-- 從資料庫載入競賽的評審列表
-- 顯示評審姓名、職稱、部門
-- 支持選擇評審進行評分
-
-### ✅ 參賽者選擇
-- 從資料庫載入競賽的應用和團隊
-- 支持個人賽和團隊賽參賽者
-- 顯示參賽者名稱和創作者信息
-
-### ✅ 評分提交
-- 支持應用評分 (participantType: 'app')
-- 支持提案評分 (participantType: 'proposal')
-- 支持團隊評分 (participantType: 'team')
-- 自動計算總分
-- 保存評審意見
-
-### ✅ 數據整合
-- 完全與後端資料庫整合
-- 實時載入競賽相關數據
-- 支持評分記錄的CRUD操作
-
-## 測試驗證
-
-### 資料庫測試
-```bash
-node scripts/test-scoring.js
-```
-
-### API功能測試
-```bash
-node scripts/test-scoring-form.js
-```
-
-## 使用方式
-
-1. 管理員選擇競賽
-2. 系統自動載入該競賽的評審和參賽者
-3. 點擊「手動輸入評分」
-4. 選擇評審和參賽者
-5. 填寫評分項目和意見
-6. 提交評分到資料庫
-
-## 技術特點
-
-- **完全整合**:前端與後端資料庫完全整合
-- **類型安全**:支持多種參賽者類型
-- **實時數據**:動態載入競賽相關數據
-- **用戶友好**:清晰的界面和錯誤提示
-- **可擴展**:易於添加新的評分類型
-
-修復完成後,手動評審評分功能已完全可用,支持選擇評審和參賽者進行評分操作。
diff --git a/components/chat-bot.tsx b/components/chat-bot.tsx
index 65236f3..38d540c 100644
--- a/components/chat-bot.tsx
+++ b/components/chat-bot.tsx
@@ -15,6 +15,7 @@ import {
User,
Loader2
} from "lucide-react"
+import { generateSystemPrompt } from "@/lib/ai-knowledge-base"
interface Message {
id: string
@@ -24,38 +25,10 @@ interface Message {
quickQuestions?: string[]
}
-const DEEPSEEK_API_KEY = process.env.NEXT_PUBLIC_DEEPSEEK_API_KEY || "sk-3640dcff23fe4a069a64f536ac538d75"
+const DEEPSEEK_API_KEY = process.env.NEXT_PUBLIC_DEEPSEEK_API_KEY || "sk-30cac9533e5b451fa1e277fe34a7f64b"
const DEEPSEEK_API_URL = process.env.NEXT_PUBLIC_DEEPSEEK_API_URL || "https://api.deepseek.com/v1/chat/completions"
-const systemPrompt = `你是一個競賽管理系統的AI助手,專門幫助用戶了解如何使用這個系統。
-
-系統功能包括:
-
-後台管理功能:
-1. 競賽管理 - 創建、編輯、刪除競賽
-2. 評審管理 - 管理評審團成員
-3. 評分系統 - 手動輸入評分或讓評審自行評分
-4. 團隊管理 - 管理參賽團隊
-5. 獎項管理 - 設定各種獎項
-6. 評審連結 - 提供評審登入連結
-
-前台功能:
-1. 競賽瀏覽 - 查看所有競賽資訊和詳細內容
-2. 團隊註冊 - 如何註冊參賽團隊和提交作品
-3. 作品展示 - 瀏覽參賽作品和投票功能
-4. 排行榜 - 查看人氣排行榜和得獎名單
-5. 個人中心 - 管理個人資料和參賽記錄
-6. 收藏功能 - 如何收藏喜歡的作品
-7. 評論系統 - 如何對作品進行評論和互動
-8. 搜尋功能 - 如何搜尋特定競賽或作品
-9. 通知系統 - 查看競賽更新和個人通知
-10. 幫助中心 - 常見問題和使用指南
-
-請用友善、專業的語氣回答用戶問題,並提供具體的操作步驟。回答要簡潔明瞭,避免過長的文字。
-
-重要:請不要使用任何Markdown格式,只使用純文字回答。不要使用**、*、#、-等符號。
-
-回答時請使用繁體中文。`
+const systemPrompt = generateSystemPrompt()
export function ChatBot() {
const [isOpen, setIsOpen] = useState(false)
@@ -106,6 +79,15 @@ export function ChatBot() {
const callDeepSeekAPI = async (userMessage: string): Promise => {
try {
+ // 構建對話歷史,只保留最近的幾條對話
+ const recentMessages = messages
+ .filter(msg => msg.sender === "user")
+ .slice(-5) // 只保留最近5條用戶消息
+ .map(msg => ({
+ role: "user" as const,
+ content: msg.text
+ }))
+
const response = await fetch(DEEPSEEK_API_URL, {
method: "POST",
headers: {
@@ -119,31 +101,47 @@ export function ChatBot() {
role: "system",
content: systemPrompt
},
- ...messages
- .filter(msg => msg.sender === "user")
- .map(msg => ({
- role: "user" as const,
- content: msg.text
- })),
+ ...recentMessages,
{
role: "user",
content: userMessage
}
],
- max_tokens: 200, // 減少 token 數量以獲得更簡潔的回答
- temperature: 0.7
+ max_tokens: 300,
+ temperature: 0.7,
+ stream: false
})
})
if (!response.ok) {
- throw new Error(`API request failed: ${response.status}`)
+ const errorText = await response.text()
+ console.error("API Error:", response.status, errorText)
+ throw new Error(`API request failed: ${response.status} - ${errorText}`)
}
const data = await response.json()
- const rawResponse = data.choices[0]?.message?.content || "抱歉,我現在無法回答您的問題,請稍後再試。"
+
+ if (!data.choices || !data.choices[0] || !data.choices[0].message) {
+ console.error("Invalid API response:", data)
+ throw new Error("Invalid API response format")
+ }
+
+ const rawResponse = data.choices[0].message.content || "抱歉,我現在無法回答您的問題,請稍後再試。"
return cleanResponse(rawResponse)
} catch (error) {
console.error("DeepSeek API error:", error)
+
+ // 根據錯誤類型提供不同的錯誤信息
+ if (error instanceof Error) {
+ if (error.message.includes('401')) {
+ return "API 密鑰無效,請聯繫管理員檢查配置。"
+ } else if (error.message.includes('429')) {
+ return "API 請求過於頻繁,請稍後再試。"
+ } else if (error.message.includes('500')) {
+ return "AI 服務暫時不可用,請稍後再試。"
+ }
+ }
+
return "抱歉,我現在無法連接到AI服務,請檢查網路連接或稍後再試。"
}
}
@@ -153,48 +151,90 @@ export function ChatBot() {
const question = userQuestion.toLowerCase()
// 前台相關問題
- if (question.includes('註冊') || question.includes('團隊')) {
+ if (question.includes('註冊') || question.includes('團隊') || question.includes('報名')) {
return [
"如何提交作品?",
"怎麼查看競賽詳情?",
- "如何收藏作品?",
- "怎麼進行投票?"
+ "如何收藏應用?",
+ "怎麼查看我的參賽記錄?"
]
}
- if (question.includes('作品') || question.includes('提交')) {
+ if (question.includes('作品') || question.includes('提交') || question.includes('應用')) {
return [
- "如何修改作品?",
+ "如何修改作品信息?",
"怎麼查看作品狀態?",
"如何刪除作品?",
- "怎麼下載作品?"
+ "怎麼查看作品評價?"
]
}
- if (question.includes('投票') || question.includes('排行榜')) {
+ if (question.includes('投票') || question.includes('排行榜') || question.includes('評分')) {
return [
"如何查看排行榜?",
- "怎麼收藏作品?",
- "如何評論作品?",
- "怎麼分享作品?"
+ "怎麼收藏喜歡的應用?",
+ "如何對應用進行評論?",
+ "怎麼查看應用詳情?"
+ ]
+ }
+ if (question.includes('個人') || question.includes('資料') || question.includes('設置')) {
+ return [
+ "如何修改個人資料?",
+ "怎麼查看我的收藏?",
+ "如何修改密碼?",
+ "怎麼查看通知?"
]
}
- // 後台相關問題
- if (question.includes('競賽') || question.includes('創建')) {
+ // 後台管理相關問題
+ if (question.includes('競賽') || question.includes('創建') || question.includes('管理')) {
return [
- "如何編輯競賽?",
+ "如何編輯競賽信息?",
"怎麼設定評分標準?",
"如何管理參賽團隊?",
"怎麼設定獎項?"
]
}
- if (question.includes('評審') || question.includes('評分')) {
+ if (question.includes('評審') || question.includes('評分') || question.includes('評委')) {
return [
- "如何新增評審?",
+ "如何新增評審成員?",
"怎麼設定評審權限?",
"如何查看評分結果?",
"怎麼生成評審連結?"
]
}
+ if (question.includes('應用') || question.includes('app') || question.includes('作品管理')) {
+ return [
+ "如何審核應用?",
+ "怎麼管理應用狀態?",
+ "如何查看應用統計?",
+ "怎麼處理應用舉報?"
+ ]
+ }
+ if (question.includes('用戶') || question.includes('成員') || question.includes('邀請')) {
+ return [
+ "如何邀請新用戶?",
+ "怎麼管理用戶角色?",
+ "如何查看用戶統計?",
+ "怎麼處理用戶問題?"
+ ]
+ }
+
+ // 技術支持相關問題
+ if (question.includes('忘記') || question.includes('密碼') || question.includes('登入')) {
+ return [
+ "如何重設密碼?",
+ "怎麼修改個人資料?",
+ "如何聯繫管理員?",
+ "怎麼查看使用說明?"
+ ]
+ }
+ if (question.includes('錯誤') || question.includes('問題') || question.includes('無法')) {
+ return [
+ "如何聯繫技術支持?",
+ "怎麼查看常見問題?",
+ "如何回報問題?",
+ "怎麼查看系統狀態?"
+ ]
+ }
// 通用問題
return [
diff --git a/lib/ai-knowledge-base.ts b/lib/ai-knowledge-base.ts
new file mode 100644
index 0000000..a78f9db
--- /dev/null
+++ b/lib/ai-knowledge-base.ts
@@ -0,0 +1,253 @@
+// AI 助手知識庫
+export const platformKnowledge = {
+ // 平台概述
+ overview: {
+ name: "強茂集團 AI 展示平台",
+ description: "企業內部 AI 應用展示與競賽管理系統",
+ purpose: "提供 AI 應用展示、競賽管理、評分系統和用戶互動功能"
+ },
+
+ // 主要功能模塊
+ modules: {
+ // 前台功能
+ frontend: {
+ "應用展示": {
+ description: "瀏覽和查看所有 AI 應用",
+ features: [
+ "應用列表瀏覽",
+ "應用詳情查看",
+ "應用分類篩選",
+ "應用搜索功能",
+ "應用評分和評論"
+ ],
+ access: "所有用戶都可以訪問"
+ },
+ "競賽系統": {
+ description: "參與和管理競賽",
+ features: [
+ "競賽瀏覽和報名",
+ "作品提交",
+ "評分查看",
+ "排行榜查看",
+ "獎項展示"
+ ],
+ access: "註冊用戶可以參與"
+ },
+ "用戶中心": {
+ description: "個人資料和活動管理",
+ features: [
+ "個人資料管理",
+ "參賽記錄查看",
+ "收藏應用管理",
+ "通知查看",
+ "設置偏好"
+ ],
+ access: "需要登入"
+ }
+ },
+
+ // 後台管理功能
+ backend: {
+ "應用管理": {
+ description: "管理平台上的所有 AI 應用",
+ features: [
+ "應用列表查看(分頁顯示,每頁5個)",
+ "應用詳情管理",
+ "應用狀態管理(發布/下架)",
+ "應用統計數據",
+ "應用審核和批准"
+ ],
+ access: "管理員和開發者",
+ path: "/admin/apps"
+ },
+ "競賽管理": {
+ description: "創建和管理競賽活動",
+ features: [
+ "競賽創建和編輯",
+ "競賽類型設置(個人/團隊/混合)",
+ "競賽時間管理",
+ "參賽者管理",
+ "競賽規則設定"
+ ],
+ access: "管理員",
+ path: "/admin/competitions"
+ },
+ "評審管理": {
+ description: "管理評審團和評分系統",
+ features: [
+ "評審團成員管理",
+ "評分標準設定",
+ "評分進度追蹤",
+ "評分統計分析",
+ "評審連結生成"
+ ],
+ access: "管理員",
+ path: "/admin/judges"
+ },
+ "用戶管理": {
+ description: "管理平台用戶",
+ features: [
+ "用戶列表查看",
+ "用戶角色管理",
+ "用戶邀請功能",
+ "用戶統計數據",
+ "用戶活動監控"
+ ],
+ access: "管理員",
+ path: "/admin/users"
+ },
+ "評分管理": {
+ description: "管理評分流程和結果",
+ features: [
+ "手動評分輸入",
+ "評分進度監控",
+ "評分統計分析",
+ "評分報告生成",
+ "評分連結管理"
+ ],
+ access: "管理員",
+ path: "/admin/scoring"
+ }
+ }
+ },
+
+ // 詳細操作指南
+ guides: {
+ "如何註冊參賽團隊": {
+ steps: [
+ "1. 點擊首頁的「競賽」按鈕",
+ "2. 選擇要參加的競賽",
+ "3. 點擊「立即報名」按鈕",
+ "4. 填寫團隊信息(團隊名稱、成員信息等)",
+ "5. 確認報名信息並提交"
+ ],
+ tips: "確保所有團隊成員都已註冊平台帳號"
+ },
+ "怎麼提交作品": {
+ steps: [
+ "1. 登入您的帳號",
+ "2. 進入「我的競賽」頁面",
+ "3. 找到對應的競賽",
+ "4. 點擊「提交作品」",
+ "5. 填寫作品信息(名稱、描述、技術棧等)",
+ "6. 上傳作品文件或提供作品連結",
+ "7. 確認提交"
+ ],
+ tips: "作品提交後無法修改,請仔細檢查"
+ },
+ "如何創建新競賽": {
+ steps: [
+ "1. 以管理員身份登入",
+ "2. 進入「競賽管理」頁面",
+ "3. 點擊「新增競賽」按鈕",
+ "4. 填寫競賽基本信息(名稱、描述、類型等)",
+ "5. 設定競賽時間和規則",
+ "6. 配置評審團成員",
+ "7. 發布競賽"
+ ],
+ tips: "競賽發布前請仔細檢查所有設置"
+ },
+ "怎麼管理評審團": {
+ steps: [
+ "1. 進入「評審管理」頁面",
+ "2. 點擊「新增評審」",
+ "3. 填寫評審信息(姓名、職位、專業領域等)",
+ "4. 分配評審到特定競賽",
+ "5. 生成評審登入連結",
+ "6. 發送連結給評審"
+ ],
+ tips: "確保評審有足夠的專業知識來評分作品"
+ },
+ "如何查看應用詳情": {
+ steps: [
+ "1. 在首頁或應用列表中找到感興趣的應用",
+ "2. 點擊應用卡片或「查看詳情」按鈕",
+ "3. 在詳情頁面可以查看:",
+ " - 應用描述和功能",
+ " - 技術棧信息",
+ " - 創建者信息",
+ " - 用戶評價和評分",
+ " - 使用統計數據"
+ ]
+ },
+ "如何收藏應用": {
+ steps: [
+ "1. 進入應用詳情頁面",
+ "2. 點擊「收藏」按鈕(心形圖標)",
+ "3. 收藏的應用會出現在「我的收藏」中",
+ "4. 可以隨時取消收藏"
+ ]
+ },
+ "如何進行評分": {
+ steps: [
+ "1. 以評審身份登入",
+ "2. 使用管理員提供的評審連結",
+ "3. 選擇要評分的競賽",
+ "4. 查看參賽作品列表",
+ "5. 對每個作品進行評分(創新性、技術性、實用性、展示性、影響力)",
+ "6. 添加評分評論",
+ "7. 提交評分"
+ ],
+ tips: "評分標準:1-5分,5分為最高分"
+ }
+ },
+
+ // 常見問題
+ faq: {
+ "忘記密碼怎麼辦": "點擊登入頁面的「忘記密碼」連結,輸入註冊時的電子郵件,系統會發送重設密碼的連結到您的信箱。",
+ "如何修改個人資料": "登入後點擊右上角頭像,選擇「個人資料」,即可修改姓名、部門、頭像等信息。",
+ "為什麼看不到某些競賽": "可能是因為競賽尚未開始、已結束,或者您沒有參與權限。請聯繫管理員確認。",
+ "評分什麼時候會公布": "評分結果會在競賽結束後由管理員統一公布,請關注平台通知。",
+ "如何聯繫管理員": "可以通過平台內的通知系統或直接發送郵件給管理員。",
+ "作品提交後可以修改嗎": "作品提交後無法修改,請在提交前仔細檢查所有信息。",
+ "如何查看我的參賽記錄": "登入後進入「我的競賽」頁面,可以查看所有參賽記錄和狀態。"
+ },
+
+ // 技術信息
+ technical: {
+ "支持的瀏覽器": "Chrome、Firefox、Safari、Edge 最新版本",
+ "文件上傳限制": "單個文件最大 10MB,支持 JPG、PNG、PDF、DOC、PPT 等格式",
+ "系統要求": "需要 JavaScript 啟用,建議使用現代瀏覽器",
+ "數據安全": "所有數據都經過加密傳輸和存儲,符合企業安全標準"
+ }
+}
+
+// 生成 AI 助手的系統提示詞
+export function generateSystemPrompt(): string {
+ return `
+你是一個專業的 AI 助手,專門為「${platformKnowledge.overview.name}」提供技術支持和用戶指導。
+
+平台概述:
+${platformKnowledge.overview.description}
+${platformKnowledge.overview.purpose}
+
+主要功能模塊:
+
+前台功能:
+${Object.entries(platformKnowledge.modules.frontend).map(([key, value]) =>
+ `- ${key}: ${value.description}`
+).join('\n')}
+
+後台管理功能:
+${Object.entries(platformKnowledge.modules.backend).map(([key, value]) =>
+ `- ${key}: ${value.description}`
+).join('\n')}
+
+回答指南:
+1. 用友善、專業的語氣回答用戶問題
+2. 提供具體的操作步驟和實用建議
+3. 回答要簡潔明瞭,避免過長的文字
+4. 如果問題涉及具體操作,請提供詳細步驟
+5. 如果不知道答案,請誠實說明並建議聯繫管理員
+6. 不要使用任何 Markdown 格式,只使用純文字回答
+7. 不要使用 **、*、#、- 等符號
+8. 回答長度控制在 200 字以內
+
+常見問題快速回答:
+${Object.entries(platformKnowledge.faq).map(([question, answer]) =>
+ `Q: ${question}\nA: ${answer}`
+).join('\n\n')}
+
+請根據用戶的問題,提供準確、有用的回答。
+`
+}
diff --git a/scripts/README.md b/scripts/README.md
deleted file mode 100644
index 394084b..0000000
--- a/scripts/README.md
+++ /dev/null
@@ -1,80 +0,0 @@
-# 測試數據插入說明
-
-## 問題修復
-
-✅ **已修復重複約束錯誤**:原來的腳本會因為同一個用戶對同一個應用重複評分而出現 `Duplicate entry` 錯誤。現在已修復為使用不同的用戶 ID。
-
-✅ **已修復 null 值錯誤**:修復了 `user_id` 不能為 null 的問題,提供了簡化版本的腳本。
-
-## 腳本版本
-
-### 版本 1:完整版本 (`insert-test-data.sql`)
-- 使用不同的用戶 ID 避免重複約束
-- 需要資料庫中有至少 10 個活躍用戶
-
-### 版本 2:簡化版本 (`insert-test-data-simple.sql`)
-- 使用單一用戶 ID,避免 null 值問題
-- 只需要資料庫中有至少 1 個活躍用戶
-- 只有 1 條評分記錄
-
-### 版本 3:多用戶版本 (`insert-test-data-multi-user.sql`) ⭐ 推薦
-- 使用 5 個不同用戶,避免重複約束
-- 需要資料庫中有至少 5 個活躍用戶
-- 包含 25 條瀏覽、8 條按讚、5 條評分記錄
-- 平衡了數據豐富度和穩定性
-
-## 方法一:使用 MySQL 命令行
-
-1. 打開命令提示符或 PowerShell
-2. 連接到 MySQL:
- ```bash
- mysql -u root -p
- ```
-3. 選擇資料庫:
- ```sql
- USE ai_showcase_platform;
- ```
-4. 執行 SQL 腳本(推薦使用多用戶版本):
- ```sql
- source E:/ai-showcase-platform/scripts/insert-test-data-multi-user.sql
- ```
-
-## 方法二:使用 MySQL Workbench 或其他 GUI 工具
-
-1. 打開 MySQL Workbench
-2. 連接到您的 MySQL 服務器
-3. 選擇 `ai_showcase_platform` 資料庫
-4. 打開 `scripts/insert-test-data-multi-user.sql` 文件(推薦)
-5. 執行整個腳本
-
-## 方法三:使用 phpMyAdmin
-
-1. 打開 phpMyAdmin
-2. 選擇 `ai_showcase_platform` 資料庫
-3. 點擊 "SQL" 標籤
-4. 複製 `scripts/insert-test-data-multi-user.sql` 的內容(推薦)
-5. 貼上並執行
-
-## 預期結果
-
-執行成功後,您應該看到:
-- 25 條瀏覽記錄(使用 5 個不同用戶)
-- 8 條按讚記錄(使用 5 個不同用戶)
-- 5 條評分記錄(使用 5 個不同用戶)
-- 應用統計數據更新為:25 瀏覽、8 讚、4.2 平均評分
-
-## 驗證
-
-執行完成後,您可以:
-1. 重新載入應用管理頁面
-2. 點擊任何應用的「查看詳情」
-3. 切換到「統計數據」標籤頁查看真實數據
-4. 切換到「評價管理」標籤頁查看評價列表
-
-## 注意事項
-
-- 腳本會先清空現有的測試數據,避免重複
-- **簡化版本**:使用單一用戶 ID,只有 1 條評分記錄
-- **多用戶版本**:使用 5 個不同用戶,平衡數據豐富度和穩定性 ⭐ 推薦
-- **完整版本**:使用不同用戶 ID,需要至少 10 個活躍用戶
-- 如果您的資料庫中用戶數量少於 5 個,建議使用簡化版本
diff --git a/scripts/check-app-competition-relation.js b/scripts/check-app-competition-relation.js
deleted file mode 100644
index d0d644e..0000000
--- a/scripts/check-app-competition-relation.js
+++ /dev/null
@@ -1,72 +0,0 @@
-// =====================================================
-// 檢查APP與競賽的關聯關係
-// =====================================================
-
-const mysql = require('mysql2/promise');
-
-async function checkAppCompetitionRelation() {
- console.log('🔍 檢查APP與競賽的關聯關係...\n');
-
- try {
- // 連接數據庫
- const connection = await mysql.createConnection({
- host: 'mysql.theaken.com',
- port: 33306,
- user: 'AI_Platform',
- password: 'Aa123456',
- database: 'db_AI_Platform'
- });
-
- console.log('✅ 數據庫連接成功');
-
- // 檢查特定APP
- const appId = "7f7395f4-ad9f-4d14-9e2c-84962ecbcfd7";
- console.log(`\n📊 檢查APP ${appId}:`);
-
- // 檢查APP是否存在
- const [apps] = await connection.execute('SELECT * FROM apps WHERE id = ?', [appId]);
- console.log('APP信息:', apps);
-
- // 檢查APP的競賽關聯
- const [competitionApps] = await connection.execute(
- 'SELECT ca.*, c.name as competition_name FROM competition_apps ca LEFT JOIN competitions c ON ca.competition_id = c.id WHERE ca.app_id = ?',
- [appId]
- );
- console.log('競賽關聯:', competitionApps);
-
- // 檢查所有競賽
- console.log('\n📊 所有競賽:');
- const [competitions] = await connection.execute('SELECT id, name, type FROM competitions');
- console.log(competitions);
-
- // 檢查所有競賽APP關聯
- console.log('\n📊 所有競賽APP關聯:');
- const [allCompetitionApps] = await connection.execute('SELECT * FROM competition_apps LIMIT 10');
- console.log(allCompetitionApps);
-
- // 如果沒有關聯,創建一個
- if (competitionApps.length === 0 && apps.length > 0 && competitions.length > 0) {
- console.log('\n🔧 創建APP與競賽的關聯...');
- const competitionId = competitions[0].id;
-
- try {
- await connection.execute(
- 'INSERT INTO competition_apps (id, competition_id, app_id) VALUES (UUID(), ?, ?)',
- [competitionId, appId]
- );
- console.log('✅ 關聯創建成功');
- } catch (error) {
- console.log('❌ 關聯創建失敗:', error.message);
- }
- }
-
- await connection.end();
- console.log('\n✅ 數據庫連接已關閉');
-
- } catch (error) {
- console.error('❌ 檢查失敗:', error.message);
- }
-}
-
-// 執行檢查
-checkAppCompetitionRelation();
diff --git a/scripts/check-competition-data-details.js b/scripts/check-competition-data-details.js
deleted file mode 100644
index 10b7150..0000000
--- a/scripts/check-competition-data-details.js
+++ /dev/null
@@ -1,69 +0,0 @@
-// =====================================================
-// 檢查競賽詳細數據
-// =====================================================
-
-const mysql = require('mysql2/promise');
-
-async function checkCompetitionDataDetails() {
- console.log('🔍 檢查競賽詳細數據...\n');
-
- try {
- // 連接數據庫
- const connection = await mysql.createConnection({
- host: 'mysql.theaken.com',
- port: 33306,
- user: 'AI_Platform',
- password: 'Aa123456',
- database: 'db_AI_Platform'
- });
-
- console.log('✅ 數據庫連接成功');
-
- const competitionId = "be4b0a71-91f1-11f0-bb38-4adff2d0e33e";
-
- // 檢查競賽評審關聯
- console.log('\n📊 競賽評審關聯:');
- const [competitionJudges] = await connection.execute(`
- SELECT cj.*, j.name as judge_name
- FROM competition_judges cj
- LEFT JOIN judges j ON cj.judge_id = j.id
- WHERE cj.competition_id = ?
- `, [competitionId]);
- console.log(competitionJudges);
-
- // 檢查競賽APP關聯
- console.log('\n📊 競賽APP關聯:');
- const [competitionApps] = await connection.execute(`
- SELECT ca.*, a.name as app_name
- FROM competition_apps ca
- LEFT JOIN apps a ON ca.app_id = a.id
- WHERE ca.competition_id = ?
- `, [competitionId]);
- console.log(competitionApps);
-
- // 檢查評分記錄
- console.log('\n📊 評分記錄:');
- const [judgeScores] = await connection.execute(`
- SELECT js.*, j.name as judge_name, a.name as app_name
- FROM judge_scores js
- LEFT JOIN judges j ON js.judge_id = j.id
- LEFT JOIN apps a ON js.app_id = a.id
- WHERE js.competition_id = ?
- `, [competitionId]);
- console.log(judgeScores);
-
- // 檢查所有競賽
- console.log('\n📊 所有競賽:');
- const [competitions] = await connection.execute('SELECT id, name FROM competitions');
- console.log(competitions);
-
- await connection.end();
- console.log('\n✅ 數據庫連接已關閉');
-
- } catch (error) {
- console.error('❌ 檢查失敗:', error.message);
- }
-}
-
-// 執行檢查
-checkCompetitionDataDetails();
diff --git a/scripts/check-competition-data.js b/scripts/check-competition-data.js
deleted file mode 100644
index b57ca11..0000000
--- a/scripts/check-competition-data.js
+++ /dev/null
@@ -1,60 +0,0 @@
-// =====================================================
-// 檢查競賽相關數據
-// =====================================================
-
-const mysql = require('mysql2/promise');
-
-async function checkCompetitionData() {
- console.log('🔍 檢查競賽相關數據...\n');
-
- try {
- // 連接數據庫
- const connection = await mysql.createConnection({
- host: 'mysql.theaken.com',
- port: 33306,
- user: 'AI_Platform',
- password: 'Aa123456',
- database: 'db_AI_Platform'
- });
-
- console.log('✅ 數據庫連接成功');
-
- // 檢查競賽數據
- console.log('\n📊 競賽數據:');
- const [competitions] = await connection.execute('SELECT id, name, type FROM competitions LIMIT 5');
- console.log(competitions);
-
- // 檢查競賽規則
- console.log('\n📊 競賽規則:');
- const [rules] = await connection.execute('SELECT * FROM competition_rules LIMIT 10');
- console.log(rules);
-
- // 檢查競賽APP關聯
- console.log('\n📊 競賽APP關聯:');
- const [competitionApps] = await connection.execute('SELECT * FROM competition_apps LIMIT 10');
- console.log(competitionApps);
-
- // 檢查APP數據
- console.log('\n📊 APP數據:');
- const [apps] = await connection.execute('SELECT id, name, team_id FROM apps LIMIT 5');
- console.log(apps);
-
- // 檢查特定APP的競賽關聯
- const appId = "7f7395f4-ad9f-4d14-9e2c-84962ecbcfd7";
- console.log(`\n📊 APP ${appId} 的競賽關聯:`);
- const [appCompetition] = await connection.execute(
- 'SELECT ca.*, c.name as competition_name FROM competition_apps ca LEFT JOIN competitions c ON ca.competition_id = c.id WHERE ca.app_id = ?',
- [appId]
- );
- console.log(appCompetition);
-
- await connection.end();
- console.log('\n✅ 數據庫連接已關閉');
-
- } catch (error) {
- console.error('❌ 檢查失敗:', error.message);
- }
-}
-
-// 執行檢查
-checkCompetitionData();
diff --git a/scripts/check-env.js b/scripts/check-env.js
deleted file mode 100644
index 554248f..0000000
--- a/scripts/check-env.js
+++ /dev/null
@@ -1,60 +0,0 @@
-// =====================================================
-// 檢查環境變數載入情況
-// =====================================================
-
-console.log('🔍 檢查環境變數載入情況...\n');
-
-// 檢查所有相關的環境變數
-const envVars = [
- 'DB_HOST',
- 'DB_PORT',
- 'DB_NAME',
- 'DB_USER',
- 'DB_PASSWORD',
- 'SLAVE_DB_HOST',
- 'SLAVE_DB_PORT',
- 'SLAVE_DB_NAME',
- 'SLAVE_DB_USER',
- 'SLAVE_DB_PASSWORD',
- 'DB_DUAL_WRITE_ENABLED',
- 'DB_MASTER_PRIORITY'
-];
-
-console.log('📋 環境變數檢查結果:');
-console.log('='.repeat(50));
-
-envVars.forEach(varName => {
- const value = process.env[varName];
- if (value) {
- console.log(`✅ ${varName}: ${value}`);
- } else {
- console.log(`❌ ${varName}: undefined`);
- }
-});
-
-console.log('\n🔍 檢查 .env 文件是否存在...');
-const fs = require('fs');
-const path = require('path');
-
-const envPath = path.join(__dirname, '..', '.env');
-if (fs.existsSync(envPath)) {
- console.log('✅ .env 文件存在');
- console.log('📄 .env 文件內容:');
- console.log('-'.repeat(30));
- const envContent = fs.readFileSync(envPath, 'utf8');
- console.log(envContent);
-} else {
- console.log('❌ .env 文件不存在');
-}
-
-console.log('\n🔍 檢查 Next.js 配置...');
-const nextConfigPath = path.join(__dirname, '..', 'next.config.mjs');
-if (fs.existsSync(nextConfigPath)) {
- console.log('✅ next.config.mjs 存在');
- const nextConfig = fs.readFileSync(nextConfigPath, 'utf8');
- console.log('📄 Next.js 配置內容:');
- console.log('-'.repeat(30));
- console.log(nextConfig);
-} else {
- console.log('❌ next.config.mjs 不存在');
-}
diff --git a/scripts/check-existing-apps.js b/scripts/check-existing-apps.js
deleted file mode 100644
index 058b7d4..0000000
--- a/scripts/check-existing-apps.js
+++ /dev/null
@@ -1,73 +0,0 @@
-// =====================================================
-// 檢查現有的APP記錄
-// =====================================================
-
-async function checkExistingApps() {
- console.log('🔍 檢查現有的APP記錄...\n');
-
- try {
- // 等待服務器啟動
- console.log('⏳ 等待服務器啟動...');
- await new Promise(resolve => setTimeout(resolve, 5000));
-
- try {
- const response = await fetch('http://localhost:3000/api/competitions/be4b0a71-91f1-11f0-bb38-4adff2d0e33e/apps');
- const data = await response.json();
-
- console.log('\n📊 競賽APP列表:');
- console.log('狀態碼:', response.status);
- console.log('APP數量:', data.data?.apps?.length || 0);
-
- if (data.data?.apps?.length > 0) {
- console.log('\n📋 APP列表:');
- data.data.apps.forEach((app, index) => {
- console.log(`${index + 1}. ID: ${app.id}`);
- console.log(` 名稱: ${app.name}`);
- console.log(` 創建者: ${app.creator}`);
- console.log(` 類型: ${app.type}`);
- console.log('---');
- });
- } else {
- console.log('❌ 沒有找到APP記錄');
- }
- } catch (error) {
- console.log('❌ API 調用失敗:', error.message);
- }
-
- // 檢查團隊APP
- try {
- const response = await fetch('http://localhost:3000/api/competitions/be4b0a71-91f1-11f0-bb38-4adff2d0e33e/teams');
- const data = await response.json();
-
- console.log('\n📊 競賽團隊列表:');
- console.log('狀態碼:', response.status);
- console.log('團隊數量:', data.data?.teams?.length || 0);
-
- if (data.data?.teams?.length > 0) {
- console.log('\n📋 團隊列表:');
- data.data.teams.forEach((team, index) => {
- console.log(`${index + 1}. 團隊ID: ${team.id}`);
- console.log(` 團隊名稱: ${team.name}`);
- console.log(` 隊長: ${team.leader_name}`);
- console.log(` APP數量: ${team.apps?.length || 0}`);
- if (team.apps && team.apps.length > 0) {
- team.apps.forEach((app, appIndex) => {
- console.log(` APP ${appIndex + 1}: ${app.id} - ${app.name}`);
- });
- }
- console.log('---');
- });
- } else {
- console.log('❌ 沒有找到團隊記錄');
- }
- } catch (error) {
- console.log('❌ 團隊API調用失敗:', error.message);
- }
-
- } catch (error) {
- console.error('❌ 檢查失敗:', error.message);
- }
-}
-
-// 執行檢查
-checkExistingApps();
diff --git a/scripts/check-server.js b/scripts/check-server.js
deleted file mode 100644
index d691258..0000000
--- a/scripts/check-server.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// =====================================================
-// 檢查服務器狀態腳本
-// =====================================================
-
-async function checkServer() {
- console.log('🔍 檢查服務器狀態...\n');
-
- try {
- // 等待服務器啟動
- console.log('⏳ 等待服務器啟動...');
- await new Promise(resolve => setTimeout(resolve, 5000));
-
- // 測試基本連接
- console.log('🌐 測試基本連接...');
- const response = await fetch('http://localhost:3000/api/test-db');
-
- if (!response.ok) {
- console.error('❌ 服務器回應錯誤:', response.status, response.statusText);
- return;
- }
-
- const data = await response.json();
- console.log('✅ 服務器正常運行');
- console.log('📊 回應數據:', JSON.stringify(data, null, 2));
-
- } catch (error) {
- console.error('❌ 服務器連接失敗:', error.message);
- console.log('\n💡 提示: 請確保開發服務器正在運行 (npm run dev)');
- }
-}
-
-checkServer();
diff --git a/scripts/clear-database.js b/scripts/clear-database.js
deleted file mode 100644
index 5963c11..0000000
--- a/scripts/clear-database.js
+++ /dev/null
@@ -1,34 +0,0 @@
-const mysql = require('mysql2/promise');
-
-async function clearDatabase() {
- const connection = await mysql.createConnection({
- host: 'mysql.theaken.com',
- port: 33306,
- user: 'AI_Platform',
- password: 'Aa123456',
- database: 'db_AI_Platform'
- });
-
- console.log('🗑️ 清空資料庫...');
-
- // 清空所有表(按依賴順序)
- const tables = [
- 'app_judge_scores',
- 'competition_apps',
- 'competition_judges',
- 'apps',
- 'judges',
- 'competitions',
- 'users'
- ];
-
- for (const table of tables) {
- await connection.execute(`DELETE FROM ${table}`);
- console.log(`✅ 清空了 ${table} 表`);
- }
-
- await connection.end();
- console.log('🎉 資料庫清空完成!');
-}
-
-clearDatabase().catch(console.error);
diff --git a/scripts/create-team-scores-table.js b/scripts/create-team-scores-table.js
deleted file mode 100644
index e07abe0..0000000
--- a/scripts/create-team-scores-table.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// =====================================================
-// 創建團隊評分表
-// =====================================================
-
-const mysql = require('mysql2/promise');
-
-async function createTeamScoresTable() {
- console.log('🔧 創建團隊評分表...\n');
-
- try {
- // 連接資料庫
- const connection = await mysql.createConnection({
- host: process.env.DB_HOST || '122.100.99.161',
- port: parseInt(process.env.DB_PORT || '43306'),
- user: process.env.DB_USER || 'AI_Platform',
- password: process.env.DB_PASSWORD || 'Aa123456',
- database: process.env.DB_NAME || 'db_AI_Platform'
- });
-
- console.log('✅ 資料庫連接成功');
-
- // 創建團隊評分表
- const createTableSQL = `
- CREATE TABLE IF NOT EXISTS team_judge_scores (
- id VARCHAR(36) PRIMARY KEY,
- judge_id VARCHAR(36) NOT NULL,
- team_id VARCHAR(36) NOT NULL,
- innovation_score INT NOT NULL CHECK (innovation_score >= 1 AND innovation_score <= 10),
- technical_score INT NOT NULL CHECK (technical_score >= 1 AND technical_score <= 10),
- usability_score INT NOT NULL CHECK (usability_score >= 1 AND usability_score <= 10),
- presentation_score INT NOT NULL CHECK (presentation_score >= 1 AND presentation_score <= 10),
- impact_score INT NOT NULL CHECK (impact_score >= 1 AND impact_score <= 10),
- total_score DECIMAL(5,2) NOT NULL,
- comments TEXT,
- submitted_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-
- FOREIGN KEY (judge_id) REFERENCES judges(id) ON DELETE CASCADE,
- FOREIGN KEY (team_id) REFERENCES teams(id) ON DELETE CASCADE,
- UNIQUE KEY unique_judge_team (judge_id, team_id),
- INDEX idx_judge (judge_id),
- INDEX idx_team (team_id),
- INDEX idx_total_score (total_score)
- )
- `;
-
- await connection.execute(createTableSQL);
- console.log('✅ 團隊評分表創建成功');
-
- // 檢查表是否創建成功
- const [tables] = await connection.execute("SHOW TABLES LIKE 'team_judge_scores'");
- if (tables.length > 0) {
- console.log('✅ 表存在確認成功');
- } else {
- console.log('❌ 表創建失敗');
- }
-
- await connection.end();
- console.log('\n✅ 團隊評分表創建完成!');
-
- } catch (error) {
- console.error('❌ 創建表失敗:', error.message);
- }
-}
-
-// 執行創建
-createTeamScoresTable();
diff --git a/scripts/create-virtual-app-api.js b/scripts/create-virtual-app-api.js
deleted file mode 100644
index 74dee08..0000000
--- a/scripts/create-virtual-app-api.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// =====================================================
-// 通過 API 創建虛擬應用記錄
-// =====================================================
-
-async function createVirtualApp() {
- console.log('🔧 通過 API 創建虛擬應用記錄...\n');
-
- try {
- // 等待服務器啟動
- console.log('⏳ 等待服務器啟動...');
- await new Promise(resolve => setTimeout(resolve, 5000));
-
- // 創建虛擬應用記錄
- const virtualAppData = {
- id: 'team_t1757702332911zcl6iafq1',
- name: '[團隊評分] aaa',
- description: '團隊 aaa 的評分記錄',
- creator_id: '00000000-0000-0000-0000-000000000000',
- category: 'team_scoring',
- type: 'team',
- app_url: null,
- icon: 'Users',
- icon_color: 'from-gray-500 to-gray-600',
- likes_count: 0,
- views_count: 0,
- rating: 0.00,
- is_active: true
- };
-
- console.log('📝 創建虛擬應用數據:');
- console.log(JSON.stringify(virtualAppData, null, 2));
-
- try {
- const response = await fetch('http://localhost:3000/api/apps', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(virtualAppData)
- });
-
- const data = await response.json();
-
- console.log('\n📊 API 回應:');
- console.log('狀態碼:', response.status);
- console.log('回應數據:', JSON.stringify(data, null, 2));
-
- if (data.success) {
- console.log('✅ 虛擬應用創建成功!');
- } else {
- console.log('❌ 虛擬應用創建失敗:', data.message);
- if (data.error) {
- console.log('錯誤詳情:', data.error);
- }
- }
- } catch (error) {
- console.log('❌ API 調用失敗:', error.message);
- }
-
- } catch (error) {
- console.error('❌ 測試失敗:', error.message);
- }
-}
-
-// 執行創建
-createVirtualApp();
diff --git a/scripts/create-virtual-app-simple.sql b/scripts/create-virtual-app-simple.sql
deleted file mode 100644
index d3671e9..0000000
--- a/scripts/create-virtual-app-simple.sql
+++ /dev/null
@@ -1,18 +0,0 @@
--- 創建虛擬應用記錄用於團隊評分
-INSERT IGNORE INTO apps (
- id, name, description, creator_id, category, type,
- app_url, icon, icon_color, likes_count, views_count,
- rating, is_active, created_at, updated_at
-) VALUES (
- 'team_t1757702332911zcl6iafq1',
- '[團隊評分] aaa',
- '團隊 aaa 的評分記錄',
- '00000000-0000-0000-0000-000000000000',
- 'team_scoring',
- 'team',
- NULL, 'Users', 'from-gray-500 to-gray-600',
- 0, 0, 0.00, TRUE, NOW(), NOW()
-);
-
--- 驗證創建結果
-SELECT id, name, type FROM apps WHERE id = 'team_t1757702332911zcl6iafq1';
diff --git a/scripts/create-virtual-apps-api.js b/scripts/create-virtual-apps-api.js
deleted file mode 100644
index b13797d..0000000
--- a/scripts/create-virtual-apps-api.js
+++ /dev/null
@@ -1,83 +0,0 @@
-// =====================================================
-// 通過 API 創建虛擬應用記錄
-// =====================================================
-
-async function createVirtualAppsViaAPI() {
- console.log('🔧 通過 API 創建虛擬應用記錄...\n');
-
- try {
- // 等待服務器啟動
- console.log('⏳ 等待服務器啟動...');
- await new Promise(resolve => setTimeout(resolve, 3000));
-
- // 獲取團隊數據
- console.log('📋 獲取團隊數據...');
- const teamsResponse = await fetch('http://localhost:3000/api/competitions');
- const competitionsData = await teamsResponse.json();
-
- if (!competitionsData.success || !competitionsData.data || competitionsData.data.length === 0) {
- console.log('❌ 無法獲取競賽數據');
- return;
- }
-
- const competition = competitionsData.data[0];
- console.log('🎯 選擇競賽:', competition.name);
-
- // 獲取競賽的團隊數據
- const teamsDataResponse = await fetch(`http://localhost:3000/api/competitions/${competition.id}/teams`);
- const teamsData = await teamsDataResponse.json();
-
- if (!teamsData.success || !teamsData.data.teams || teamsData.data.teams.length === 0) {
- console.log('❌ 競賽沒有團隊數據');
- return;
- }
-
- const teams = teamsData.data.teams;
- console.log('✅ 獲取到', teams.length, '個團隊');
-
- // 為每個團隊創建虛擬應用
- for (const team of teams) {
- const virtualAppData = {
- name: `[團隊評分] ${team.name}`,
- description: `團隊 ${team.name} 的評分記錄`,
- creator_id: '00000000-0000-0000-0000-000000000000', // 虛擬創建者ID
- category: 'team_scoring',
- type: 'team',
- app_url: null,
- icon: 'Users',
- icon_color: 'from-gray-500 to-gray-600'
- };
-
- console.log(`📝 創建虛擬應用: ${team.name}...`);
-
- try {
- const response = await fetch('http://localhost:3000/api/apps', {
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json',
- },
- body: JSON.stringify(virtualAppData)
- });
-
- const data = await response.json();
-
- if (data.success) {
- console.log(`✅ 虛擬應用創建成功: ${data.app?.id || '未知ID'}`);
- } else {
- console.log(`⚠️ 虛擬應用創建失敗: ${data.message}`);
- }
- } catch (error) {
- console.log(`❌ 創建虛擬應用時出錯: ${error.message}`);
- }
- }
-
- console.log('\n✅ 虛擬應用記錄創建完成!');
-
- } catch (error) {
- console.error('❌ 創建虛擬應用失敗:', error.message);
- console.log('\n💡 提示: 請確保開發服務器正在運行 (npm run dev)');
- }
-}
-
-// 執行創建
-createVirtualAppsViaAPI();
diff --git a/scripts/create-virtual-apps.js b/scripts/create-virtual-apps.js
deleted file mode 100644
index 7889e4c..0000000
--- a/scripts/create-virtual-apps.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// =====================================================
-// 創建虛擬應用記錄用於團隊評分
-// =====================================================
-
-const mysql = require('mysql2/promise');
-
-async function createVirtualApps() {
- console.log('🔧 創建虛擬應用記錄...\n');
-
- try {
- // 連接資料庫
- const connection = await mysql.createConnection({
- host: process.env.DB_HOST || '122.100.99.161',
- port: parseInt(process.env.DB_PORT || '43306'),
- user: process.env.DB_USER || 'AI_Platform',
- password: process.env.DB_PASSWORD || 'Aa123456',
- database: process.env.DB_NAME || 'db_AI_Platform'
- });
-
- console.log('✅ 資料庫連接成功');
-
- // 獲取所有團隊
- const [teams] = await connection.execute('SELECT id, name FROM teams WHERE is_active = TRUE');
- console.log('📋 找到', teams.length, '個團隊');
-
- // 為每個團隊創建虛擬應用
- for (const team of teams) {
- const virtualAppId = `team_${team.id}`;
-
- // 檢查是否已存在
- const [existing] = await connection.execute('SELECT id FROM apps WHERE id = ?', [virtualAppId]);
-
- if (existing.length === 0) {
- const sql = `
- INSERT INTO apps (id, name, description, creator_id, category, type, app_url, icon, icon_color, likes_count, views_count, rating, is_active, created_at, updated_at)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())
- `;
-
- const params = [
- virtualAppId,
- `[團隊評分] ${team.name}`,
- `團隊 ${team.name} 的評分記錄`,
- '00000000-0000-0000-0000-000000000000', // 虛擬創建者ID
- 'team_scoring',
- 'team',
- null,
- 'Users',
- 'from-gray-500 to-gray-600',
- 0,
- 0,
- 0.00,
- true
- ];
-
- await connection.execute(sql, params);
- console.log(`✅ 創建虛擬應用: ${virtualAppId} (${team.name})`);
- } else {
- console.log(`⏭️ 虛擬應用已存在: ${virtualAppId}`);
- }
- }
-
- await connection.end();
- console.log('\n✅ 虛擬應用記錄創建完成!');
-
- } catch (error) {
- console.error('❌ 創建虛擬應用失敗:', error.message);
- }
-}
-
-// 執行創建
-createVirtualApps();
diff --git a/scripts/fix-foreign-key-constraint.sql b/scripts/fix-foreign-key-constraint.sql
deleted file mode 100644
index bece863..0000000
--- a/scripts/fix-foreign-key-constraint.sql
+++ /dev/null
@@ -1,107 +0,0 @@
--- =====================================================
--- 修復外鍵約束問題的 SQL 腳本
--- =====================================================
-
--- 問題:app_judge_scores 表的 app_id 外鍵約束失敗
--- 原因:團隊評分使用的 teamId 不存在於 apps 表中
-
--- 解決方案:為團隊創建對應的虛擬應用記錄
-
--- 1. 先查看現有的團隊數據
-SELECT '=== 現有團隊 ===' as info;
-SELECT id, name, department FROM teams WHERE is_active = TRUE;
-
--- 2. 為團隊 t1757702332911zcl6iafq1 (aaa) 創建虛擬應用
-INSERT IGNORE INTO apps (
- id,
- name,
- description,
- creator_id,
- category,
- type,
- app_url,
- icon,
- icon_color,
- likes_count,
- views_count,
- rating,
- is_active,
- created_at,
- updated_at
-) VALUES (
- 'team_t1757702332911zcl6iafq1',
- '[團隊評分] aaa',
- '團隊 aaa 的評分記錄 - 用於存儲團隊評分數據',
- '00000000-0000-0000-0000-000000000000',
- 'team_scoring',
- 'team',
- NULL,
- 'Users',
- 'from-gray-500 to-gray-600',
- 0,
- 0,
- 0.00,
- TRUE,
- NOW(),
- NOW()
-);
-
--- 3. 驗證虛擬應用是否創建成功
-SELECT '=== 虛擬應用創建結果 ===' as info;
-SELECT id, name, type, category, is_active FROM apps WHERE id = 'team_t1757702332911zcl6iafq1';
-
--- 4. 現在可以插入團隊評分記錄了
--- 測試插入團隊評分(使用真實的評審ID)
-INSERT INTO app_judge_scores (
- id,
- judge_id,
- app_id,
- innovation_score,
- technical_score,
- usability_score,
- presentation_score,
- impact_score,
- total_score,
- comments,
- submitted_at
-) VALUES (
- UUID(),
- 'fed0a353-8ffe-11f0-bb38-4adff2d0e33e', -- 評審ID
- 'team_t1757702332911zcl6iafq1', -- 虛擬應用ID
- 8, -- innovation_score
- 7, -- technical_score
- 9, -- usability_score
- 8, -- presentation_score
- 7, -- impact_score
- 7.8, -- total_score (平均分)
- '測試團隊評分記錄',
- NOW()
-);
-
--- 5. 驗證評分記錄是否插入成功
-SELECT '=== 評分記錄插入結果 ===' as info;
-SELECT
- ajs.id,
- ajs.judge_id,
- ajs.app_id,
- ajs.innovation_score,
- ajs.technical_score,
- ajs.usability_score,
- ajs.presentation_score,
- ajs.impact_score,
- ajs.total_score,
- ajs.comments,
- ajs.submitted_at,
- a.name as app_name
-FROM app_judge_scores ajs
-LEFT JOIN apps a ON ajs.app_id = a.id
-WHERE ajs.app_id = 'team_t1757702332911zcl6iafq1'
-ORDER BY ajs.submitted_at DESC;
-
--- 6. 如果有其他團隊,也需要創建對應的虛擬應用
--- 格式:team_{teamId}
--- 例如:team_另一個團隊ID
-
--- 7. 清理測試數據(可選)
--- DELETE FROM app_judge_scores WHERE app_id = 'team_t1757702332911zcl6iafq1';
--- DELETE FROM apps WHERE id = 'team_t1757702332911zcl6iafq1';
diff --git a/scripts/populate-sample-data.js b/scripts/populate-sample-data.js
deleted file mode 100644
index ec41f06..0000000
--- a/scripts/populate-sample-data.js
+++ /dev/null
@@ -1,319 +0,0 @@
-#!/usr/bin/env node
-
-// =====================================================
-// 填充示例數據腳本
-// =====================================================
-
-const mysql = require('mysql2/promise');
-const { v4: uuidv4 } = require('uuid');
-
-// 資料庫配置
-const dbConfig = {
- host: process.env.DB_HOST || 'mysql.theaken.com',
- port: parseInt(process.env.DB_PORT || '33306'),
- user: process.env.DB_USER || 'AI_Platform',
- password: process.env.DB_PASSWORD || 'Aa123456',
- database: process.env.DB_NAME || 'db_AI_Platform',
- charset: 'utf8mb4',
- timezone: '+08:00',
-};
-
-async function populateSampleData() {
- let connection;
-
- try {
- console.log('🚀 開始填充示例數據...');
-
- // 創建連接
- connection = await mysql.createConnection(dbConfig);
- console.log('✅ 資料庫連接成功');
-
- // 1. 創建示例用戶
- console.log('👥 創建示例用戶...');
- const users = [
- {
- id: uuidv4(),
- name: '張小明',
- email: 'zhang.xiaoming@company.com',
- password_hash: '$2b$10$example.hash.here', // 示例哈希
- department: 'HQBU',
- role: 'developer',
- join_date: '2024-01-15',
- total_likes: 25,
- total_views: 150,
- is_active: true
- },
- {
- id: uuidv4(),
- name: '李美華',
- email: 'li.meihua@company.com',
- password_hash: '$2b$10$example.hash.here',
- department: 'ITBU',
- role: 'developer',
- join_date: '2024-02-01',
- total_likes: 18,
- total_views: 120,
- is_active: true
- },
- {
- id: uuidv4(),
- name: '王大偉',
- email: 'wang.dawei@company.com',
- password_hash: '$2b$10$example.hash.here',
- department: 'MBU1',
- role: 'developer',
- join_date: '2024-01-20',
- total_likes: 32,
- total_views: 200,
- is_active: true
- },
- {
- id: uuidv4(),
- name: '陳小芳',
- email: 'chen.xiaofang@company.com',
- password_hash: '$2b$10$example.hash.here',
- department: 'SBU',
- role: 'developer',
- join_date: '2024-02-10',
- total_likes: 15,
- total_views: 90,
- is_active: true
- },
- {
- id: uuidv4(),
- name: '劉志強',
- email: 'liu.zhiqiang@company.com',
- password_hash: '$2b$10$example.hash.here',
- department: 'HQBU',
- role: 'admin',
- join_date: '2023-12-01',
- total_likes: 5,
- total_views: 50,
- is_active: true
- }
- ];
-
- for (const user of users) {
- await connection.execute(
- `INSERT INTO users (id, name, email, password_hash, department, role, join_date, total_likes, total_views, status, created_at, updated_at)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())`,
- [user.id, user.name, user.email, user.password_hash, user.department, user.role, user.join_date, user.total_likes, user.total_views, 'active']
- );
- }
- console.log(`✅ 創建了 ${users.length} 個用戶`);
-
- // 2. 創建示例評審
- console.log('👨⚖️ 創建示例評審...');
- const judges = [
- {
- id: uuidv4(),
- name: '王教授',
- title: '技術總監',
- department: 'ITBU',
- expertise: JSON.stringify(['AI', '機器學習', '深度學習']),
- is_active: true
- },
- {
- id: uuidv4(),
- name: '李博士',
- title: '產品經理',
- department: 'HQBU',
- expertise: JSON.stringify(['產品設計', '用戶體驗', '商業分析']),
- is_active: true
- },
- {
- id: uuidv4(),
- name: '陳工程師',
- title: '資深工程師',
- department: 'MBU1',
- expertise: JSON.stringify(['軟體開發', '系統架構', '資料庫']),
- is_active: true
- }
- ];
-
- for (const judge of judges) {
- await connection.execute(
- `INSERT INTO judges (id, name, title, department, expertise, is_active, created_at, updated_at)
- VALUES (?, ?, ?, ?, ?, ?, NOW(), NOW())`,
- [judge.id, judge.name, judge.title, judge.department, judge.expertise, judge.is_active]
- );
- }
- console.log(`✅ 創建了 ${judges.length} 個評審`);
-
- // 3. 創建示例競賽
- console.log('🏆 創建示例競賽...');
- const competitions = [
- {
- id: uuidv4(),
- name: '2024年AI創新競賽',
- description: '展示最新的AI技術創新成果',
- type: 'individual',
- year: 2024,
- month: 3,
- start_date: '2024-03-01',
- end_date: '2024-03-31',
- status: 'active',
- is_current: true,
- is_active: true,
- evaluation_focus: JSON.stringify(['創新性', '技術性', '實用性']),
- max_team_size: 5
- },
- {
- id: uuidv4(),
- name: '2024年團隊協作競賽',
- description: '團隊協作開發的AI應用',
- type: 'team',
- year: 2024,
- month: 4,
- start_date: '2024-04-01',
- end_date: '2024-04-30',
- status: 'upcoming',
- is_current: false,
- is_active: true,
- evaluation_focus: JSON.stringify(['團隊協作', '技術實現', '創新應用']),
- max_team_size: 8
- }
- ];
-
- for (const competition of competitions) {
- await connection.execute(
- `INSERT INTO competitions (id, name, description, type, year, month, start_date, end_date, status, is_current, is_active, evaluation_focus, max_team_size, created_at, updated_at)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())`,
- [competition.id, competition.name, competition.description, competition.type, competition.year, competition.month,
- competition.start_date, competition.end_date, competition.status, competition.is_current, competition.is_active,
- competition.evaluation_focus, competition.max_team_size]
- );
- }
- console.log(`✅ 創建了 ${competitions.length} 個競賽`);
-
- // 4. 創建示例應用
- console.log('📱 創建示例應用...');
- const apps = [
- {
- id: uuidv4(),
- name: '智能對話助手',
- description: '基於大語言模型的智能對話系統',
- creator_id: users[0].id,
- team_id: null,
- category: '文字處理',
- technology_stack: JSON.stringify(['Python', 'OpenAI API', 'React']),
- github_url: 'https://github.com/example/chatbot',
- demo_url: 'https://demo.example.com/chatbot',
- status: 'published',
- is_active: true,
- total_likes: 25,
- total_views: 150
- },
- {
- id: uuidv4(),
- name: '圖像生成工具',
- description: 'AI驅動的創意圖像生成平台',
- creator_id: users[1].id,
- team_id: null,
- category: '圖像生成',
- technology_stack: JSON.stringify(['Python', 'Stable Diffusion', 'FastAPI']),
- github_url: 'https://github.com/example/image-gen',
- demo_url: 'https://demo.example.com/image-gen',
- status: 'published',
- is_active: true,
- total_likes: 18,
- total_views: 120
- },
- {
- id: uuidv4(),
- name: '語音識別系統',
- description: '高精度多語言語音識別服務',
- creator_id: users[2].id,
- team_id: null,
- category: '語音辨識',
- technology_stack: JSON.stringify(['Python', 'Whisper', 'Docker']),
- github_url: 'https://github.com/example/speech-recognition',
- demo_url: 'https://demo.example.com/speech',
- status: 'published',
- is_active: true,
- total_likes: 32,
- total_views: 200
- }
- ];
-
- for (const app of apps) {
- await connection.execute(
- `INSERT INTO apps (id, name, description, creator_id, team_id, category, type, app_url, likes_count, views_count, is_active, created_at, updated_at)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW(), NOW())`,
- [app.id, app.name, app.description, app.creator_id, app.team_id, app.category, 'web', app.demo_url, app.total_likes, app.total_views, 1]
- );
- }
- console.log(`✅ 創建了 ${apps.length} 個應用`);
-
- // 5. 關聯競賽和應用
- console.log('🔗 關聯競賽和應用...');
- const currentCompetition = competitions[0]; // 當前競賽
- for (const app of apps) {
- await connection.execute(
- `INSERT INTO competition_apps (id, competition_id, app_id, submitted_at) VALUES (?, ?, ?, NOW())`,
- [uuidv4(), currentCompetition.id, app.id]
- );
- }
- console.log(`✅ 關聯了 ${apps.length} 個應用到當前競賽`);
-
- // 6. 關聯競賽和評審
- console.log('🔗 關聯競賽和評審...');
- for (const judge of judges) {
- await connection.execute(
- `INSERT INTO competition_judges (id, competition_id, judge_id, assigned_at) VALUES (?, ?, ?, NOW())`,
- [uuidv4(), currentCompetition.id, judge.id]
- );
- }
- console.log(`✅ 關聯了 ${judges.length} 個評審到當前競賽`);
-
- // 7. 創建示例評分
- console.log('📊 創建示例評分...');
- for (const app of apps) {
- for (const judge of judges) {
- const scores = {
- innovation_score: Math.floor(Math.random() * 5) + 1,
- technical_score: Math.floor(Math.random() * 5) + 1,
- usability_score: Math.floor(Math.random() * 5) + 1,
- presentation_score: Math.floor(Math.random() * 5) + 1,
- impact_score: Math.floor(Math.random() * 5) + 1
- };
-
- const totalScore = (scores.innovation_score + scores.technical_score + scores.usability_score +
- scores.presentation_score + scores.impact_score) / 5;
-
- await connection.execute(
- `INSERT INTO app_judge_scores (id, judge_id, app_id, innovation_score, technical_score, usability_score, presentation_score, impact_score, total_score, comments, submitted_at)
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, NOW())`,
- [uuidv4(), judge.id, app.id, scores.innovation_score, scores.technical_score, scores.usability_score,
- scores.presentation_score, scores.impact_score, totalScore, '示例評分']
- );
- }
- }
- console.log(`✅ 創建了 ${apps.length * judges.length} 個評分記錄`);
-
- console.log('🎉 示例數據填充完成!');
- console.log('\n📊 數據摘要:');
- console.log(`- 用戶: ${users.length} 個`);
- console.log(`- 評審: ${judges.length} 個`);
- console.log(`- 競賽: ${competitions.length} 個 (其中 1 個為當前競賽)`);
- console.log(`- 應用: ${apps.length} 個`);
- console.log(`- 評分記錄: ${apps.length * judges.length} 個`);
-
- } catch (error) {
- console.error('❌ 填充失敗:', error.message);
- console.error('詳細錯誤:', error);
- process.exit(1);
- } finally {
- if (connection) {
- await connection.end();
- console.log('🔌 資料庫連接已關閉');
- }
- }
-}
-
-// 執行填充
-if (require.main === module) {
- populateSampleData().catch(console.error);
-}
-
-module.exports = { populateSampleData };
diff --git a/scripts/quick-fix.sql b/scripts/quick-fix.sql
deleted file mode 100644
index 9e61f1e..0000000
--- a/scripts/quick-fix.sql
+++ /dev/null
@@ -1,22 +0,0 @@
--- =====================================================
--- 快速修復外鍵約束問題
--- =====================================================
-
--- 插入虛擬應用記錄
-INSERT IGNORE INTO apps (
- id, name, description, creator_id, category, type,
- app_url, icon, icon_color, likes_count, views_count,
- rating, is_active, created_at, updated_at
-) VALUES (
- 'team_t1757702332911zcl6iafq1',
- '[團隊評分] aaa',
- '團隊 aaa 的評分記錄',
- '00000000-0000-0000-0000-000000000000',
- 'team_scoring',
- 'team',
- NULL, 'Users', 'from-gray-500 to-gray-600',
- 0, 0, 0.00, TRUE, NOW(), NOW()
-);
-
--- 驗證創建結果
-SELECT id, name, type FROM apps WHERE id = 'team_t1757702332911zcl6iafq1';
diff --git a/scripts/redesign-scoring-database.sql b/scripts/redesign-scoring-database.sql
deleted file mode 100644
index b8f3390..0000000
--- a/scripts/redesign-scoring-database.sql
+++ /dev/null
@@ -1,145 +0,0 @@
--- =====================================================
--- 重新設計評分數據庫架構
--- 讓評分系統完全基於 competition_rules 的動態內容
--- =====================================================
-
--- 1. 創建新的評分記錄表(基於競賽規則)
-CREATE TABLE `judge_scores` (
- `id` VARCHAR(36) PRIMARY KEY,
- `judge_id` VARCHAR(36) NOT NULL,
- `app_id` VARCHAR(36) NOT NULL,
- `competition_id` VARCHAR(36) NOT NULL,
- `total_score` DECIMAL(5,2) NOT NULL,
- `comments` TEXT,
- `submitted_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-
- FOREIGN KEY (`judge_id`) REFERENCES `judges`(`id`) ON DELETE CASCADE,
- FOREIGN KEY (`app_id`) REFERENCES `apps`(`id`) ON DELETE CASCADE,
- FOREIGN KEY (`competition_id`) REFERENCES `competitions`(`id`) ON DELETE CASCADE,
- UNIQUE KEY `unique_judge_app_competition` (`judge_id`, `app_id`, `competition_id`),
- INDEX `idx_judge` (`judge_id`),
- INDEX `idx_app` (`app_id`),
- INDEX `idx_competition` (`competition_id`),
- INDEX `idx_total_score` (`total_score`)
-);
-
--- 2. 創建評分項目詳情表(存儲具體的評分項目和分數)
-CREATE TABLE `judge_score_details` (
- `id` VARCHAR(36) PRIMARY KEY,
- `judge_score_id` VARCHAR(36) NOT NULL,
- `rule_id` VARCHAR(36) NOT NULL,
- `rule_name` VARCHAR(200) NOT NULL,
- `score` INT NOT NULL CHECK (`score` >= 1 AND `score` <= 10),
- `weight` DECIMAL(5,2) NOT NULL DEFAULT 0.00,
- `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
-
- FOREIGN KEY (`judge_score_id`) REFERENCES `judge_scores`(`id`) ON DELETE CASCADE,
- FOREIGN KEY (`rule_id`) REFERENCES `competition_rules`(`id`) ON DELETE CASCADE,
- UNIQUE KEY `unique_score_rule` (`judge_score_id`, `rule_id`),
- INDEX `idx_judge_score` (`judge_score_id`),
- INDEX `idx_rule` (`rule_id`)
-);
-
--- 3. 備份現有的 app_judge_scores 數據(如果需要)
-CREATE TABLE `app_judge_scores_backup` AS SELECT * FROM `app_judge_scores`;
-
--- 4. 遷移現有數據到新結構
-INSERT INTO `judge_scores` (
- `id`, `judge_id`, `app_id`, `competition_id`, `total_score`, `comments`, `submitted_at`
-)
-SELECT
- `id`,
- `judge_id`,
- `app_id`,
- COALESCE(
- (SELECT ca.competition_id FROM competition_apps ca WHERE ca.app_id = ajs.app_id LIMIT 1),
- 'unknown-competition'
- ) as competition_id,
- `total_score`,
- `comments`,
- `submitted_at`
-FROM `app_judge_scores` ajs;
-
--- 5. 遷移評分詳情數據
-INSERT INTO `judge_score_details` (
- `id`, `judge_score_id`, `rule_id`, `rule_name`, `score`, `weight`
-)
-SELECT
- UUID() as id,
- ajs.id as judge_score_id,
- 'migration-innovation' as rule_id,
- '創新程度' as rule_name,
- ajs.innovation_score as score,
- 20.00 as weight
-FROM `app_judge_scores` ajs
-WHERE ajs.innovation_score > 0
-
-UNION ALL
-
-SELECT
- UUID() as id,
- ajs.id as judge_score_id,
- 'migration-technical' as rule_id,
- '技術實現' as rule_name,
- ajs.technical_score as score,
- 20.00 as weight
-FROM `app_judge_scores` ajs
-WHERE ajs.technical_score > 0
-
-UNION ALL
-
-SELECT
- UUID() as id,
- ajs.id as judge_score_id,
- 'migration-usability' as rule_id,
- '實用性' as rule_name,
- ajs.usability_score as score,
- 20.00 as weight
-FROM `app_judge_scores` ajs
-WHERE ajs.usability_score > 0
-
-UNION ALL
-
-SELECT
- UUID() as id,
- ajs.id as judge_score_id,
- 'migration-presentation' as rule_id,
- '展示效果' as rule_name,
- ajs.presentation_score as score,
- 20.00 as weight
-FROM `app_judge_scores` ajs
-WHERE ajs.presentation_score > 0
-
-UNION ALL
-
-SELECT
- UUID() as id,
- ajs.id as judge_score_id,
- 'migration-impact' as rule_id,
- '影響力' as rule_name,
- ajs.impact_score as score,
- 20.00 as weight
-FROM `app_judge_scores` ajs
-WHERE ajs.impact_score > 0;
-
--- 6. 刪除舊的 app_judge_scores 表
--- DROP TABLE `app_judge_scores`;
-
--- 7. 創建視圖以保持向後兼容性
-CREATE VIEW `app_judge_scores` AS
-SELECT
- js.id,
- js.judge_id,
- js.app_id,
- js.total_score,
- js.comments,
- js.submitted_at,
- -- 動態生成評分字段(基於競賽規則)
- COALESCE(MAX(CASE WHEN jsd.rule_name = '創新程度' THEN jsd.score END), 0) as innovation_score,
- COALESCE(MAX(CASE WHEN jsd.rule_name = '技術實現' THEN jsd.score END), 0) as technical_score,
- COALESCE(MAX(CASE WHEN jsd.rule_name = '實用性' THEN jsd.score END), 0) as usability_score,
- COALESCE(MAX(CASE WHEN jsd.rule_name = '展示效果' THEN jsd.score END), 0) as presentation_score,
- COALESCE(MAX(CASE WHEN jsd.rule_name = '影響力' THEN jsd.score END), 0) as impact_score
-FROM `judge_scores` js
-LEFT JOIN `judge_score_details` jsd ON js.id = jsd.judge_score_id
-GROUP BY js.id, js.judge_id, js.app_id, js.total_score, js.comments, js.submitted_at;
diff --git a/scripts/test-invitation-link.js b/scripts/test-invitation-link.js
deleted file mode 100644
index 2cca5a1..0000000
--- a/scripts/test-invitation-link.js
+++ /dev/null
@@ -1,47 +0,0 @@
-// 測試邀請連結生成
-console.log('🧪 測試邀請連結生成...\n');
-
-// 模擬環境變數
-process.env.NEXT_PUBLIC_APP_URL = 'https://ai-showcase.company.com';
-
-// 測試不同的環境變數設置
-const testCases = [
- {
- name: '使用 NEXT_PUBLIC_APP_URL',
- env: { NEXT_PUBLIC_APP_URL: 'https://ai-showcase.company.com' }
- },
- {
- name: '未設置 NEXT_PUBLIC_APP_URL (使用 fallback)',
- env: {}
- },
- {
- name: '設置為空字符串 (使用 fallback)',
- env: { NEXT_PUBLIC_APP_URL: '' }
- }
-];
-
-testCases.forEach((testCase, index) => {
- console.log(`${index + 1}. ${testCase.name}`);
-
- // 設置環境變數
- Object.keys(testCase.env).forEach(key => {
- process.env[key] = testCase.env[key];
- });
-
- // 生成邀請連結
- const invitationToken = 'test123456789';
- const email = 'test@company.com';
- const role = 'developer';
-
- const invitationLink = `${process.env.NEXT_PUBLIC_APP_URL || 'http://localhost:3000'}/register?token=${invitationToken}&email=${encodeURIComponent(email)}&role=${role}`;
-
- console.log(` 邀請連結: ${invitationLink}`);
- console.log(` 環境變數: NEXT_PUBLIC_APP_URL = ${process.env.NEXT_PUBLIC_APP_URL || 'undefined'}`);
- console.log('');
-});
-
-console.log('✅ 測試完成!');
-console.log('\n📝 說明:');
-console.log('- 如果設置了 NEXT_PUBLIC_APP_URL,將使用該值');
-console.log('- 如果未設置或為空,將使用 fallback: http://localhost:3000');
-console.log('- 在生產環境中,請確保設置正確的 NEXT_PUBLIC_APP_URL');
diff --git a/scripts/test-scoring-progress.js b/scripts/test-scoring-progress.js
deleted file mode 100644
index 6fdbba6..0000000
--- a/scripts/test-scoring-progress.js
+++ /dev/null
@@ -1,51 +0,0 @@
-// =====================================================
-// 測試評分進度功能
-// =====================================================
-
-async function testScoringProgress() {
- console.log('🔧 測試評分進度功能...\n');
-
- try {
- // 等待服務器啟動
- console.log('⏳ 等待服務器啟動...');
- await new Promise(resolve => setTimeout(resolve, 5000));
-
- // 獲取競賽列表
- console.log('📊 獲取競賽列表...');
- const competitionsResponse = await fetch('http://localhost:3000/api/competitions');
- const competitionsData = await competitionsResponse.json();
-
- if (!competitionsData.success || !competitionsData.data || competitionsData.data.length === 0) {
- console.log('❌ 沒有找到競賽數據');
- return;
- }
-
- const competition = competitionsData.data[0];
- console.log('✅ 找到競賽:', competition.name, '(ID:', competition.id + ')');
-
- // 測試評分進度 API
- console.log('\n📊 測試評分進度 API...');
- const progressResponse = await fetch(`http://localhost:3000/api/competitions/scoring-progress?competitionId=${competition.id}`);
- const progressData = await progressResponse.json();
-
- console.log('📊 評分進度 API 回應:');
- console.log('狀態碼:', progressResponse.status);
- console.log('回應數據:', JSON.stringify(progressData, null, 2));
-
- if (progressData.success) {
- console.log('✅ 評分進度獲取成功!');
- console.log(`📈 評分進度: ${progressData.data.completed}/${progressData.data.total} (${progressData.data.percentage}%)`);
- } else {
- console.log('❌ 評分進度獲取失敗:', progressData.message);
- if (progressData.error) {
- console.log('錯誤詳情:', progressData.error);
- }
- }
-
- } catch (error) {
- console.error('❌ 測試失敗:', error.message);
- }
-}
-
-// 執行測試
-testScoringProgress();
diff --git a/scripts/test-scoring-summary.js b/scripts/test-scoring-summary.js
deleted file mode 100644
index 35c443b..0000000
--- a/scripts/test-scoring-summary.js
+++ /dev/null
@@ -1,79 +0,0 @@
-// =====================================================
-// 測試評分完成度匯總功能
-// =====================================================
-
-async function testScoringSummary() {
- console.log('🔧 測試評分完成度匯總功能...\n');
-
- try {
- // 等待服務器啟動
- console.log('⏳ 等待服務器啟動...');
- await new Promise(resolve => setTimeout(resolve, 5000));
-
- // 獲取競賽列表
- console.log('📊 獲取競賽列表...');
- const competitionsResponse = await fetch('http://localhost:3000/api/competitions');
- const competitionsData = await competitionsResponse.json();
-
- if (!competitionsData.success || !competitionsData.data || competitionsData.data.length === 0) {
- console.log('❌ 沒有找到競賽數據');
- return;
- }
-
- const competition = competitionsData.data[0];
- console.log('✅ 找到競賽:', competition.name, '(ID:', competition.id + ')');
-
- // 測試評分完成度匯總 API
- console.log('\n📊 測試評分完成度匯總 API...');
- const summaryResponse = await fetch(`http://localhost:3000/api/admin/scoring/summary?competitionId=${competition.id}`);
- const summaryData = await summaryResponse.json();
-
- console.log('📊 評分完成度匯總 API 回應:');
- console.log('狀態碼:', summaryResponse.status);
- console.log('回應數據:', JSON.stringify(summaryData, null, 2));
-
- if (summaryData.success) {
- console.log('✅ 評分完成度匯總獲取成功!');
-
- const { judges, apps, overallStats } = summaryData.data;
-
- console.log('\n📈 總體統計:');
- console.log(`- 評審總數: ${overallStats.totalJudges}`);
- console.log(`- 參賽APP數: ${overallStats.totalApps}`);
- console.log(`- 已完成評分: ${overallStats.completedScores}`);
- console.log(`- 總完成率: ${overallStats.overallCompletionRate}%`);
-
- console.log('\n👨⚖️ 評審完成度:');
- judges.forEach((judge, index) => {
- console.log(`${index + 1}. ${judge.name} (${judge.email})`);
- console.log(` - 完成度: ${judge.completedCount}/${judge.totalCount} (${judge.completionRate}%)`);
- console.log(` - 狀態: ${judge.status}`);
- if (judge.lastScoredAt) {
- console.log(` - 最後評分時間: ${judge.lastScoredAt}`);
- }
- });
-
- console.log('\n📱 參賽APP完成度:');
- apps.forEach((app, index) => {
- console.log(`${index + 1}. ${app.name}${app.teamName ? ` (團隊: ${app.teamName})` : ''}`);
- console.log(` - 完成度: ${app.scoredCount}/${app.totalJudges} 評審 (${app.completionRate}%)`);
- console.log(` - 狀態: ${app.status}`);
- if (app.averageScore) {
- console.log(` - 平均分: ${app.averageScore}`);
- }
- });
-
- } else {
- console.log('❌ 評分完成度匯總獲取失敗:', summaryData.message);
- if (summaryData.error) {
- console.log('錯誤詳情:', summaryData.error);
- }
- }
-
- } catch (error) {
- console.error('❌ 測試失敗:', error.message);
- }
-}
-
-// 執行測試
-testScoringSummary();