# CI 必需环境变量清单

> 本文档整理小虾 SaaS 项目中所有从环境变量读取的配置项，明确哪些是 CI 测试必须的、哪些是可选的。
> 最后更新：2026-07-09

## 目录

- [一、配置来源说明](#一配置来源说明)
- [二、CI 必需环境变量（P0）](#二ci-必需环境变量p0)
- [三、可选环境变量（有默认值）](#三可选环境变量有默认值)
- [四、测试专用环境变量](#四测试专用环境变量)
- [五、Worker 服务环境变量](#五worker-服务环境变量)
- [六、当前 CI 配置对照](#六当前-ci-配置对照)

---

## 一、配置来源说明

项目的环境变量配置主要来自以下几处：

| 来源 | 文件路径 | 说明 |
|------|---------|------|
| API 主配置 | `apps/api/app/config.py` | pydantic `Settings` 类，API 服务核心配置 |
| Worker 配置 | `apps/worker/worker_app/core/config.py` | pydantic `WorkerSettings` 类，Worker 服务配置 |
| 共享配置 | `packages/shared/config.py` | pydantic `SharedSettings` 类，API + Worker 共享配置 |
| 直接读取 | 各模块中 `os.environ` / `os.getenv` | 散落在各业务模块中的直接读取 |

> **注意**：pydantic-settings 配置默认 `case_sensitive=False`，即环境变量名不区分大小写，但习惯上使用大写。

---

## 二、CI 必需环境变量（P0）

以下变量是 CI 运行测试**必须配置**的，缺失会导致测试启动失败或核心功能异常。

| 变量名 | 用途说明 | 默认值 | 影响范围 |
|--------|---------|--------|---------|
| `DATABASE_URL` | 数据库连接字符串 | `postgresql+psycopg://postgres:postgres@localhost:5432/xiaoxia_saas` | 集成测试、 Alembic 迁移验证 |
| `USE_IN_MEMORY_DB` | 是否使用内存数据库（SQLite） | `false` | 单元测试（设为 `true` 可跳过 PostgreSQL 依赖） |
| `JWT_SECRET_KEY` | JWT 签名密钥，**无安全默认值**，必须显式设置 | `None`（启动校验失败） | 所有涉及认证的 API 测试 |

> **说明**：
> - 单元测试通过 `USE_IN_MEMORY_DB=true` 使用 SQLite 内存数据库，无需 PostgreSQL
> - 集成测试需要真实 PostgreSQL，需设置 `DATABASE_URL`
> - `JWT_SECRET_KEY` 在测试文件中通过 `os.environ.setdefault()` 设置了测试用默认值，CI 中可不额外配置，但生产环境必须配置

---

## 三、可选环境变量（有默认值）

以下变量都有合理的默认值，CI 中可以不配置，使用默认值即可。

### 3.1 应用基础配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `APP_NAME` | 应用名称 | `xiaoxia-saas` |
| `APP_VERSION` | 应用版本号 | `0.1.61` / `unknown` |
| `ENVIRONMENT` | 运行环境标识 | `development` |
| `DEBUG` | 是否开启调试模式 | `true` |
| `APP_BASE_URL` | 应用基础 URL（用于生成邮件链接等） | `http://localhost:3000` |
| `API_HOST` | API 服务绑定地址 | `0.0.0.0` |
| `API_PORT` | API 服务端口 | `8000` |
| `API_PREFIX` | API 路由前缀 | `/api/v1` |
| `APP_ENV` | 环境标识（用于加载 .env.{env} 文件） | `development` |
| `LOG_LEVEL` | 日志级别 | `INFO` |

### 3.2 数据库连接池配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `DATABASE_POOL_SIZE` | 连接池大小 | `20` |
| `DATABASE_MAX_OVERFLOW` | 最大溢出连接数 | `10` (API) / `40` (Worker) |
| `DATABASE_POOL_TIMEOUT` | 获取连接超时时间（秒） | `30` |
| `DATABASE_POOL_RECYLE` / `DATABASE_POOL_RECYCLE` | 连接回收时间（秒） | `3600` |
| `AUTO_CREATE_SCHEMA` | 是否自动创建表结构 | `false` |

### 3.3 Redis / Celery 配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `REDIS_URL` | Redis 连接地址 | `redis://localhost:6379/0` |
| `REDIS_MAX_CONNECTION` | Redis 最大连接数 | `50` |
| `ENABLE_REDIS_SESSIONS` | 是否启用 Redis 会话存储 | `false` |
| `CELERY_BROKER_URL` / `BROKER_URL` | Celery Broker 地址 | `redis://localhost:6379/0` |
| `CELERY_RESULT_BACKEND` / `RESULT_BACKEND` | Celery 结果后端 | `redis://localhost:6379/1` |

### 3.4 JWT 配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `JWT_ALGORITHM` | JWT 签名算法 | `HS256`（隐式默认） |
| `JWT_ACCESS_TOKEN_EXPIRE_MINUTES` | Access Token 过期时间（分钟） | `30`（隐式默认） |
| `JWT_REFRESH_TOKEN_EXPIRE_DAYS` | Refresh Token 过期时间（天） | `30`（隐式默认） |
| `JWT_SECRET_KEY_OLD` | 旧 JWT 密钥（用于密钥轮换） | `None` |
| `SECRET_ROTATION_DAYS` | 密钥轮换建议天数 | `90` |

### 3.5 邮件配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `ENABLE_EMAIL_DELIVERY` | 是否启用邮件发送 | `false` |
| `SMTP_HOST` | SMTP 服务器地址 | `smtp.gmail.com` |
| `SMTP_PORT` | SMTP 端口 | `587` |
| `SMTP_USER` | SMTP 用户名 | `""`（空） |
| `SMTP_PASSWORD` | SMTP 密码 | `""`（空） |
| `SMTP_FROM_EMAIL` | 发件人邮箱 | `""`（空） |
| `SMTP_FROM_NAME` | 发件人名称 | `小虾 SaaS` |
| `SMTP_USE_TLS` | 是否使用 TLS | `true` |

### 3.6 OSS 阿里云存储配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `OSS_ENDPOINT` | OSS Endpoint | `oss-cn-hangzhou.aliyuncs.com` |
| `OSS_ACCESS_KEY_ID` | OSS Access Key ID | `""`（空） |
| `OSS_ACCESS_KEY_SECRET` | OSS Access Key Secret | `""`（空） |
| `OSS_BUCKET_NAME` | OSS Bucket 名称 | `xiaoxia-autocut` |
| `OSS_DIRECT_UPLOAD_MAX_MB` / `MAX_UPLOAD_SIZE_MB` | 直传最大文件大小（MB） | `2000` |
| `OSS_DIRECT_UPLOAD_EXPIRE_SECONDS` | 直传签名过期时间（秒） | `900` |

### 3.7 CosyVoice 语音合成配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `COSYVOICE_API_KEY` | CosyVoice API Key | `""`（空） |
| `COSYVOICE_BASE_URL` | CosyVoice API 地址 | `https://dashscope.aliyuncs.com/api/v1/services/aigc/text2audio` |
| `COSYVOICE_MODEL` | CosyVoice 模型 | `cosyvoice-v1` |
| `COSYVOICE_VOICE` | 默认音色 | `longxiaochun` |
| `COSYVOICE_SAMPLE_RATE` | 采样率 | `22050` |
| `COSYVOICE_FORMAT` | 输出格式 | `mp3` |

### 3.8 CORS 配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `CORS_ORIGINS_RAW` | CORS 允许的源（逗号分隔） | `http://localhost:3000,http://localhost:5173,http://localhost:8000` |

### 3.9 文件存储 / 生成文件配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `GENERATED_FILES_DIR` | 生成文件本地存储目录 | `/app/generated` |
| `GENERATED_FILES_URL_PREFIX` | 生成文件访问 URL 前缀 | `/generated-files` |
| `VIDEO_OUTPUT_DIR` | 视频输出目录 | `{tempdir}/video_output` |
| `PUBLIC_API_BASE_URL` | 公开 API 基础 URL | `https://api.xiaoxiajianji.com` |

### 3.10 监控 / 指标配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `METRICS_AUTH_TOKEN` | Prometheus 指标接口认证 Token | `""`（空，不启用认证） |

### 3.11 内部 API 配置

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `INTERNAL_API_KEYS` | 内部 API 调用密钥列表（逗号分隔） | `""`（空） |

---

## 四、测试专用环境变量

以下变量仅在测试或冒烟测试脚本中使用。

| 变量名 | 用途说明 | 默认值 | 使用位置 |
|--------|---------|--------|---------|
| `SMOKE_TEST_PASSWORD` | 冒烟测试用的测试账号密码 | `changeme` | `scripts/smoke_*.py` |
| `MIGRATION_SINCE_REVISION` | 迁移安全检查的起始版本 | `None` | `scripts/check_migration_safety.py` |
| `MIGRATION_DIFF_AGAINST` | 迁移 diff 对比的目标分支/版本 | `None` | `scripts/check_migration_safety.py` |

---

## 五、Worker 服务环境变量

以下变量主要用于 Worker（Celery）服务，CI 的单元/集成测试通常不涉及。

| 变量名 | 用途说明 | 默认值 |
|--------|---------|--------|
| `WORKER_NAME` | Worker 名称 | `xiaoxia-saas-worker` |
| `WORKER_CONCURRENCY` | Worker 并发数 | `4` |
| `WORKER_MAX_TASKS_PER_CHILD` | 每个子进程最大任务数 | `1000` |

---

## 六、当前 CI 配置对照

当前 `.gitea/workflows/ci-cd.yml` 中 `validate` job 配置的环境变量：

| 变量名 | CI 配置值 | 是否必需 | 备注 |
|--------|----------|---------|------|
| `DATABASE_URL` | `postgresql+psycopg://postgres:postgres@127.0.0.1:5432/xiaoxia_saas` | ✅ 是 | Job 级别配置 |
| `USE_IN_MEMORY_DB` | `"false"`（Job 级） / `"true"`（单元测试 step 级） | ✅ 是 | 单元测试 step 覆盖为 `true` |
| `JWT_SECRET_KEY` | （未配置） | ⚠️ 测试内置 | 测试文件中通过 `setdefault` 设置了测试密钥 |

### 6.1 CI 环境变量现状评估

- ✅ **数据库配置完备**：DATABASE_URL + USE_IN_MEMORY_DB 已正确配置
- ✅ **JWT 密钥**：测试代码内置默认值，CI 可正常运行
- ⚠️ **缺少 Redis 配置**：但当前测试不依赖 Redis，使用默认值即可
- ⚠️ **缺少邮件/OSS/语音配置**：均为可选，CI 中使用空默认值不影响核心测试

### 6.2 建议后续补充

如果未来测试覆盖到以下功能，需要在 CI 中补充对应配置：

1. **Redis 相关测试** → 配置 `REDIS_URL`
2. **邮件发送测试** → 配置 `ENABLE_EMAIL_DELIVERY` 及 SMTP 相关变量
3. **OSS 上传测试** → 配置 OSS 相关变量（或使用 mock）
4. **语音合成测试** → 配置 CosyVoice 相关变量（或使用 mock）

---

## 附录：环境变量读取位置索引

### pydantic Settings 类
- `apps/api/app/config.py` → `Settings` 类（API 主配置）
- `apps/worker/worker_app/core/config.py` → `WorkerSettings` 类（Worker 配置）
- `packages/shared/config.py` → `SharedSettings` 类（共享配置）

### 直接 os.environ / os.getenv 读取
| 变量名 | 文件位置 |
|--------|---------|
| `VIDEO_OUTPUT_DIR` | `apps/worker/video_processing/video_compose_service.py`、`apps/worker/worker_app/tasks/compose_video.py` |
| `INTERNAL_API_KEYS` | `apps/api/app/api/routes/auth.py` |
| `APP_ENV` / `ENV` | `apps/api/app/api/routes/auth.py`、各 config.py 的 `get_settings()` |
| `GENERATED_FILES_DIR` | `apps/worker/worker_app/tasks/generation.py`、`apps/api/main.py`、`scripts/cleanup_generated_files.py` |
| `GENERATED_FILES_URL_PREFIX` | `apps/worker/worker_app/tasks/generation.py`、`apps/api/main.py`、`apps/api/app/core/storage.py` |
| `PUBLIC_API_BASE_URL` | `apps/worker/worker_app/tasks/generation.py` |
| `METRICS_AUTH_TOKEN` | `apps/api/app/middleware/prometheus_metrics.py` |
| `APP_VERSION` | `apps/api/app/middleware/prometheus_metrics.py` |
| `SMOKE_TEST_PASSWORD` | `scripts/smoke_*.py` |
| `MIGRATION_SINCE_REVISION` | `scripts/check_migration_safety.py` |
| `MIGRATION_DIFF_AGAINST` | `scripts/check_migration_safety.py` |
| `DATABASE_URL` | `alembic/env.py` |
