feat: Migrate to MySQL and add unified environment configuration
## Database Migration (SQLite → MySQL) - Add Alembic migration framework - Add 'tr_' prefix to all tables to avoid conflicts in shared database - Remove SQLite support, use MySQL exclusively - Add pymysql driver dependency - Change ad_token column to Text type for long JWT tokens ## Unified Environment Configuration - Centralize all hardcoded settings to environment variables - Backend: Extend Settings class in app/core/config.py - Frontend: Use Vite environment variables (import.meta.env) - Docker: Move credentials to environment variables - Update .env.example files with comprehensive documentation ## Test Organization - Move root-level test files to tests/ directory: - test_chat_room.py → tests/test_chat_room.py - test_websocket.py → tests/test_websocket.py - test_realtime_implementation.py → tests/test_realtime_implementation.py - Fix path references in test_realtime_implementation.py Breaking Changes: - CORS now requires explicit origins (no more wildcard) - All database tables renamed with 'tr_' prefix - SQLite no longer supported 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
# Change: Unified Environment Configuration Management
|
||||
|
||||
## Why
|
||||
|
||||
目前專案中存在多處硬編碼的設定值(端口、URL、超時時間、檔案大小限制等),分散在後端 Python 程式碼、前端 TypeScript 程式碼、Docker 配置檔案及開發腳本中。這造成:
|
||||
|
||||
1. **部署困難**:每次部署到不同環境需要修改多個檔案
|
||||
2. **安全風險**:CORS 使用萬用字元 `["*"]`、MinIO 使用預設密碼
|
||||
3. **維護成本**:設定值分散在 20+ 個檔案中,難以追蹤和更新
|
||||
4. **環境一致性問題**:開發、測試、生產環境難以保持設定同步
|
||||
|
||||
## What Changes
|
||||
|
||||
### Backend Configuration (Python)
|
||||
- 將所有硬編碼的設定值移至 `app/core/config.py` 的 Settings 類別
|
||||
- 擴展 `.env` 文件以包含所有可配置項目
|
||||
- 新增以下環境變數:
|
||||
- `HOST`, `PORT`, `DEBUG` - 伺服器設定
|
||||
- `CORS_ORIGINS` - CORS 來源白名單(**BREAKING**: 移除萬用字元)
|
||||
- `SYSTEM_ADMIN_EMAIL` - 系統管理員信箱
|
||||
- `AD_API_TIMEOUT_SECONDS` - AD API 超時設定
|
||||
- `MESSAGE_EDIT_TIME_LIMIT_MINUTES` - 訊息編輯時間限制
|
||||
- `TYPING_TIMEOUT_SECONDS` - 打字指示器超時
|
||||
- `IMAGE_MAX_SIZE_MB`, `DOCUMENT_MAX_SIZE_MB`, `LOG_MAX_SIZE_MB` - 檔案大小限制
|
||||
- `LOG_LEVEL` - 日誌等級
|
||||
|
||||
### Frontend Configuration (TypeScript/Vite)
|
||||
- 使用 Vite 環境變數機制 (`import.meta.env`)
|
||||
- 新增以下環境變數:
|
||||
- `VITE_API_TIMEOUT_MS` - API 請求超時
|
||||
- `VITE_MESSAGES_REFETCH_INTERVAL_MS` - 訊息重新取得間隔
|
||||
- `VITE_MAX_RECONNECT_DELAY_MS` - WebSocket 重連延遲
|
||||
- `VITE_REPORTS_STALE_TIME_MS` - 報告快取過期時間
|
||||
- `VITE_PORT` - 開發伺服器端口
|
||||
- `VITE_BACKEND_URL` - 後端 API URL
|
||||
|
||||
### Docker Configuration
|
||||
- 將 `docker-compose.minio.yml` 中的硬編碼認證資訊改為環境變數
|
||||
- 新增 `.env.docker` 範例檔案
|
||||
|
||||
### Documentation
|
||||
- 更新 `.env.example` 包含所有環境變數及說明
|
||||
- 更新 `frontend/.env.example` 包含所有前端環境變數
|
||||
|
||||
## Impact
|
||||
|
||||
- **Affected specs**: 新增 `env-config` spec
|
||||
- **Affected code**:
|
||||
- `app/core/config.py` - 擴展 Settings 類別
|
||||
- `app/main.py` - CORS 設定改為從環境變數讀取
|
||||
- `app/modules/realtime/router.py` - SYSTEM_ADMIN_EMAIL
|
||||
- `app/modules/auth/services/ad_client.py` - AD API 超時
|
||||
- `app/modules/realtime/services/message_service.py` - 訊息編輯限制
|
||||
- `app/modules/realtime/websocket_manager.py` - 打字超時
|
||||
- `app/modules/file_storage/validators.py` - 檔案大小限制
|
||||
- `frontend/vite.config.ts` - 端口和後端 URL
|
||||
- `frontend/src/services/api.ts` - API 超時
|
||||
- `frontend/src/hooks/*.ts` - 各種超時和間隔設定
|
||||
- `docker-compose.minio.yml` - MinIO 認證
|
||||
- `.env.example`, `frontend/.env.example` - 文件更新
|
||||
- **Breaking changes**:
|
||||
- CORS 設定從 `["*"]` 改為必須明確指定來源
|
||||
- 新的必要環境變數可能導致現有部署需要更新 `.env` 檔案
|
||||
@@ -0,0 +1,158 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Centralized Backend Configuration
|
||||
系統 SHALL 透過 `app/core/config.py` 中的 Settings 類別集中管理所有後端配置,並從環境變數讀取設定值。
|
||||
|
||||
**必要環境變數:**
|
||||
| 變數名稱 | 類型 | 預設值 | 說明 |
|
||||
|---------|------|--------|------|
|
||||
| `DATABASE_URL` | str | (必填) | 資料庫連線字串 |
|
||||
| `FERNET_KEY` | str | (必填) | 加密金鑰 |
|
||||
| `AD_API_URL` | str | (必填) | AD 認證 API URL |
|
||||
| `HOST` | str | `0.0.0.0` | 伺服器綁定位址 |
|
||||
| `PORT` | int | `8000` | 伺服器端口 |
|
||||
| `DEBUG` | bool | `False` | 除錯模式 |
|
||||
| `LOG_LEVEL` | str | `INFO` | 日誌等級 (DEBUG/INFO/WARNING/ERROR) |
|
||||
| `CORS_ORIGINS` | str | (必填) | 允許的 CORS 來源,逗號分隔 |
|
||||
| `SYSTEM_ADMIN_EMAIL` | str | (必填) | 系統管理員信箱 |
|
||||
| `AD_API_TIMEOUT_SECONDS` | int | `10` | AD API 請求超時秒數 |
|
||||
| `SESSION_INACTIVITY_DAYS` | int | `3` | 會話閒置過期天數 |
|
||||
| `TOKEN_REFRESH_THRESHOLD_MINUTES` | int | `5` | Token 更新閾值分鐘數 |
|
||||
| `MAX_REFRESH_ATTEMPTS` | int | `3` | 最大 Token 更新嘗試次數 |
|
||||
| `MESSAGE_EDIT_TIME_LIMIT_MINUTES` | int | `15` | 訊息編輯時間限制分鐘數 |
|
||||
| `TYPING_TIMEOUT_SECONDS` | int | `3` | 打字指示器超時秒數 |
|
||||
|
||||
#### Scenario: 必要環境變數缺失時啟動失敗
|
||||
- **WHEN** 啟動應用程式時缺少必要環境變數(如 `DATABASE_URL`)
|
||||
- **THEN** 應用程式 SHALL 顯示明確錯誤訊息並拒絕啟動
|
||||
|
||||
#### Scenario: 使用預設值啟動
|
||||
- **WHEN** 提供所有必要環境變數但未設定選填變數
|
||||
- **THEN** 系統 SHALL 使用預設值正常啟動
|
||||
|
||||
---
|
||||
|
||||
### Requirement: File Storage Configuration
|
||||
系統 SHALL 支援透過環境變數配置檔案儲存相關設定。
|
||||
|
||||
**環境變數:**
|
||||
| 變數名稱 | 類型 | 預設值 | 說明 |
|
||||
|---------|------|--------|------|
|
||||
| `MINIO_ENDPOINT` | str | `localhost:9000` | MinIO 伺服器位址 |
|
||||
| `MINIO_ACCESS_KEY` | str | `minioadmin` | MinIO 存取金鑰 |
|
||||
| `MINIO_SECRET_KEY` | str | `minioadmin` | MinIO 密鑰 |
|
||||
| `MINIO_BUCKET` | str | `task-reporter-files` | 預設儲存桶名稱 |
|
||||
| `MINIO_SECURE` | bool | `False` | 是否使用 HTTPS |
|
||||
| `IMAGE_MAX_SIZE_MB` | int | `10` | 圖片最大上傳大小 (MB) |
|
||||
| `DOCUMENT_MAX_SIZE_MB` | int | `20` | 文件最大上傳大小 (MB) |
|
||||
| `LOG_MAX_SIZE_MB` | int | `5` | 日誌檔最大上傳大小 (MB) |
|
||||
|
||||
#### Scenario: 自訂檔案大小限制
|
||||
- **WHEN** 設定 `IMAGE_MAX_SIZE_MB=20`
|
||||
- **THEN** 系統 SHALL 接受最大 20MB 的圖片上傳
|
||||
|
||||
#### Scenario: MinIO 連線配置
|
||||
- **WHEN** 設定自訂 MinIO 端點和認證資訊
|
||||
- **THEN** 系統 SHALL 使用該配置連線 MinIO 服務
|
||||
|
||||
---
|
||||
|
||||
### Requirement: AI Service Configuration
|
||||
系統 SHALL 支援透過環境變數配置 AI 報告生成服務。
|
||||
|
||||
**環境變數:**
|
||||
| 變數名稱 | 類型 | 預設值 | 說明 |
|
||||
|---------|------|--------|------|
|
||||
| `DIFY_BASE_URL` | str | `https://dify.theaken.com/v1` | DIFY API 基礎 URL |
|
||||
| `DIFY_API_KEY` | str | `""` | DIFY API 金鑰 |
|
||||
| `DIFY_TIMEOUT_SECONDS` | int | `120` | DIFY API 請求超時秒數 |
|
||||
| `REPORT_MAX_MESSAGES` | int | `200` | 報告包含的最大訊息數 |
|
||||
| `REPORT_STORAGE_PATH` | str | `reports` | 報告儲存路徑 |
|
||||
|
||||
#### Scenario: DIFY API 配置
|
||||
- **WHEN** 設定有效的 `DIFY_API_KEY`
|
||||
- **THEN** 系統 SHALL 能夠呼叫 DIFY API 生成報告
|
||||
|
||||
#### Scenario: DIFY API 金鑰缺失
|
||||
- **WHEN** 未設定 `DIFY_API_KEY` 或設為空字串
|
||||
- **THEN** 報告生成功能 SHALL 返回適當錯誤訊息
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Frontend Environment Configuration
|
||||
前端應用程式 SHALL 透過 Vite 環境變數機制配置運行時設定。
|
||||
|
||||
**環境變數:**
|
||||
| 變數名稱 | 類型 | 預設值 | 說明 |
|
||||
|---------|------|--------|------|
|
||||
| `VITE_API_BASE_URL` | str | `""` | API 基礎 URL(空字串表示相對路徑) |
|
||||
| `VITE_PORT` | int | `3000` | 開發伺服器端口 |
|
||||
| `VITE_BACKEND_URL` | str | `http://localhost:8000` | 後端 API URL(開發代理用) |
|
||||
| `VITE_API_TIMEOUT_MS` | int | `30000` | API 請求超時毫秒數 |
|
||||
| `VITE_MESSAGES_REFETCH_INTERVAL_MS` | int | `30000` | 訊息重新取得間隔毫秒數 |
|
||||
| `VITE_MAX_RECONNECT_DELAY_MS` | int | `30000` | WebSocket 最大重連延遲毫秒數 |
|
||||
| `VITE_REPORTS_STALE_TIME_MS` | int | `30000` | 報告快取過期時間毫秒數 |
|
||||
|
||||
#### Scenario: 開發環境配置
|
||||
- **WHEN** 在開發環境執行 `npm run dev`
|
||||
- **THEN** 前端 SHALL 使用 `VITE_BACKEND_URL` 設定代理轉發 API 請求
|
||||
|
||||
#### Scenario: 生產環境配置
|
||||
- **WHEN** 建置生產版本並設定 `VITE_API_BASE_URL`
|
||||
- **THEN** 前端 SHALL 使用該 URL 作為 API 請求基礎路徑
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Docker Environment Configuration
|
||||
Docker 部署 SHALL 支援透過環境變數文件配置所有服務。
|
||||
|
||||
**Docker Compose 支援的環境變數:**
|
||||
| 變數名稱 | 類型 | 說明 |
|
||||
|---------|------|------|
|
||||
| `MINIO_ROOT_USER` | str | MinIO 管理員帳號 |
|
||||
| `MINIO_ROOT_PASSWORD` | str | MinIO 管理員密碼 |
|
||||
| `MINIO_API_PORT` | int | MinIO S3 API 端口 (預設 9000) |
|
||||
| `MINIO_CONSOLE_PORT` | int | MinIO Console 端口 (預設 9001) |
|
||||
|
||||
#### Scenario: Docker 環境變數載入
|
||||
- **WHEN** 執行 `docker-compose --env-file .env.docker up`
|
||||
- **THEN** Docker 服務 SHALL 使用環境變數文件中的配置
|
||||
|
||||
#### Scenario: 安全認證配置
|
||||
- **WHEN** 設定非預設的 MinIO 認證資訊
|
||||
- **THEN** MinIO 服務 SHALL 使用自訂認證
|
||||
|
||||
---
|
||||
|
||||
### Requirement: CORS Security Configuration
|
||||
系統 SHALL 要求明確配置 CORS 允許來源,禁止使用萬用字元。
|
||||
|
||||
#### Scenario: CORS 來源配置
|
||||
- **WHEN** 設定 `CORS_ORIGINS=http://localhost:3000,https://example.com`
|
||||
- **THEN** 系統 SHALL 只接受來自這些來源的跨域請求
|
||||
|
||||
#### Scenario: CORS 未配置
|
||||
- **WHEN** 未設定 `CORS_ORIGINS` 環境變數
|
||||
- **THEN** 系統 SHALL 拒絕啟動並顯示錯誤訊息
|
||||
|
||||
#### Scenario: 開發環境 CORS
|
||||
- **WHEN** `DEBUG=True` 且 `CORS_ORIGINS` 包含 `http://localhost:3000`
|
||||
- **THEN** 開發環境前端 SHALL 能夠正常存取 API
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Environment Example Files
|
||||
專案 SHALL 提供完整的環境變數範例檔案,包含所有可配置項目及說明。
|
||||
|
||||
**必要範例檔案:**
|
||||
- `.env.example` - 後端環境變數範例
|
||||
- `frontend/.env.example` - 前端環境變數範例
|
||||
- `.env.docker.example` - Docker 部署環境變數範例
|
||||
|
||||
#### Scenario: 新開發者設定環境
|
||||
- **WHEN** 新開發者複製 `.env.example` 到 `.env`
|
||||
- **THEN** 只需填入必要的 API 金鑰即可啟動開發環境
|
||||
|
||||
#### Scenario: 生產部署設定
|
||||
- **WHEN** 運維人員參考 `.env.example` 設定生產環境
|
||||
- **THEN** 所有環境變數 SHALL 有明確的說明和範例值
|
||||
@@ -0,0 +1,36 @@
|
||||
# Tasks: Unified Environment Configuration
|
||||
|
||||
## 1. Backend Configuration Enhancement
|
||||
|
||||
- [x] 1.1 擴展 `app/core/config.py` Settings 類別,新增所有環境變數
|
||||
- [x] 1.2 更新 `app/main.py` 使 CORS 來源從 `CORS_ORIGINS` 環境變數讀取
|
||||
- [x] 1.3 更新 `app/modules/realtime/router.py` 將硬編碼的 `SYSTEM_ADMIN_EMAIL` 改為環境變數
|
||||
- [x] 1.4 更新 `app/modules/auth/services/ad_client.py` 將 timeout 改為可配置
|
||||
- [x] 1.5 更新 `app/modules/realtime/services/message_service.py` 將訊息編輯時間限制改為可配置
|
||||
- [x] 1.6 更新 `app/modules/realtime/websocket_manager.py` 將打字超時改為可配置
|
||||
- [x] 1.7 更新 `app/modules/file_storage/validators.py` 將檔案大小限制改為可配置
|
||||
|
||||
## 2. Frontend Configuration Enhancement
|
||||
|
||||
- [x] 2.1 更新 `frontend/vite.config.ts` 使用環境變數設定端口和後端 URL
|
||||
- [x] 2.2 更新 `frontend/src/services/api.ts` 使用環境變數設定 API 超時
|
||||
- [x] 2.3 更新 `frontend/src/hooks/useMessages.ts` 使用環境變數設定重新取得間隔
|
||||
- [x] 2.4 更新 `frontend/src/hooks/useWebSocket.ts` 使用環境變數設定重連延遲
|
||||
- [x] 2.5 更新 `frontend/src/hooks/useReports.ts` 使用環境變數設定快取過期時間
|
||||
|
||||
## 3. Docker Configuration
|
||||
|
||||
- [x] 3.1 更新 `docker-compose.minio.yml` 使用環境變數取代硬編碼認證
|
||||
- [x] 3.2 創建 `.env.docker.example` 範例檔案
|
||||
|
||||
## 4. Documentation Updates
|
||||
|
||||
- [x] 4.1 更新根目錄 `.env.example` 包含所有後端環境變數及中英文說明
|
||||
- [x] 4.2 更新 `frontend/.env.example` 包含所有前端環境變數及說明
|
||||
- [x] 4.3 更新現有 `.env` 檔案包含所有新環境變數
|
||||
|
||||
## 5. Testing & Validation
|
||||
|
||||
- [x] 5.1 驗證所有環境變數有合理的預設值(開發環境可直接運行)
|
||||
- [x] 5.2 確保前端編譯成功
|
||||
- [x] 5.3 驗證後端配置正確載入
|
||||
@@ -0,0 +1,66 @@
|
||||
# Change: Migrate SQLite to MySQL with Table Prefix
|
||||
|
||||
## Why
|
||||
|
||||
目前專案使用 SQLite 作為開發資料庫,需要遷移到雲端 MySQL 資料庫以支援生產環境部署。由於 MySQL 資料庫 `db_A060` 會與其他專案共用,需要為所有資料表加上 `tr_` 前綴以避免命名衝突。
|
||||
|
||||
**遷移目標:**
|
||||
- 完全移除 SQLite 支援,統一使用 MySQL
|
||||
- 所有資料表加上 `tr_` 前綴(例如 `users` → `tr_users`)
|
||||
- 使用 Alembic 進行資料庫版本控制和遷移管理
|
||||
- 確保遷移腳本只影響 `tr_` 前綴的資料表
|
||||
|
||||
## What Changes
|
||||
|
||||
### 1. Database Configuration
|
||||
- 更新 `DATABASE_URL` 環境變數格式支援 MySQL
|
||||
- 移除 `app/core/database.py` 中的 SQLite 特殊處理
|
||||
- 新增 MySQL 驅動相依套件 (`pymysql` 或 `mysqlclient`)
|
||||
|
||||
### 2. Model Table Prefix (**BREAKING**)
|
||||
所有 10 個資料表將重新命名:
|
||||
|
||||
| 原名稱 | 新名稱 |
|
||||
|--------|--------|
|
||||
| `users` | `tr_users` |
|
||||
| `user_sessions` | `tr_user_sessions` |
|
||||
| `incident_rooms` | `tr_incident_rooms` |
|
||||
| `room_members` | `tr_room_members` |
|
||||
| `room_templates` | `tr_room_templates` |
|
||||
| `messages` | `tr_messages` |
|
||||
| `message_reactions` | `tr_message_reactions` |
|
||||
| `message_edit_history` | `tr_message_edit_history` |
|
||||
| `generated_reports` | `tr_generated_reports` |
|
||||
| `room_files` | `tr_room_files` |
|
||||
|
||||
### 3. Alembic Integration
|
||||
- 初始化 Alembic 遷移框架
|
||||
- 建立初始遷移腳本(建立所有 `tr_` 前綴資料表)
|
||||
- 移除 `app/main.py` 中的 `Base.metadata.create_all()` 自動建表
|
||||
|
||||
### 4. Index and Constraint Naming
|
||||
- 更新所有索引名稱加上 `tr_` 前綴以避免衝突
|
||||
- 更新唯一約束名稱
|
||||
|
||||
### 5. MySQL Compatibility
|
||||
- 確保 JSON 欄位在 MySQL 中正確運作
|
||||
- 確保 Enum 類型在 MySQL 中正確運作
|
||||
- 處理 MySQL 的字串長度限制(VARCHAR vs TEXT)
|
||||
|
||||
## Impact
|
||||
|
||||
- **Affected specs**: 新增 `database` spec
|
||||
- **Affected code**:
|
||||
- `app/core/database.py` - 移除 SQLite 支援
|
||||
- `app/core/config.py` - 可能新增資料表前綴設定
|
||||
- `app/modules/*/models.py` - 所有 5 個 models.py 檔案更新 `__tablename__`
|
||||
- `app/main.py` - 移除自動建表,改用 Alembic
|
||||
- `requirements.txt` - 新增 `alembic`, `pymysql`
|
||||
- `.env`, `.env.example` - 更新 DATABASE_URL 格式
|
||||
- **Breaking changes**:
|
||||
- 所有資料表重新命名(需要重新建立資料庫或執行遷移)
|
||||
- SQLite 不再支援
|
||||
- 現有 SQLite 資料不會自動遷移(需手動處理)
|
||||
- **New files**:
|
||||
- `alembic.ini` - Alembic 設定檔
|
||||
- `alembic/` - 遷移腳本目錄
|
||||
@@ -0,0 +1,97 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: MySQL Database Support
|
||||
系統 SHALL 使用 MySQL 作為唯一的資料庫後端,不再支援 SQLite。
|
||||
|
||||
**MySQL 連線配置:**
|
||||
| 環境變數 | 格式 | 說明 |
|
||||
|---------|------|------|
|
||||
| `DATABASE_URL` | `mysql+pymysql://user:pass@host:port/database` | MySQL 連線字串 |
|
||||
|
||||
#### Scenario: MySQL 連線成功
|
||||
- **WHEN** 提供有效的 MySQL 連線字串
|
||||
- **THEN** 系統 SHALL 成功連線到 MySQL 資料庫
|
||||
|
||||
#### Scenario: MySQL 連線失敗
|
||||
- **WHEN** MySQL 伺服器無法連線
|
||||
- **THEN** 系統 SHALL 顯示明確的連線錯誤訊息並拒絕啟動
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Table Prefix Convention
|
||||
所有資料表 SHALL 使用 `tr_` 前綴以避免與同資料庫中的其他專案發生命名衝突。
|
||||
|
||||
**資料表命名規則:**
|
||||
- 所有資料表名稱以 `tr_` 開頭
|
||||
- 所有索引名稱以 `ix_tr_` 開頭
|
||||
- 所有唯一約束名稱以 `uq_tr_` 開頭
|
||||
|
||||
**完整資料表清單:**
|
||||
| 模組 | 資料表名稱 |
|
||||
|------|-----------|
|
||||
| Auth | `tr_users`, `tr_user_sessions` |
|
||||
| Chat Room | `tr_incident_rooms`, `tr_room_members`, `tr_room_templates` |
|
||||
| Realtime | `tr_messages`, `tr_message_reactions`, `tr_message_edit_history` |
|
||||
| Report | `tr_generated_reports` |
|
||||
| File Storage | `tr_room_files` |
|
||||
|
||||
#### Scenario: 資料表前綴驗證
|
||||
- **WHEN** 查詢資料庫中由本系統建立的資料表
|
||||
- **THEN** 所有資料表名稱 SHALL 以 `tr_` 開頭
|
||||
|
||||
#### Scenario: 索引前綴驗證
|
||||
- **WHEN** 查詢資料庫中由本系統建立的索引
|
||||
- **THEN** 所有索引名稱 SHALL 以 `ix_tr_` 開頭
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Alembic Database Migration
|
||||
系統 SHALL 使用 Alembic 進行資料庫結構版本控制和遷移管理。
|
||||
|
||||
**Alembic 配置要求:**
|
||||
- 從環境變數 `DATABASE_URL` 讀取資料庫連線
|
||||
- 遷移腳本存放於 `alembic/versions/` 目錄
|
||||
- 支援 `alembic upgrade head` 和 `alembic downgrade` 指令
|
||||
|
||||
#### Scenario: 執行資料庫遷移
|
||||
- **WHEN** 執行 `alembic upgrade head`
|
||||
- **THEN** 系統 SHALL 建立所有 `tr_` 前綴的資料表
|
||||
|
||||
#### Scenario: 自動產生遷移腳本
|
||||
- **WHEN** 執行 `alembic revision --autogenerate`
|
||||
- **THEN** Alembic SHALL 比對 models 與資料庫結構並產生遷移腳本
|
||||
|
||||
#### Scenario: 遷移腳本隔離
|
||||
- **WHEN** 執行任何 Alembic 遷移操作
|
||||
- **THEN** 只有 `tr_` 前綴的資料表會受到影響,其他專案的資料表不受影響
|
||||
|
||||
---
|
||||
|
||||
### Requirement: MySQL Connection Pooling
|
||||
系統 SHALL 使用連線池管理 MySQL 連線以提升效能和穩定性。
|
||||
|
||||
**連線池配置:**
|
||||
| 參數 | 預設值 | 說明 |
|
||||
|------|--------|------|
|
||||
| `pool_size` | 5 | 連線池大小 |
|
||||
| `max_overflow` | 10 | 最大額外連線數 |
|
||||
| `pool_recycle` | 3600 | 連線回收時間(秒) |
|
||||
|
||||
#### Scenario: 連線池運作
|
||||
- **WHEN** 多個 API 請求同時存取資料庫
|
||||
- **THEN** 系統 SHALL 從連線池取得連線而非每次建立新連線
|
||||
|
||||
#### Scenario: 連線回收
|
||||
- **WHEN** 連線閒置超過 `pool_recycle` 時間
|
||||
- **THEN** 系統 SHALL 自動回收並建立新連線以避免 MySQL 的 wait_timeout 問題
|
||||
|
||||
---
|
||||
|
||||
## REMOVED Requirements
|
||||
|
||||
### Requirement: SQLite Support
|
||||
**Reason**: 專案已完全遷移至 MySQL,不再需要 SQLite 支援
|
||||
**Migration**:
|
||||
- 移除 `app/core/database.py` 中的 SQLite 特殊處理(`check_same_thread`)
|
||||
- 更新 `.env.example` 移除 SQLite 連線範例
|
||||
- 現有 SQLite 資料需手動遷移或重新建立
|
||||
@@ -0,0 +1,49 @@
|
||||
# Tasks: Migrate SQLite to MySQL
|
||||
|
||||
## 1. Dependencies Setup
|
||||
|
||||
- [x] 1.1 新增 `pymysql` 到 requirements.txt
|
||||
- [x] 1.2 新增 `alembic` 到 requirements.txt
|
||||
- [x] 1.3 安裝新相依套件
|
||||
|
||||
## 2. Model Updates (Add tr_ Prefix)
|
||||
|
||||
- [x] 2.1 更新 `app/modules/auth/models.py` - `tr_users`, `tr_user_sessions`
|
||||
- [x] 2.2 更新 `app/modules/chat_room/models.py` - `tr_incident_rooms`, `tr_room_members`, `tr_room_templates`
|
||||
- [x] 2.3 更新 `app/modules/realtime/models.py` - `tr_messages`, `tr_message_reactions`, `tr_message_edit_history`
|
||||
- [x] 2.4 更新 `app/modules/report_generation/models.py` - `tr_generated_reports`
|
||||
- [x] 2.5 更新 `app/modules/file_storage/models.py` - `tr_room_files`
|
||||
- [x] 2.6 更新所有索引和約束名稱加上 `tr_` 前綴
|
||||
|
||||
## 3. Database Core Updates
|
||||
|
||||
- [x] 3.1 更新 `app/core/database.py` 移除 SQLite 特殊處理,加入 MySQL 連線池設定
|
||||
- [x] 3.2 更新 `app/main.py` 移除 `Base.metadata.create_all()` 自動建表
|
||||
|
||||
## 4. Alembic Setup
|
||||
|
||||
- [x] 4.1 執行 `alembic init alembic` 初始化 Alembic
|
||||
- [x] 4.2 設定 `alembic/env.py` 使用環境變數讀取 DATABASE_URL
|
||||
- [x] 4.3 更新 `alembic/env.py` 設定 target_metadata 和 `tr_alembic_version` 版本表
|
||||
- [x] 4.4 建立初始遷移腳本 `alembic revision --autogenerate -m "Initial migration - create tr_ prefixed tables"`
|
||||
|
||||
## 5. Environment Configuration
|
||||
|
||||
- [x] 5.1 更新 `.env` 使用 MySQL 連線字串
|
||||
- [x] 5.2 更新 `.env.example` 提供 MySQL 連線範例
|
||||
- [x] 5.3 移除 SQLite 相關註解和範例
|
||||
|
||||
## 6. Database Migration
|
||||
|
||||
- [x] 6.1 執行 `alembic upgrade head` 建立資料表
|
||||
- [x] 6.2 驗證所有資料表正確建立於 MySQL (11 個 tr_ 前綴表格)
|
||||
|
||||
## 7. Cleanup
|
||||
|
||||
- [x] 7.1 刪除本地 SQLite 資料庫檔案 `task_reporter.db`
|
||||
- [x] 7.2 確認 `.gitignore` 包含 `*.db` 規則
|
||||
|
||||
## 8. Testing
|
||||
|
||||
- [x] 8.1 驗證後端應用程式可正常啟動並連接 MySQL
|
||||
- [x] 8.2 驗證資料庫 CRUD 操作正常 (tr_room_templates 查詢成功)
|
||||
162
openspec/specs/env-config/spec.md
Normal file
162
openspec/specs/env-config/spec.md
Normal file
@@ -0,0 +1,162 @@
|
||||
# env-config Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change add-unified-env-config. Update Purpose after archive.
|
||||
## Requirements
|
||||
### Requirement: Centralized Backend Configuration
|
||||
系統 SHALL 透過 `app/core/config.py` 中的 Settings 類別集中管理所有後端配置,並從環境變數讀取設定值。
|
||||
|
||||
**必要環境變數:**
|
||||
| 變數名稱 | 類型 | 預設值 | 說明 |
|
||||
|---------|------|--------|------|
|
||||
| `DATABASE_URL` | str | (必填) | 資料庫連線字串 |
|
||||
| `FERNET_KEY` | str | (必填) | 加密金鑰 |
|
||||
| `AD_API_URL` | str | (必填) | AD 認證 API URL |
|
||||
| `HOST` | str | `0.0.0.0` | 伺服器綁定位址 |
|
||||
| `PORT` | int | `8000` | 伺服器端口 |
|
||||
| `DEBUG` | bool | `False` | 除錯模式 |
|
||||
| `LOG_LEVEL` | str | `INFO` | 日誌等級 (DEBUG/INFO/WARNING/ERROR) |
|
||||
| `CORS_ORIGINS` | str | (必填) | 允許的 CORS 來源,逗號分隔 |
|
||||
| `SYSTEM_ADMIN_EMAIL` | str | (必填) | 系統管理員信箱 |
|
||||
| `AD_API_TIMEOUT_SECONDS` | int | `10` | AD API 請求超時秒數 |
|
||||
| `SESSION_INACTIVITY_DAYS` | int | `3` | 會話閒置過期天數 |
|
||||
| `TOKEN_REFRESH_THRESHOLD_MINUTES` | int | `5` | Token 更新閾值分鐘數 |
|
||||
| `MAX_REFRESH_ATTEMPTS` | int | `3` | 最大 Token 更新嘗試次數 |
|
||||
| `MESSAGE_EDIT_TIME_LIMIT_MINUTES` | int | `15` | 訊息編輯時間限制分鐘數 |
|
||||
| `TYPING_TIMEOUT_SECONDS` | int | `3` | 打字指示器超時秒數 |
|
||||
|
||||
#### Scenario: 必要環境變數缺失時啟動失敗
|
||||
- **WHEN** 啟動應用程式時缺少必要環境變數(如 `DATABASE_URL`)
|
||||
- **THEN** 應用程式 SHALL 顯示明確錯誤訊息並拒絕啟動
|
||||
|
||||
#### Scenario: 使用預設值啟動
|
||||
- **WHEN** 提供所有必要環境變數但未設定選填變數
|
||||
- **THEN** 系統 SHALL 使用預設值正常啟動
|
||||
|
||||
---
|
||||
|
||||
### Requirement: File Storage Configuration
|
||||
系統 SHALL 支援透過環境變數配置檔案儲存相關設定。
|
||||
|
||||
**環境變數:**
|
||||
| 變數名稱 | 類型 | 預設值 | 說明 |
|
||||
|---------|------|--------|------|
|
||||
| `MINIO_ENDPOINT` | str | `localhost:9000` | MinIO 伺服器位址 |
|
||||
| `MINIO_ACCESS_KEY` | str | `minioadmin` | MinIO 存取金鑰 |
|
||||
| `MINIO_SECRET_KEY` | str | `minioadmin` | MinIO 密鑰 |
|
||||
| `MINIO_BUCKET` | str | `task-reporter-files` | 預設儲存桶名稱 |
|
||||
| `MINIO_SECURE` | bool | `False` | 是否使用 HTTPS |
|
||||
| `IMAGE_MAX_SIZE_MB` | int | `10` | 圖片最大上傳大小 (MB) |
|
||||
| `DOCUMENT_MAX_SIZE_MB` | int | `20` | 文件最大上傳大小 (MB) |
|
||||
| `LOG_MAX_SIZE_MB` | int | `5` | 日誌檔最大上傳大小 (MB) |
|
||||
|
||||
#### Scenario: 自訂檔案大小限制
|
||||
- **WHEN** 設定 `IMAGE_MAX_SIZE_MB=20`
|
||||
- **THEN** 系統 SHALL 接受最大 20MB 的圖片上傳
|
||||
|
||||
#### Scenario: MinIO 連線配置
|
||||
- **WHEN** 設定自訂 MinIO 端點和認證資訊
|
||||
- **THEN** 系統 SHALL 使用該配置連線 MinIO 服務
|
||||
|
||||
---
|
||||
|
||||
### Requirement: AI Service Configuration
|
||||
系統 SHALL 支援透過環境變數配置 AI 報告生成服務。
|
||||
|
||||
**環境變數:**
|
||||
| 變數名稱 | 類型 | 預設值 | 說明 |
|
||||
|---------|------|--------|------|
|
||||
| `DIFY_BASE_URL` | str | `https://dify.theaken.com/v1` | DIFY API 基礎 URL |
|
||||
| `DIFY_API_KEY` | str | `""` | DIFY API 金鑰 |
|
||||
| `DIFY_TIMEOUT_SECONDS` | int | `120` | DIFY API 請求超時秒數 |
|
||||
| `REPORT_MAX_MESSAGES` | int | `200` | 報告包含的最大訊息數 |
|
||||
| `REPORT_STORAGE_PATH` | str | `reports` | 報告儲存路徑 |
|
||||
|
||||
#### Scenario: DIFY API 配置
|
||||
- **WHEN** 設定有效的 `DIFY_API_KEY`
|
||||
- **THEN** 系統 SHALL 能夠呼叫 DIFY API 生成報告
|
||||
|
||||
#### Scenario: DIFY API 金鑰缺失
|
||||
- **WHEN** 未設定 `DIFY_API_KEY` 或設為空字串
|
||||
- **THEN** 報告生成功能 SHALL 返回適當錯誤訊息
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Frontend Environment Configuration
|
||||
前端應用程式 SHALL 透過 Vite 環境變數機制配置運行時設定。
|
||||
|
||||
**環境變數:**
|
||||
| 變數名稱 | 類型 | 預設值 | 說明 |
|
||||
|---------|------|--------|------|
|
||||
| `VITE_API_BASE_URL` | str | `""` | API 基礎 URL(空字串表示相對路徑) |
|
||||
| `VITE_PORT` | int | `3000` | 開發伺服器端口 |
|
||||
| `VITE_BACKEND_URL` | str | `http://localhost:8000` | 後端 API URL(開發代理用) |
|
||||
| `VITE_API_TIMEOUT_MS` | int | `30000` | API 請求超時毫秒數 |
|
||||
| `VITE_MESSAGES_REFETCH_INTERVAL_MS` | int | `30000` | 訊息重新取得間隔毫秒數 |
|
||||
| `VITE_MAX_RECONNECT_DELAY_MS` | int | `30000` | WebSocket 最大重連延遲毫秒數 |
|
||||
| `VITE_REPORTS_STALE_TIME_MS` | int | `30000` | 報告快取過期時間毫秒數 |
|
||||
|
||||
#### Scenario: 開發環境配置
|
||||
- **WHEN** 在開發環境執行 `npm run dev`
|
||||
- **THEN** 前端 SHALL 使用 `VITE_BACKEND_URL` 設定代理轉發 API 請求
|
||||
|
||||
#### Scenario: 生產環境配置
|
||||
- **WHEN** 建置生產版本並設定 `VITE_API_BASE_URL`
|
||||
- **THEN** 前端 SHALL 使用該 URL 作為 API 請求基礎路徑
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Docker Environment Configuration
|
||||
Docker 部署 SHALL 支援透過環境變數文件配置所有服務。
|
||||
|
||||
**Docker Compose 支援的環境變數:**
|
||||
| 變數名稱 | 類型 | 說明 |
|
||||
|---------|------|------|
|
||||
| `MINIO_ROOT_USER` | str | MinIO 管理員帳號 |
|
||||
| `MINIO_ROOT_PASSWORD` | str | MinIO 管理員密碼 |
|
||||
| `MINIO_API_PORT` | int | MinIO S3 API 端口 (預設 9000) |
|
||||
| `MINIO_CONSOLE_PORT` | int | MinIO Console 端口 (預設 9001) |
|
||||
|
||||
#### Scenario: Docker 環境變數載入
|
||||
- **WHEN** 執行 `docker-compose --env-file .env.docker up`
|
||||
- **THEN** Docker 服務 SHALL 使用環境變數文件中的配置
|
||||
|
||||
#### Scenario: 安全認證配置
|
||||
- **WHEN** 設定非預設的 MinIO 認證資訊
|
||||
- **THEN** MinIO 服務 SHALL 使用自訂認證
|
||||
|
||||
---
|
||||
|
||||
### Requirement: CORS Security Configuration
|
||||
系統 SHALL 要求明確配置 CORS 允許來源,禁止使用萬用字元。
|
||||
|
||||
#### Scenario: CORS 來源配置
|
||||
- **WHEN** 設定 `CORS_ORIGINS=http://localhost:3000,https://example.com`
|
||||
- **THEN** 系統 SHALL 只接受來自這些來源的跨域請求
|
||||
|
||||
#### Scenario: CORS 未配置
|
||||
- **WHEN** 未設定 `CORS_ORIGINS` 環境變數
|
||||
- **THEN** 系統 SHALL 拒絕啟動並顯示錯誤訊息
|
||||
|
||||
#### Scenario: 開發環境 CORS
|
||||
- **WHEN** `DEBUG=True` 且 `CORS_ORIGINS` 包含 `http://localhost:3000`
|
||||
- **THEN** 開發環境前端 SHALL 能夠正常存取 API
|
||||
|
||||
---
|
||||
|
||||
### Requirement: Environment Example Files
|
||||
專案 SHALL 提供完整的環境變數範例檔案,包含所有可配置項目及說明。
|
||||
|
||||
**必要範例檔案:**
|
||||
- `.env.example` - 後端環境變數範例
|
||||
- `frontend/.env.example` - 前端環境變數範例
|
||||
- `.env.docker.example` - Docker 部署環境變數範例
|
||||
|
||||
#### Scenario: 新開發者設定環境
|
||||
- **WHEN** 新開發者複製 `.env.example` 到 `.env`
|
||||
- **THEN** 只需填入必要的 API 金鑰即可啟動開發環境
|
||||
|
||||
#### Scenario: 生產部署設定
|
||||
- **WHEN** 運維人員參考 `.env.example` 設定生產環境
|
||||
- **THEN** 所有環境變數 SHALL 有明確的說明和範例值
|
||||
|
||||
Reference in New Issue
Block a user