# 环境配置指南

## 环境区分方案

项目支持通过 `NODE_ENV` 环境变量和不同的 `.env` 文件来区分开发和生产环境。

## 配置文件结构

```
backend/
├── .env                    # 默认配置（可选，作为后备）
├── .env.development        # 开发环境配置
├── .env.production         # 生产环境配置
└── .env.test              # 测试环境配置（可选）
```

## 配置优先级

配置文件按以下优先级加载：

1. `.env.${NODE_ENV}` - 根据当前环境加载（最高优先级）
2. `.env` - 默认配置文件（后备）

例如：
- `NODE_ENV=development` → 加载 `.env.development`
- `NODE_ENV=production` → 加载 `.env.production`
- 未设置 `NODE_ENV` → 默认加载 `.env.development`，然后 `.env`

## 开发环境配置

### 创建 `.env.development` 文件

```env
# 开发环境配置
NODE_ENV=development

# 开发数据库（本地数据库）
DATABASE_URL="mysql://root:password@localhost:3306/competition_management_dev?schema=public"

# JWT 密钥（开发环境可以使用简单密钥）
JWT_SECRET="dev-secret-key-not-for-production"

# 服务器端口
PORT=3001

# 日志级别
LOG_LEVEL=debug

# CORS 配置（开发环境允许所有来源）
CORS_ORIGIN=*
```

### 开发环境数据库命名建议

- 数据库名：`competition_management_dev`
- 便于区分：开发和生产使用不同的数据库
- 安全：避免误操作生产数据

## 生产环境配置

### 创建 `.env.production` 文件

```env
# 生产环境配置
NODE_ENV=production

# 生产数据库（远程或云数据库）
DATABASE_URL="mysql://prod_user:strong_password@prod-db-host:3306/competition_management?schema=public&sslmode=require"

# JWT 密钥（必须使用强随机字符串）
# 生成方式: openssl rand -hex 32
JWT_SECRET="your-production-secret-key-must-be-strong-and-random-64-chars"

# 服务器端口
PORT=3001

# 日志级别
LOG_LEVEL=error

# CORS 配置（生产环境指定具体域名）
CORS_ORIGIN=https://yourdomain.com

# 数据库连接池配置
DB_POOL_MIN=2
DB_POOL_MAX=10

# SSL/TLS 配置
SSL_ENABLED=true
```

### 生产环境数据库配置要点

1. **使用独立的数据库服务器**
2. **启用 SSL 连接**（`sslmode=require`）
3. **使用强密码**
4. **限制数据库用户权限**（最小权限原则）
5. **定期备份**

## 使用方法

### 开发环境

```bash
# 方式 1: 设置环境变量后启动
NODE_ENV=development pnpm start:dev

# 方式 2: 在 package.json 中配置（推荐）
# 已自动配置，直接运行：
pnpm start:dev
```

### 生产环境

```bash
# 方式 1: 设置环境变量后启动
NODE_ENV=production pnpm start:prod

# 方式 2: 在部署脚本中设置
export NODE_ENV=production
pnpm start:prod
```

### 测试环境（可选）

```bash
# 创建 .env.test 文件
NODE_ENV=test
DATABASE_URL="mysql://root:password@localhost:3306/competition_management_test?schema=public"
JWT_SECRET="test-secret-key"
PORT=3002

# 运行测试
NODE_ENV=test pnpm test
```

## 数据库命名规范

建议使用以下命名规范来区分不同环境的数据库：

| 环境 | 数据库名 | 说明 |
|------|---------|------|
| 开发 | `competition_management_dev` | 开发环境数据库 |
| 测试 | `competition_management_test` | 测试环境数据库 |
| 生产 | `competition_management` | 生产环境数据库 |
| 预发布 | `competition_management_staging` | 预发布环境数据库 |

## 创建不同环境的数据库

### 开发环境数据库

```sql
CREATE DATABASE competition_management_dev 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;
```

### 生产环境数据库

```sql
CREATE DATABASE competition_management 
CHARACTER SET utf8mb4 
COLLATE utf8mb4_unicode_ci;
```

## 环境变量管理最佳实践

### 1. 使用 .gitignore

确保 `.env*` 文件不被提交到版本控制：

```gitignore
# .env files
.env
.env.local
.env.*.local
.env.development
.env.production
.env.test
```

### 2. 提供示例文件

创建 `.env.example` 或 `.env.*.example` 文件作为模板：

```bash
# 开发环境示例
cp .env.development.example .env.development

# 生产环境示例
cp .env.production.example .env.production
```

### 3. 使用环境变量管理工具（生产环境）

- **Docker**: 使用 `docker-compose.yml` 中的 `env_file`
- **Kubernetes**: 使用 `ConfigMap` 和 `Secret`
- **云平台**: 
  - AWS: Secrets Manager
  - Azure: Key Vault
  - GCP: Secret Manager

### 4. 验证配置

在应用启动时验证必要的环境变量：

```typescript
// 可以在 main.ts 中添加验证
if (!process.env.DATABASE_URL) {
  throw new Error('DATABASE_URL is required');
}
```

## 快速开始

### 1. 创建开发环境配置

```bash
cd backend

# 创建开发环境配置文件
cat > .env.development << EOF
NODE_ENV=development
DATABASE_URL="mysql://root:password@localhost:3306/competition_management_dev?schema=public"
JWT_SECRET="dev-secret-key"
PORT=3001
EOF
```

### 2. 创建生产环境配置

```bash
# 创建生产环境配置文件（不要提交到 Git）
cat > .env.production << EOF
NODE_ENV=production
DATABASE_URL="mysql://prod_user:password@prod-host:3306/competition_management?schema=public&sslmode=require"
JWT_SECRET="$(openssl rand -hex 32)"
PORT=3001
EOF
```

### 3. 初始化数据库

```bash
# 开发环境
NODE_ENV=development pnpm prisma:migrate dev

# 生产环境（部署时）
NODE_ENV=production pnpm prisma:migrate deploy
```

## 常见问题

### Q: 如何确保使用正确的环境配置？

A: 在启动应用前检查 `NODE_ENV` 环境变量：
```bash
echo $NODE_ENV  # 应该显示 development 或 production
```

### Q: 生产环境配置应该存储在哪里？

A: 
- **不要提交到 Git**
- 使用环境变量管理工具（如 Docker secrets、K8s secrets）
- 或使用云平台提供的密钥管理服务

### Q: 如何在不同环境间切换？

A: 通过设置 `NODE_ENV` 环境变量：
```bash
# 开发环境
export NODE_ENV=development
pnpm start:dev

# 生产环境
export NODE_ENV=production
pnpm start:prod
```

### Q: 数据库迁移如何区分环境？

A: Prisma 会根据 `DATABASE_URL` 环境变量自动使用对应的数据库：
```bash
# 开发环境迁移
NODE_ENV=development pnpm prisma:migrate dev

# 生产环境迁移
NODE_ENV=production pnpm prisma:migrate deploy
```

