# 配置管理指南

## 概述

Zulip 集成系统支持多种配置方式，包括环境变量、配置文件和运行时配置。本文档详细说明各配置项的用途和设置方法。

## 环境变量配置

### Zulip 服务器配置

```bash
# Zulip 服务器 URL
ZULIP_SERVER_URL=https://zulip.xinghangee.icu/

# Zulip Bot 邮箱
ZULIP_BOT_EMAIL=cbot-bot@zulip.xinghangee.icu

# Zulip Bot API Key
ZULIP_BOT_API_KEY=your-bot-api-key

# Zulip Realm (可选，默认从 URL 推断)
ZULIP_REALM=your-realm
```

### WebSocket 配置

```bash
# WebSocket 端口
WEBSOCKET_PORT=3000

# WebSocket 命名空间
WEBSOCKET_NAMESPACE=/game

# 最大连接数
WEBSOCKET_MAX_CONNECTIONS=100

# 连接超时时间 (毫秒)
WEBSOCKET_TIMEOUT=60000
```

### 消息配置

```bash
# 消息频率限制 (条/分钟)
MESSAGE_RATE_LIMIT=10

# 消息最大长度 (字符)
MESSAGE_MAX_LENGTH=1000

# 是否启用内容过滤
ENABLE_CONTENT_FILTER=true

# 是否启用重复检测
ENABLE_DUPLICATE_DETECTION=true
```

### 会话配置

```bash
# 会话超时时间 (分钟)
SESSION_TIMEOUT=30

# 会话清理间隔 (分钟)
SESSION_CLEANUP_INTERVAL=5

# 最大会话数
MAX_SESSIONS=5000
```

### Redis 配置

```bash
# Redis 主机
REDIS_HOST=localhost

# Redis 端口
REDIS_PORT=6379

# Redis 密码 (可选)
REDIS_PASSWORD=

# Redis 数据库索引
REDIS_DB=0

# Redis 键前缀
REDIS_KEY_PREFIX=zulip:
```

### 日志配置

```bash
# 日志级别 (debug, info, warn, error)
LOG_LEVEL=info

# 是否启用结构化日志
LOG_STRUCTURED=true

# 日志文件路径 (可选)
LOG_FILE_PATH=logs/zulip.log
```

## 配置文件

### 地图映射配置

文件位置: `config/zulip/map-config.json`

```json
{
  "version": "2.0.0",
  "lastModified": "2025-12-25T20:00:00.000Z",
  "description": "基于像素大地图的 Zulip 映射配置",
  "maps": [
    {
      "mapId": "whale_port",
      "mapName": "鲸之港",
      "zulipStream": "Whale Port",
      "description": "中心城区，交通枢纽与主要聚会点",
      "interactionObjects": [
        {
          "objectId": "whale_statue",
          "objectName": "鲸鱼雕像",
          "zulipTopic": "Announcements",
          "position": { "x": 600, "y": 400 }
        },
        {
          "objectId": "clock_tower",
          "objectName": "大本钟",
          "zulipTopic": "General Chat",
          "position": { "x": 550, "y": 350 }
        }
      ]
    },
    {
      "mapId": "pumpkin_valley",
      "mapName": "南瓜谷",
      "zulipStream": "Pumpkin Valley",
      "description": "新手成长、基础资源与学习社区",
      "interactionObjects": [
        {
          "objectId": "pumpkin_patch",
          "objectName": "南瓜田",
          "zulipTopic": "Tutorials",
          "position": { "x": 150, "y": 400 }
        },
        {
          "objectId": "farm_house",
          "objectName": "农舍",
          "zulipTopic": "Study Group",
          "position": { "x": 200, "y": 450 }
        }
      ]
    },
    {
      "mapId": "offer_city",
      "mapName": "Offer 城",
      "zulipStream": "Offer City",
      "description": "职业发展、面试与商务区",
      "interactionObjects": [
        {
          "objectId": "skyscrapers",
          "objectName": "摩天大楼",
          "zulipTopic": "Career Talk",
          "position": { "x": 350, "y": 650 }
        }
      ]
    },
    {
      "mapId": "model_factory",
      "mapName": "模型工厂",
      "zulipStream": "Model Factory",
      "description": "AI模型训练、代码构建与工业区",
      "interactionObjects": [
        {
          "objectId": "assembly_line",
          "objectName": "流水线",
          "zulipTopic": "Code Review",
          "position": { "x": 400, "y": 200 }
        }
      ]
    }
  ]
}
```

系统现在支持 9 个地图区域：

