chore: Archive all pending OpenSpec proposals
Force archive the following proposals: - add-audio-device-selector (complete) - add-embedded-backend-packaging (19/26 tasks) - add-flexible-deployment-options (20/21 tasks) New specs created: - audio-device-management (7 requirements) - embedded-backend (8 requirements) Updated specs: - transcription (+2 requirements for model download progress) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
# Design: Extract Environment Variables
|
||||
|
||||
## Context
|
||||
|
||||
專案需要支援以下部署場景:
|
||||
1. 開發環境:前後端在本地同時運行
|
||||
2. 生產環境:後端部署於 1Panel 伺服器,前端(Electron 應用)獨立打包部署
|
||||
|
||||
**架構說明**:
|
||||
- **後端**:FastAPI 服務,使用兩個 Dify 服務(LLM 摘要 + STT 轉錄)
|
||||
- **前端**:Electron 應用,包含 Sidecar(本地 Whisper 即時轉錄服務)
|
||||
|
||||
目前的硬編碼配置使得部署困難,且敏感資訊(如 API 密鑰、資料庫密碼)散落在代碼中。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
### Goals
|
||||
- 將所有硬編碼配置提取到環境變數
|
||||
- 提供完整的 `.env.example` 範例檔案
|
||||
- 支援前端獨立打包時指定後端 API URL
|
||||
- 提供 1Panel 部署完整指南和腳本
|
||||
- 確保向後相容(預設值與現有行為一致)
|
||||
|
||||
### Non-Goals
|
||||
- 不實現配置熱重載
|
||||
- 不實現密鑰輪換機制
|
||||
- 不實現多環境配置管理(如 .env.production, .env.staging)
|
||||
|
||||
## Decisions
|
||||
|
||||
### 1. 環境變數命名規範
|
||||
|
||||
**決定**:使用大寫蛇形命名法,前端變數加 `VITE_` 前綴
|
||||
|
||||
**原因**:
|
||||
- Vite 要求客戶端環境變數必須以 `VITE_` 開頭
|
||||
- 大寫蛇形是環境變數的標準慣例
|
||||
|
||||
### 2. 前端 API URL 配置
|
||||
|
||||
**決定**:使用 `VITE_API_BASE_URL` 環境變數,在 `api.js` 中讀取
|
||||
|
||||
```javascript
|
||||
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || "http://localhost:8000/api";
|
||||
```
|
||||
|
||||
**替代方案**:
|
||||
- 使用 runtime 配置檔案(如 `/config.js`)- 更靈活但增加部署複雜度
|
||||
- 使用相對路徑 `/api` - 需要 nginx 反向代理,不適合獨立部署
|
||||
|
||||
### 3. 超時配置單位
|
||||
|
||||
**決定**:統一使用毫秒(ms),與 JavaScript 一致
|
||||
|
||||
**後端配置項**:
|
||||
| 變數名 | 預設值 | 用途 |
|
||||
|--------|--------|------|
|
||||
| UPLOAD_TIMEOUT | 600000 | 大檔案上傳(10分鐘) |
|
||||
| DIFY_STT_TIMEOUT | 300000 | Dify STT 轉錄每個分塊(5分鐘) |
|
||||
| LLM_TIMEOUT | 120000 | Dify LLM 摘要處理(2分鐘) |
|
||||
| AUTH_TIMEOUT | 30000 | 認證 API 調用(30秒) |
|
||||
|
||||
**前端/Sidecar 配置項**:
|
||||
| 變數名 | 預設值 | 用途 |
|
||||
|--------|--------|------|
|
||||
| WHISPER_MODEL | medium | 本地 Whisper 模型大小 |
|
||||
| WHISPER_DEVICE | cpu | 執行裝置(cpu/cuda) |
|
||||
| WHISPER_COMPUTE | int8 | 運算精度 |
|
||||
|
||||
### 4. 1Panel 部署架構
|
||||
|
||||
**決定**:使用 systemd 管理後端服務,nginx 反向代理
|
||||
|
||||
```
|
||||
[Client] → [Nginx:443] → [Uvicorn:8000]
|
||||
↓
|
||||
[Static Files]
|
||||
```
|
||||
|
||||
**原因**:
|
||||
- systemd 提供進程管理、日誌、自動重啟
|
||||
- nginx 處理 HTTPS、靜態檔案、反向代理
|
||||
- 這是 1Panel 的標準部署模式
|
||||
|
||||
### 5. CORS 配置
|
||||
|
||||
**決定**:保持 `allow_origins=["*"]`,不額外配置
|
||||
|
||||
**原因**:
|
||||
- 前端是 Electron 桌面應用,分發到多台電腦
|
||||
- Electron 主進程的 HTTP 請求不受 CORS 限制
|
||||
- 簡化部署配置,IT 只需關心 HOST 和 PORT
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
### 風險 1:環境變數遺漏
|
||||
- **風險**:部署時遺漏必要的環境變數導致服務異常
|
||||
- **緩解**:提供完整的 `.env.example`,啟動時檢查必要變數
|
||||
|
||||
### 風險 2:前端打包後無法修改 API URL
|
||||
- **風險**:Vite 環境變數在打包時固定
|
||||
- **緩解**:文件中說明需要為不同環境分別打包,或考慮未來實現 runtime 配置
|
||||
|
||||
### 風險 3:敏感資訊外洩
|
||||
- **風險**:`.env` 檔案被提交到版本控制
|
||||
- **緩解**:確保 `.gitignore` 包含 `.env`,只提交 `.env.example`
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. **Phase 1 - 後端配置**
|
||||
- 更新 `config.py` 添加新配置項
|
||||
- 更新各 router 使用配置
|
||||
- 更新 `.env` 和 `.env.example`
|
||||
|
||||
2. **Phase 2 - 前端配置**
|
||||
- 創建 `.env` 和 `.env.example`
|
||||
- 更新 `api.js` 使用環境變數
|
||||
|
||||
3. **Phase 3 - 部署文件**
|
||||
- 創建 1Panel 部署指南
|
||||
- 創建部署腳本
|
||||
|
||||
4. **Rollback**
|
||||
- 所有配置都有預設值,回滾只需刪除環境變數
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Q: 是否需要支援 Docker 部署?
|
||||
- A: 暫不包含,但環境變數配置天然支援 Docker
|
||||
@@ -0,0 +1,85 @@
|
||||
# Change: Extract Hardcoded Configurations to Environment Variables
|
||||
|
||||
## Why
|
||||
|
||||
專案中存在大量硬編碼的路徑、URL、API 端點、埠號及敏感資訊,這些配置散落在前後端程式碼中。為了支援獨立部署(後端部署於 1Panel 伺服器,前端獨立打包),需要將這些配置統一提取到環境變數檔案中管理,提高部署彈性與安全性。
|
||||
|
||||
## What Changes
|
||||
|
||||
### 後端配置提取
|
||||
|
||||
後端使用兩個 Dify 服務:
|
||||
- **LLM 服務**(`DIFY_API_KEY`)- 產生會議結論及行動事項
|
||||
- **STT 服務**(`DIFY_STT_API_KEY`)- 上傳音訊檔案的語音轉文字
|
||||
|
||||
1. **新增環境變數**
|
||||
- `BACKEND_HOST` - 後端監聽地址(預設:0.0.0.0)
|
||||
- `BACKEND_PORT` - 後端監聽埠號(預設:8000)
|
||||
- `DB_POOL_SIZE` - 資料庫連線池大小(預設:5)
|
||||
- `JWT_EXPIRE_HOURS` - JWT Token 過期時間(預設:24)
|
||||
- `UPLOAD_TIMEOUT` - 檔案上傳超時時間(預設:600000ms)
|
||||
- `DIFY_STT_TIMEOUT` - Dify STT 轉錄超時時間(預設:300000ms)
|
||||
- `LLM_TIMEOUT` - Dify LLM 處理超時時間(預設:120000ms)
|
||||
- `AUTH_TIMEOUT` - 認證 API 超時時間(預設:30000ms)
|
||||
- `TEMPLATE_DIR` - Excel 範本目錄路徑
|
||||
- `RECORD_DIR` - 會議記錄匯出目錄路徑
|
||||
- `MAX_FILE_SIZE` - 最大上傳檔案大小(預設:500MB)
|
||||
- `SUPPORTED_AUDIO_FORMATS` - 支援的音訊格式
|
||||
|
||||
**註**:CORS 保持 `allow_origins=["*"]`,因為前端是 Electron 桌面應用,無需細粒度控制。
|
||||
|
||||
2. **已存在環境變數**(確認文件化)
|
||||
- `DB_HOST`, `DB_PORT`, `DB_USER`, `DB_PASS`, `DB_NAME` - 資料庫配置
|
||||
- `AUTH_API_URL` - 認證 API 端點
|
||||
- `DIFY_API_URL` - Dify API 基礎 URL
|
||||
- `DIFY_API_KEY` - Dify LLM 服務金鑰
|
||||
- `DIFY_STT_API_KEY` - Dify STT 服務金鑰
|
||||
- `ADMIN_EMAIL` - 管理員郵箱
|
||||
- `JWT_SECRET` - JWT 密鑰
|
||||
|
||||
### 前端/Electron 配置提取
|
||||
|
||||
前端包含 Sidecar(本地 Whisper 即時轉錄服務)。
|
||||
|
||||
1. **Vite 環境變數**(打包時使用)
|
||||
- `VITE_API_BASE_URL` - 後端 API 基礎 URL(預設:http://localhost:8000/api)
|
||||
- `VITE_UPLOAD_TIMEOUT` - 大檔案上傳超時時間(預設:600000ms)
|
||||
- `VITE_APP_TITLE` - 應用程式標題
|
||||
|
||||
2. **Sidecar/Whisper 環境變數**(執行時使用)
|
||||
- `WHISPER_MODEL` - 模型大小(預設:medium)
|
||||
- `WHISPER_DEVICE` - 執行裝置(預設:cpu)
|
||||
- `WHISPER_COMPUTE` - 運算精度(預設:int8)
|
||||
- `SIDECAR_DIR` - Sidecar 目錄路徑(Electron 打包時使用)
|
||||
|
||||
### 部署文件與腳本
|
||||
|
||||
1. **1Panel 部署指南** - `docs/1panel-deployment.md`
|
||||
2. **後端部署腳本** - `scripts/deploy-backend.sh`
|
||||
3. **環境變數範例檔案**
|
||||
- 更新 `backend/.env.example`
|
||||
- 新增 `client/.env.example`
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs: `middleware`
|
||||
- Affected code:
|
||||
- `backend/app/config.py` - 新增配置項
|
||||
- `backend/app/database.py` - 使用連線池配置
|
||||
- `backend/app/routers/ai.py` - 使用 Dify 超時配置
|
||||
- `backend/app/routers/auth.py` - 使用認證超時配置
|
||||
- `backend/app/routers/export.py` - 使用目錄路徑配置
|
||||
- `client/src/services/api.js` - 使用 Vite 環境變數
|
||||
- `client/src/main.js` - Sidecar 路徑配置
|
||||
- `start.sh` - 更新啟動腳本
|
||||
|
||||
## 部署流程簡化
|
||||
|
||||
**IT 只需提供:**
|
||||
1. 後端伺服器 IP/域名
|
||||
2. 後端使用的 PORT
|
||||
|
||||
**開發者打包前端時:**
|
||||
1. 設定 `VITE_API_BASE_URL=http://<伺服器>:<PORT>/api`
|
||||
2. 執行打包命令
|
||||
3. 分發 EXE 給使用者
|
||||
@@ -0,0 +1,122 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: FastAPI Server Configuration
|
||||
The middleware server SHALL be implemented using Python FastAPI framework with comprehensive environment-based configuration supporting standalone deployment.
|
||||
|
||||
#### Scenario: Server startup with valid configuration
|
||||
- **WHEN** the server starts with valid .env file containing all required variables (DB_HOST, DB_PORT, DB_USER, DB_PASS, DB_NAME, DIFY_API_URL, DIFY_API_KEY, AUTH_API_URL)
|
||||
- **THEN** the server SHALL start successfully and accept connections on the configured BACKEND_HOST and BACKEND_PORT
|
||||
|
||||
#### Scenario: Server startup with missing configuration
|
||||
- **WHEN** the server starts with missing required environment variables
|
||||
- **THEN** the server SHALL fail to start with descriptive error message
|
||||
|
||||
#### Scenario: Server startup with optional configuration
|
||||
- **WHEN** optional environment variables (BACKEND_PORT, DB_POOL_SIZE, etc.) are not set
|
||||
- **THEN** the server SHALL use sensible defaults and start normally
|
||||
|
||||
### Requirement: Database Connection Pool
|
||||
The middleware server SHALL maintain a configurable connection pool to the MySQL database using environment variables.
|
||||
|
||||
#### Scenario: Database connection success
|
||||
- **WHEN** the server connects to MySQL with valid credentials from environment
|
||||
- **THEN** a connection pool SHALL be established with DB_POOL_SIZE connections
|
||||
|
||||
#### Scenario: Database connection failure
|
||||
- **WHEN** the database is unreachable
|
||||
- **THEN** the server SHALL return HTTP 503 with error details for affected endpoints
|
||||
|
||||
### Requirement: CORS Configuration
|
||||
The middleware server SHALL allow cross-origin requests from all origins to support Electron desktop application clients.
|
||||
|
||||
#### Scenario: CORS preflight request
|
||||
- **WHEN** any client sends OPTIONS request
|
||||
- **THEN** the server SHALL respond with CORS headers allowing the request (allow_origins=["*"])
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Backend Server Configuration
|
||||
The middleware server SHALL support configurable host and port through environment variables for flexible deployment.
|
||||
|
||||
#### Scenario: Custom port binding
|
||||
- **WHEN** BACKEND_PORT environment variable is set to 9000
|
||||
- **THEN** the server SHALL listen on port 9000
|
||||
|
||||
#### Scenario: Production host binding
|
||||
- **WHEN** BACKEND_HOST is set to 0.0.0.0
|
||||
- **THEN** the server SHALL accept connections from any network interface
|
||||
|
||||
#### Scenario: Default configuration
|
||||
- **WHEN** BACKEND_HOST and BACKEND_PORT are not set
|
||||
- **THEN** the server SHALL default to 0.0.0.0:8000
|
||||
|
||||
### Requirement: Timeout Configuration
|
||||
The middleware server SHALL support configurable timeout values for different operations through environment variables.
|
||||
|
||||
#### Scenario: File upload timeout
|
||||
- **WHEN** UPLOAD_TIMEOUT is set to 900000 (15 minutes)
|
||||
- **THEN** file upload operations SHALL allow up to 15 minutes before timeout
|
||||
|
||||
#### Scenario: LLM processing timeout
|
||||
- **WHEN** LLM_TIMEOUT is set to 180000 (3 minutes)
|
||||
- **THEN** Dify LLM summarization operations SHALL allow up to 3 minutes before timeout
|
||||
|
||||
#### Scenario: Dify STT timeout
|
||||
- **WHEN** DIFY_STT_TIMEOUT is set to 600000 (10 minutes)
|
||||
- **THEN** Dify STT audio transcription per chunk SHALL allow up to 10 minutes before timeout
|
||||
|
||||
#### Scenario: Authentication timeout
|
||||
- **WHEN** AUTH_TIMEOUT is set to 60000 (1 minute)
|
||||
- **THEN** authentication API calls SHALL allow up to 1 minute before timeout
|
||||
|
||||
### Requirement: File Path Configuration
|
||||
The middleware server SHALL support configurable directory paths for templates and records.
|
||||
|
||||
#### Scenario: Custom template directory
|
||||
- **WHEN** TEMPLATE_DIR environment variable is set to /data/templates
|
||||
- **THEN** Excel templates SHALL be loaded from /data/templates
|
||||
|
||||
#### Scenario: Custom record directory
|
||||
- **WHEN** RECORD_DIR environment variable is set to /data/records
|
||||
- **THEN** exported meeting records SHALL be saved to /data/records
|
||||
|
||||
#### Scenario: Relative path resolution
|
||||
- **WHEN** directory paths are relative
|
||||
- **THEN** they SHALL be resolved relative to the backend application root
|
||||
|
||||
### Requirement: Frontend Environment Configuration
|
||||
The frontend Electron application SHALL support environment-based API URL configuration for connecting to deployed backend.
|
||||
|
||||
#### Scenario: Custom API URL in production build
|
||||
- **WHEN** VITE_API_BASE_URL is set to http://192.168.1.100:8000/api during build
|
||||
- **THEN** the built Electron app SHALL connect to http://192.168.1.100:8000/api
|
||||
|
||||
#### Scenario: Default API URL in development
|
||||
- **WHEN** VITE_API_BASE_URL is not set
|
||||
- **THEN** the frontend SHALL default to http://localhost:8000/api
|
||||
|
||||
### Requirement: Sidecar Whisper Configuration
|
||||
The Electron frontend's Sidecar (local Whisper transcription service) SHALL support environment-based model configuration.
|
||||
|
||||
#### Scenario: Custom Whisper model
|
||||
- **WHEN** WHISPER_MODEL environment variable is set to "large"
|
||||
- **THEN** the Sidecar SHALL load the large Whisper model for transcription
|
||||
|
||||
#### Scenario: GPU acceleration
|
||||
- **WHEN** WHISPER_DEVICE is set to "cuda" and WHISPER_COMPUTE is set to "float16"
|
||||
- **THEN** the Sidecar SHALL use GPU for faster transcription
|
||||
|
||||
#### Scenario: Default CPU mode
|
||||
- **WHEN** WHISPER_DEVICE is not set
|
||||
- **THEN** the Sidecar SHALL default to CPU with int8 compute type
|
||||
|
||||
### Requirement: Environment Example Files
|
||||
The project SHALL provide example environment files documenting all configuration options.
|
||||
|
||||
#### Scenario: Backend environment example
|
||||
- **WHEN** developer sets up backend
|
||||
- **THEN** backend/.env.example SHALL list all environment variables with descriptions and example values (without sensitive data)
|
||||
|
||||
#### Scenario: Frontend environment example
|
||||
- **WHEN** developer sets up frontend
|
||||
- **THEN** client/.env.example SHALL list all VITE_ prefixed and WHISPER_ prefixed environment variables with descriptions
|
||||
@@ -0,0 +1,45 @@
|
||||
# Tasks: Extract Environment Variables
|
||||
|
||||
## 1. Backend Configuration
|
||||
|
||||
- [x] 1.1 Update `backend/app/config.py` with new environment variables
|
||||
- Add: BACKEND_HOST, BACKEND_PORT
|
||||
- Add: DB_POOL_SIZE, JWT_EXPIRE_HOURS
|
||||
- Add: UPLOAD_TIMEOUT, DIFY_STT_TIMEOUT, LLM_TIMEOUT, AUTH_TIMEOUT
|
||||
- Add: TEMPLATE_DIR, RECORD_DIR, MAX_FILE_SIZE, SUPPORTED_AUDIO_FORMATS
|
||||
- [x] 1.2 Update `backend/app/database.py` to use DB_POOL_SIZE from config
|
||||
- [x] 1.3 Update `backend/app/routers/ai.py` to use Dify timeout configs (DIFY_STT_TIMEOUT, LLM_TIMEOUT)
|
||||
- [x] 1.4 Update `backend/app/routers/auth.py` to use AUTH_TIMEOUT and JWT_EXPIRE_HOURS from config
|
||||
- [x] 1.5 Update `backend/app/routers/export.py` to use TEMPLATE_DIR and RECORD_DIR from config
|
||||
- [x] 1.6 Update `backend/.env` with all new variables
|
||||
- [x] 1.7 Update `backend/.env.example` with all variables (without sensitive values)
|
||||
|
||||
## 2. Frontend/Electron Configuration
|
||||
|
||||
- [x] 2.1 Create `client/.env` with VITE_API_BASE_URL and Whisper settings
|
||||
- [x] 2.2 Create `client/.env.example` as template
|
||||
- [x] 2.3 Update `client/src/services/api.js` to use import.meta.env.VITE_API_BASE_URL
|
||||
- [x] 2.4 Update `client/src/main.js` to pass Whisper env vars to Sidecar process
|
||||
|
||||
## 3. Startup Scripts
|
||||
|
||||
- [x] 3.1 Update `start.sh` to load environment variables properly
|
||||
- [x] 3.2 Create `scripts/deploy-backend.sh` for standalone backend deployment
|
||||
|
||||
## 4. Deployment Documentation
|
||||
|
||||
- [x] 4.1 Create `docs/1panel-deployment.md` with step-by-step guide
|
||||
- Include: Prerequisites and system requirements
|
||||
- Include: Python environment setup
|
||||
- Include: Environment variable configuration (IT only needs HOST + PORT)
|
||||
- Include: Nginx reverse proxy configuration example
|
||||
- Include: Systemd service file example
|
||||
- Include: SSL/HTTPS setup guide (optional)
|
||||
- Include: Troubleshooting common issues
|
||||
|
||||
## 5. Validation
|
||||
|
||||
- [ ] 5.1 Test backend starts with new config
|
||||
- [ ] 5.2 Test frontend builds with environment variables
|
||||
- [ ] 5.3 Test API connectivity between frontend and backend
|
||||
- [ ] 5.4 Verify all hardcoded values are externalized
|
||||
Reference in New Issue
Block a user