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:
egg
2025-12-07 14:15:11 +08:00
parent 1d5d4d447d
commit 92834dbe0e
39 changed files with 1558 additions and 136 deletions

View File

@@ -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/` - 遷移腳本目錄

View File

@@ -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 資料需手動遷移或重新建立

View File

@@ -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 查詢成功)