1. **鲸之港 (Whale Port)** - 中心城区，交通枢纽与主要聚会点
2. **南瓜谷 (Pumpkin Valley)** - 新手成长、基础资源与学习社区
3. **Offer 城 (Offer City)** - 职业发展、面试与商务区
4. **模型工厂 (Model Factory)** - AI模型训练、代码构建与工业区
5. **内核岛 (Kernel Island)** - 核心技术研究、底层原理与算法
6. **摸鱼海滩 (Moyu Beach)** - 休闲娱乐、水贴与非技术话题
7. **天梯峰 (Ladder Peak)** - 挑战、竞赛与排行榜
8. **星河湾 (Galaxy Bay)** - 创意、设计与灵感
9. **数据遗迹 (Data Ruins)** - 数据库、归档与历史记录

### 配置字段说明

| 字段 | 类型 | 必填 | 说明 |
|-----|------|-----|------|
| version | string | 是 | 配置版本号 |
| lastModified | string | 否 | 最后修改时间 (ISO 8601) |
| description | string | 否 | 配置文件描述 |
| maps | array | 是 | 地图配置数组 |
| maps[].mapId | string | 是 | 地图唯一标识 |
| maps[].mapName | string | 是 | 地图显示名称 |
| maps[].zulipStream | string | 是 | 对应的 Zulip Stream |
| maps[].description | string | 否 | 地图区域描述 |
| maps[].defaultTopic | string | 否 | 默认 Topic，默认 "General" |
| maps[].interactionObjects | array | 否 | 交互对象配置 |
| interactionObjects[].objectId | string | 是 | 对象唯一标识 |
| interactionObjects[].objectName | string | 是 | 对象显示名称 |
| interactionObjects[].zulipTopic | string | 是 | 对应的 Zulip Topic |
| interactionObjects[].position | object | 是 | 对象位置坐标 |
| interactionObjects[].radius | number | 否 | 交互半径，默认 50 |

### 敏感词配置

文件位置: `config/zulip/sensitive-words.json`

```json
{
  "version": "1.0.0",
  "words": [
    "敏感词1",
    "敏感词2"
  ],
  "patterns": [
    "正则表达式1",
    "正则表达式2"
  ],
  "replacements": {
    "原词": "替换词"
  }
}
```

### 允许的 Stream 配置

文件位置: `config/zulip/allowed-streams.json`

```json
{
  "version": "1.0.0",
  "streams": [
    "Novice Village",
    "Market Square",
    "Guild Hall",
    "Arena"
  ],
  "privateStreams": [
    "Admin",
    "Moderators"
  ]
}
```

## 运行时配置

### 通过 API 更新配置

```typescript
// 更新消息频率限制
await configManager.updateConfig('messageRateLimit', 20);

// 更新会话超时时间
await configManager.updateConfig('sessionTimeout', 60);

// 重新加载地图配置
await configManager.reloadMapConfig();
```

### 配置热重载

系统支持配置热重载，无需重启服务：

```bash
# 发送 SIGHUP 信号触发配置重载
kill -HUP <pid>
```

或通过 API：

```bash
curl -X POST http://localhost:3000/admin/config/reload \
  -H "Authorization: Bearer <admin_token>"
```

## 配置验证

### 启动时验证

系统在启动时会验证所有配置的有效性：

```typescript
// 配置验证示例
const configValidator = new ConfigValidator();

// 验证环境变量
configValidator.validateEnv({
  ZULIP_SERVER_URL: { required: true, type: 'url' },
  ZULIP_BOT_EMAIL: { required: true, type: 'email' },
  ZULIP_BOT_API_KEY: { required: true, type: 'string' },
  MESSAGE_RATE_LIMIT: { required: false, type: 'number', default: 10 },
});

// 验证地图配置
configValidator.validateMapConfig(mapConfig);
```

### 验证错误处理

配置验证失败时，系统会：

1. 记录详细的错误日志
2. 输出错误信息到控制台
3. 阻止服务启动（严重错误）或使用默认值（非严重错误）

```
[ERROR] 配置验证失败:
  - ZULIP_SERVER_URL: 必填项未设置
  - MESSAGE_RATE_LIMIT: 值必须大于 0
  - map-config.json: maps[0].zulipStream 不能为空
```

## Stream 初始化

### 自动初始化服务

系统在启动时会自动检查所有地图配置中定义的 Zulip Streams 是否存在。如果发现缺失的 Streams，会尝试自动创建。

**服务配置:**

```typescript
// Stream 初始化服务会在系统启动 5 秒后自动运行
// 位置: src/core/zulip_core/services/stream_initializer.service.ts

@Injectable()
export class StreamInitializerService implements OnModuleInit {
  async onModuleInit() {
    // 延迟 5 秒启动，确保其他服务已就绪
    setTimeout(() => {
      this.initializeStreams();
    }, 5000);
  }
}
```

### 权限要求

创建 Zulip Streams 需要特定权限：

- **Bot 账号**: 默认情况下可能缺少创建 Stream 的权限
- **管理员账号**: 拥有完整的 Stream 创建权限

**解决方案:**

1. **方案一**: 在 Zulip 服务器中为 Bot 账号授予创建 Stream 的权限
   - 登录 Zulip 管理后台
   - 找到 Bot 账号设置
   - 授予 "Create streams" 权限

2. **方案二**: 使用管理员账号手动创建 Streams
   - 使用提供的测试脚本 `test-stream-initialization.js`
   - 配置管理员 API Key
   - 运行脚本自动创建所有 Streams

3. **方案三**: 在 Zulip 网页界面手动创建
   - 登录 Zulip 网页界面
   - 创建对应的 Streams (参考 `config/zulip/map-config.json`)

### 手动创建 Streams

使用测试脚本创建所有地图区域的 Streams：

```bash
# 编辑 test-stream-initialization.js，配置管理员 API Key
# 然后运行脚本
node test-stream-initialization.js
```

脚本会自动创建以下 Streams：

- Whale Port (鲸之港)
- Pumpkin Valley (南瓜谷)
- Offer City (Offer 城)
- Model Factory (模型工厂)
- Kernel Island (内核岛)
- Moyu Beach (摸鱼海滩)
- Ladder Peak (天梯峰)
- Galaxy Bay (星河湾)
- Data Ruins (数据遗迹)

### 初始化日志

系统会记录 Stream 初始化的详细日志：

```
[INFO] 开始初始化 Zulip Streams...
[INFO] 检查 Stream: Whale Port
[INFO] Stream 已存在: Whale Port
[WARN] Stream 不存在，尝试创建: Pumpkin Valley
[INFO] Stream 创建成功: Pumpkin Valley
[ERROR] Stream 创建失败: Offer City - Insufficient permission
```

## 配置最佳实践

### 1. 使用环境变量管理敏感信息

```bash
# 不要在代码中硬编码敏感信息
# 使用环境变量或密钥管理服务

# 开发环境
export ZULIP_BOT_API_KEY=dev-api-key

# 生产环境 (使用密钥管理服务)
export ZULIP_BOT_API_KEY=$(aws secretsmanager get-secret-value --secret-id zulip-api-key --query SecretString --output text)
```

### 2. 分环境配置

```
config/
├── zulip/
│   ├── map-config.json          # 默认配置
│   ├── map-config.dev.json      # 开发环境
│   ├── map-config.staging.json  # 预发布环境
│   └── map-config.prod.json     # 生产环境
```

```typescript
// 根据环境加载配置
const env = process.env.NODE_ENV || 'development';
const configPath = `config/zulip/map-config.${env}.json`;
```

### 3. 配置版本控制

- 将配置文件纳入版本控制
- 使用 `.env.example` 提供配置模板
- 敏感配置使用 `.gitignore` 排除

### 4. 配置文档化

为每个配置项提供清晰的文档说明：

```typescript
/**
 * 消息频率限制配置
 * 
 * @description 限制用户每分钟可发送的消息数量
 * @default 10
 * @range 1-100
 * @env MESSAGE_RATE_LIMIT
 */
messageRateLimit: number;
```

## 故障排除

### 常见配置问题

#### 1. Zulip 连接失败

```
错误: ZULIP_CONNECTION_FAILED
原因: 无法连接到 Zulip 服务器
```

检查项:
- `ZULIP_SERVER_URL` 是否正确
- 网络是否可达
- API Key 是否有效

#### 2. 地图配置加载失败

```
错误: MAP_CONFIG_LOAD_FAILED
原因: 地图配置文件格式错误
```

检查项:
- JSON 格式是否正确
- 必填字段是否完整
- 字段类型是否正确

#### 3. Redis 连接失败

```
错误: REDIS_CONNECTION_FAILED
原因: 无法连接到 Redis 服务器
```

检查项:
- `REDIS_HOST` 和 `REDIS_PORT` 是否正确
- Redis 服务是否运行
- 密码是否正确

### 配置诊断命令

```bash
# 检查配置有效性
npm run config:validate

# 显示当前配置
npm run config:show

# 测试 Zulip 连接
npm run config:test-zulip

# 测试 Redis 连接
npm run config:test-redis
```
