# 考培练系统 - 部署架构（统一版）

> 更新日期：2026-01-18（新增 SaaS 超级管理后台，统一租户配置管理）
> 
> 本文档描述了考培练系统的统一部署架构，实现代码热重载和快速更新。
> 
> **核心特性**：
> - 前后端均采用共享代码方案，一次构建/修改，全部租户同步更新
> - **新增**：SaaS 超级管理后台，统一管理所有租户配置、AI提示词、功能开关

## 一、架构概览

```
                    ┌─────────────────────────────────────┐
                    │        kaopeilian-nginx             │
                    │       (入口反向代理服务器)            │
                    │      80/443 端口                    │
                    └───────────────┬─────────────────────┘
                                    │
    ┌───────────────────────────────┼───────────────────────────────┐
    │               │               │               │               │
    ▼               ▼               ▼               ▼               ▼
┌─────────┐  ┌───────────┐  ┌───────────┐  ┌───────────┐  ┌───────────┐
│管理后台  │  │ 演示版    │  │ 多客户版   │  │ 瑞小美    │  │陪练试用版  │
│admin.*  │  │ aiedu.*  │  │yy/hl/xy.. │  │ kpl.*    │  │ pl.*     │
└─────────┘  └───────────┘  └───────────┘  └───────────┘  └───────────┘
    │
    ▼
┌─────────────┐
│kaopeilian_  │
│admin (管理库)│
└─────────────┘
```

## 二、容器清单

### 2.1 基础设施层

| 容器名称 | 镜像 | 端口 | 说明 |
|---------|------|------|------|
| kaopeilian-nginx | nginx:1.25-alpine | 80, 443 | 入口反向代理 |
| kaopeilian-mysql | mysql:8.0.43 | 3307 | 演示版数据库 |
| kaopeilian-redis | redis:7.2-alpine | 6379 | 演示版 Redis |
| kpl-mysql-dev | mysql:8.0.43 | 3308 | 瑞小美数据库 |
| kpl-redis-dev | redis:7.2-alpine | 6380 | 瑞小美 Redis |
| prod-mysql | mysql:8.0.43 | 3309 | 多客户共享数据库 |
| peilian-mysql | mysql:8.0.43 | 3310 | 陪练试用版数据库 |
| peilian-redis | redis:7.2-alpine | 6382 | 陪练试用版 Redis |

### 2.2 前端层（共享 dist 方案）

所有前端容器使用同一个 `kaopeilian-frontend:shared` 镜像，挂载共享的 dist 目录：

| 容器名称 | 对应域名 | 端口 | 说明 |
|---------|---------|------|------|
| kaopeilian-frontend | aiedu.ireborn.com.cn | - | 演示版（无外部端口映射） |
| kpl-frontend-dev | kpl.ireborn.com.cn | 3002:80 | 瑞小美 |
| hua-frontend | hua.ireborn.com.cn | 3010:80 | 华尔倍丽 |
| yy-frontend | yy.ireborn.com.cn | 3011:80 | 杨扬宠物 |
| hl-frontend | hl.ireborn.com.cn | 3012:80 | 武汉禾丽 |
| xy-frontend | xy.ireborn.com.cn | 3013:80 | 芯颜定制 |
| fw-frontend | fw.ireborn.com.cn | 3014:80 | 飞沃 |
| ex-frontend | ex.ireborn.com.cn | 3015:80 | 恩喜成都总院 |

#### 独立部署前端

| 容器名称 | 对应域名 | 端口 | 说明 |
|---------|---------|------|------|
| peilian-frontend | pl.ireborn.com.cn | 3020:3000 | 陪练试用版（独立代码库） |

**共享前端配置说明：**
- 镜像：`kaopeilian-frontend:shared`（仅含 nginx，不含代码）
- 挂载：`/root/aiedu/kaopeilian-frontend/dist:/usr/share/nginx/html:ro`
- 原理：前端代码使用 `window.location.origin` 动态获取 API 地址，支持多域名部署
- 优势：一次 `npm run build`（约3分钟），8 个租户同时更新
- 配置文件：`/root/aiedu/docker-compose.prod-multi.yml`（所有租户前端配置已统一）

### 2.3 后端层（代码热重载）

所有后端容器挂载同一个代码目录，实现统一代码管理：

| 容器名称 | 对应域名 | 端口 | 数据库 |
|---------|---------|------|--------|
| kaopeilian-backend | aiedu.ireborn.com.cn | 8000 | kaopeilian-mysql |
| kpl-backend-dev | kpl.ireborn.com.cn | 8001 | kpl-mysql-dev |
| hua-backend | hua.ireborn.com.cn | 8010 | prod-mysql |
| yy-backend | yy.ireborn.com.cn | 8011 | prod-mysql |
| hl-backend | hl.ireborn.com.cn | 8012 | prod-mysql |
| xy-backend | xy.ireborn.com.cn | 8013 | prod-mysql |
| fw-backend | fw.ireborn.com.cn | 8014 | prod-mysql |
| ex-backend | ex.ireborn.com.cn | 8015 | prod-mysql |
| peilian-backend | pl.ireborn.com.cn | 8020 | peilian-mysql |

**共享配置：**
- 代码目录：`/root/aiedu/kaopeilian-backend/app:/app/app`
- 启动命令：`uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload`

### 2.4 Redis 缓存层

| 容器名称 | 端口 | 对应租户 |
|---------|------|---------|
| kaopeilian-redis | 6379 | 演示版 |
| kpl-redis-dev | 6380 | 瑞小美 |
| peilian-redis | 6382 | 陪练试用版 |
| hua-redis | 6390 | 华尔倍丽 |
| yy-redis | 6391 | 杨扬宠物 |
| hl-redis | 6392 | 武汉禾丽 |
| xy-redis | 6393 | 芯颜定制 |
| fw-redis | 6394 | 飞沃 |
| ex-redis | 6395 | 恩喜成都总院 |

## 三、代码更新方式

### 3.1 后端代码更新

**方式：自动热重载**

直接修改 `/root/aiedu/kaopeilian-backend/app/` 下的文件，所有后端容器会自动检测变更并重载。

```bash
# 示例：修改 admin.py
vim /root/aiedu/kaopeilian-backend/app/api/v1/admin.py
# 保存后自动生效，无需任何操作
```

### 3.2 前端代码更新

**方式：一次构建，全部更新**

```bash
cd /root/aiedu/kaopeilian-frontend && npm run build
```

构建完成后，所有共享前端容器自动提供最新的静态文件，无需重启。

## 四、配置文件位置

### 4.1 Docker Compose 文件

| 文件 | 说明 |
|------|------|
| `/root/aiedu/docker-compose.yml` | 演示版（含 Nginx） |
| `/root/aiedu/docker-compose.kpl.yml` | 瑞小美后端 |
| `/root/aiedu/docker-compose.prod-multi.yml` | **多客户前端 + 后端 + Redis（已统一，推荐）** |

> **重要**：2026-01-17 已将所有租户前端配置统一到 `docker-compose.prod-multi.yml`，使用共享 dist 挂载方式。

### 4.2 Nginx 配置

| 文件 | 对应域名 |
|------|---------|
| `/root/aiedu/nginx/conf.d/kaopeilian.conf` | aiedu.ireborn.com.cn |
| `/root/aiedu/nginx/conf.d/kpl.conf` | kpl.ireborn.com.cn |
| `/root/aiedu/nginx/conf.d/pl.conf` | pl.ireborn.com.cn |
| `/root/aiedu/nginx/conf.d/yy.conf` | yy.ireborn.com.cn |
| `/root/aiedu/nginx/conf.d/hl.conf` | hl.ireborn.com.cn |
| `/root/aiedu/nginx/conf.d/xy.conf` | xy.ireborn.com.cn |
| `/root/aiedu/nginx/conf.d/fw.conf` | fw.ireborn.com.cn |
| `/root/aiedu/nginx/conf.d/hua.conf` | hua.ireborn.com.cn |
| `/root/aiedu/nginx/conf.d/ex.conf` | ex.ireborn.com.cn |

### 4.3 环境变量文件

| 文件 | 说明 |
|------|------|
| `/root/aiedu/kaopeilian-backend/.env.production` | 演示版 |
| `/data/prod-envs/kaopeilian-backend/.env.yy` | 杨扬宠物 |
| `/data/prod-envs/kaopeilian-backend/.env.hl` | 武汉禾丽 |
| `/data/prod-envs/kaopeilian-backend/.env.xy` | 芯颜定制 |
| `/data/prod-envs/kaopeilian-backend/.env.fw` | 飞沃 |
| `/data/prod-envs/kaopeilian-backend/.env.hua` | 华尔倍丽 |
| `/data/prod-envs/kaopeilian-backend/.env.ex` | 恩喜成都总院 |

## 五、常用运维命令

### 5.1 查看容器状态
```bash
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | sort
```

### 5.2 重启后端（热重载失效时）
```bash
# 重启所有后端
docker restart kaopeilian-backend kpl-backend-dev yy-backend hl-backend xy-backend fw-backend hua-backend peilian-backend
```

### 5.3 更新前端（共享 dist 方案）
```bash
# 一次构建，所有 8 个租户自动更新
cd /root/aiedu/kaopeilian-frontend && npm run build

# 如需强制刷新，可重启前端容器（通常不需要）
cd /root/aiedu && docker compose -f docker-compose.prod-multi.yml restart hua-frontend yy-frontend hl-frontend xy-frontend fw-frontend
```

### 5.4 重新加载 Nginx
```bash
docker exec kaopeilian-nginx nginx -s reload
```

### 5.5 查看后端日志
```bash
# 指定租户
docker logs -f yy-backend --tail 100

# 所有后端
for c in kaopeilian-backend kpl-backend-dev yy-backend hl-backend xy-backend fw-backend hua-backend peilian-backend; do
  echo "=== $c ===" && docker logs $c --tail 5
done
```

### 5.6 启动多客户服务（前端+后端+Redis）
```bash
cd /root/aiedu && docker compose -f docker-compose.prod-multi.yml up -d
```

### 5.7 验证前端统一部署状态
```bash
# 检查所有前端容器是否使用共享 dist 目录
for c in ex-frontend kpl-frontend-dev kaopeilian-frontend hl-frontend xy-frontend hua-frontend yy-frontend fw-frontend; do
  mount=$(docker inspect $c --format='{{range .Mounts}}{{if eq .Destination "/usr/share/nginx/html"}}{{.Source}}{{end}}{{end}}' 2>/dev/null)
  status=$(docker inspect $c --format='{{.State.Health.Status}}' 2>/dev/null)
  echo "$c: $mount ($status)"
done
```

## 六、数据库连接信息

### 6.1 演示版数据库
- 主机：kaopeilian-mysql（内部）/ 120.79.247.16:3307（外部）
- 数据库：kaopeilian
- 用户：root
- 密码：nj861021

### 6.2 瑞小美数据库
- 主机：kpl-mysql-dev（内部）/ 120.79.247.16:3308（外部）
- 数据库：kaopeilian
- 用户：root
- 密码：nj861021

### 6.3 多客户共享数据库
- 主机：prod-mysql（内部）/ 120.79.247.16:3309（外部）
- 各租户独立数据库：kaopeilian_yy, kaopeilian_hl, kaopeilian_xy, kaopeilian_fw, kaopeilian_hua, kaopeilian_ex
- 用户：root
- 密码：ProdMySQL2025!@#

### 6.4 陪练试用版数据库
- 主机：peilian-mysql（内部）/ 120.79.247.16:3310（外部）
- 数据库：peilian
- 用户：root
- 密码：nj861021

## 七、架构优势

| 特性 | 说明 |
|------|------|
| **代码统一** | 所有租户共享同一份前端和后端代码 |
| **后端热重载** | 修改代码自动生效，无需重启 |
| **前端快速更新** | 一次构建（约3分钟），8 个租户同时更新 |
| **配置隔离** | 各租户通过独立的 .env 文件和数据库隔离 |
| **版本一致性** | 所有租户始终使用相同版本，避免版本不一致问题 |
| **磁盘节省** | 共享 1 份 dist（~30MB），而非 8 个独立镜像（~800MB） |
| **易于维护** | 统一的代码库，便于问题排查和功能迭代 |

### 共享前端方案注意事项

1. **更新流程**：修改代码 → `pnpm run build` → 自动生效
2. **回滚方法**：备份 dist 目录 `cp -r dist dist.backup`，回滚时恢复即可
3. **无需重启**：构建完成后，nginx 自动提供新文件，用户刷新页面即可
4. **浏览器缓存**：HTML 文件设置为不缓存，JS/CSS 带 hash 可长期缓存

## 7.5 Docker Compose 部署规范

> 参考：《瑞小美系统技术栈标准与字符标准.md》

### 镜像版本

**禁用 latest 标签**，必须使用具体版本号：

```yaml
# ❌ 错误
image: kaopeilian-admin-frontend:latest

# ✅ 正确
image: kaopeilian-admin-frontend:1.0.0
```

### 日志配置（必须）

所有容器必须配置日志轮转：

```yaml
logging:
  driver: "json-file"
  options:
    max-size: "10m"
    max-file: "3"
```

### 资源限制（必须）

| 容器类型 | 内存限制 | 说明 |
|---------|---------|------|
| 前端容器 | 256M-512M | Nginx 静态文件服务 |
| 后端容器 | 512M-1G | FastAPI 业务服务 |

```yaml
deploy:
  resources:
    limits:
      cpus: '1'
      memory: 512M
    reservations:
      cpus: '0.25'
      memory: 128M
```

### 敏感信息管理

**禁止硬编码密码**，使用 `env_file` 方式：

```yaml
# ❌ 错误
environment:
  - ADMIN_DB_PASSWORD=xxxxx

# ✅ 正确
env_file:
  - .env.admin
```

`.env` 文件权限必须设置为 600：
```bash
chmod 600 .env.admin
```

## 八、数据存储架构

### 8.1 磁盘规划

| 磁盘 | 挂载点 | 容量 | 已用 | 可用 | 用途 |
|------|--------|------|------|------|------|
| 系统盘 /dev/vda3 | / | 79G | 35G | 41G | 系统 + Docker 镜像 |
| 数据盘 /dev/vdb1 | /data | 60G | 1.6G | 55G | 持久化数据（上传文件、数据库、备份） |

### 8.2 数据盘目录结构

```
/data/
├── kaopeilian/                    # 考培练系统数据根目录
│   ├── uploads/                   # 统一上传文件存储（按租户隔离）
│   │   ├── demo/                  # 演示版 (aiedu.ireborn.com.cn)
│   │   ├── kpl/                   # 瑞小美 (kpl.ireborn.com.cn)
│   │   ├── yy/                    # 杨扬宠物
│   │   ├── hl/                    # 武汉禾丽
│   │   ├── xy/                    # 芯颜定制
│   │   ├── fw/                    # 飞沃
│   │   ├── hua/                   # 华尔倍丽
│   │   ├── ex/                    # 恩喜成都总院
│   │   └── peilian/               # 陪练试用版
│   ├── backups/                   # 数据库备份
│   │   ├── daily/                 # 每日备份（保留7天）
│   │   └── weekly/                # 每周备份（保留4周）
│   └── logs/                      # 应用日志归档
├── mysql-data/                    # MySQL 数据目录
├── redis-data/                    # Redis 数据目录
└── prod-envs/                     # 生产环境配置
```

### 8.3 自动备份

- **备份脚本**：`/data/kaopeilian/backup.sh`
- **执行时间**：每天凌晨 2:00
- **备份内容**：所有租户的上传文件和数据库
- **保留策略**：日备份保留 7 天，周备份保留 4 周

## 九、网络架构

### Docker 网络

| 网络名称 | 说明 |
|---------|------|
| kaopeilian-network | 演示版容器网络 |
| kpl-dev-network | 瑞小美开发网络 |
| prod-network | 多客户生产网络 |

## 十、SSL 证书管理

### 10.1 证书概览

所有域名使用 Let's Encrypt 免费证书，有效期 90 天，自动续期。

| 域名 | 证书路径 | 续期方式 |
|------|---------|---------|
| aiedu.ireborn.com.cn | /etc/letsencrypt/live/aiedu.ireborn.com.cn/ | webroot |
| hua.ireborn.com.cn | /etc/letsencrypt/live/hua.ireborn.com.cn/ | webroot |
| yy.ireborn.com.cn | /etc/letsencrypt/live/yy.ireborn.com.cn/ | webroot |
| hl.ireborn.com.cn | /etc/letsencrypt/live/hl.ireborn.com.cn/ | webroot |
| xy.ireborn.com.cn | /etc/letsencrypt/live/xy.ireborn.com.cn/ | webroot |
| fw.ireborn.com.cn | /etc/letsencrypt/live/fw.ireborn.com.cn/ | webroot |
| kpl.ireborn.com.cn | /etc/letsencrypt/live/kpl.ireborn.com.cn/ | webroot |
| pl.ireborn.com.cn | /etc/letsencrypt/live/pl.ireborn.com.cn/ | webroot |
| ex.ireborn.com.cn | /etc/letsencrypt/live/ex.ireborn.com.cn/ | webroot |

### 10.2 自动续期机制

系统已配置三重保障，确保证书不会过期：

**1. Certbot 定时器（主力）**
- 服务：`certbot-renew.timer`
- 频率：每 12 小时检查一次
- 策略：证书到期前 30 天自动续期

```bash
# 查看定时器状态
systemctl status certbot-renew.timer

# 手动测试续期（不会真正续期）
certbot renew --dry-run
```

**2. 续期后自动重载 Nginx**
- Hook 脚本：`/etc/letsencrypt/renewal-hooks/deploy/reload-nginx.sh`
- 作用：证书续期成功后自动重载 Docker nginx，使新证书生效

**3. 证书到期监控**
- 脚本：`/root/scripts/check-ssl-expiry.sh`
- 频率：每周一上午 9 点（cron）
- 日志：`/var/log/ssl-check.log`
- 预警：证书有效期不足 30 天时输出警告

### 10.3 常用命令

```bash
# 查看所有证书状态
certbot certificates

# 手动续期所有证书
certbot renew

# 强制续期指定证书
certbot renew --cert-name aiedu.ireborn.com.cn --force-renewal

# 手动重载 nginx
docker exec kaopeilian-nginx nginx -s reload

# 查看证书到期日期
for cert in /etc/letsencrypt/live/*/fullchain.pem; do
  domain=$(basename $(dirname $cert))
  expiry=$(openssl x509 -enddate -noout -in "$cert" | cut -d= -f2)
  echo "$domain: $expiry"
done
```

### 10.4 故障排查

**问题：证书续期失败**
1. 检查 webroot 目录：`ls -la /var/www/certbot/.well-known/acme-challenge/`
2. 检查 nginx 配置是否有 acme-challenge 路由
3. 查看日志：`tail -100 /var/log/letsencrypt/letsencrypt.log`

**问题：续期成功但 HTTPS 仍显示过期**
1. 重载 nginx：`docker exec kaopeilian-nginx nginx -s reload`
2. 检查 hook 脚本权限：`ls -la /etc/letsencrypt/renewal-hooks/deploy/`

## 十一、AI 服务配置（Python 原生实现）

> 更新日期：2026-01-21（AI 配置从管理库加载）

### 11.1 概述

所有 AI 功能均使用 **Python 原生实现**，直接调用 AI API，无外部平台依赖。

**特点**：
- 双服务商自动降级（4sapi.com → OpenRouter）
- JSON 解析多层兜底，成功率 99%+
- 无外部平台依赖，100% 可控
- 统一的提示词管理
- **AI 配置从管理库（kaopeilian_admin）统一加载**

### 11.2 配置加载架构

```
┌─────────────────────────────────────────────────────────────┐
│  kaopeilian_admin 数据库（prod-mysql:3309）                   │
│  ├── tenants 表（租户信息）                                    │
│  │   └── id, code, name, status                             │
│  └── tenant_configs 表（租户配置）                             │
│      └── tenant_id, config_group='ai', config_key, config_value │
└──────────────────────────────────────────────────────────────┘
                               │
                               ▼ AIService 启动时同步查询
┌──────────────────────────────────────────────────────────────┐
│  后端容器（需配置以下环境变量）                                  │
│  - TENANT_CODE=ex                                            │
│  - ADMIN_DB_HOST=prod-mysql                                  │
│  - ADMIN_DB_PASSWORD=ProdMySQL2025!@#                        │
│  - ADMIN_DB_NAME=kaopeilian_admin                            │
└──────────────────────────────────────────────────────────────┘
```

**配置加载优先级**：
1. 管理库 `tenant_configs` 表（按 TENANT_CODE 查询）
2. 环境变量 `.env` 文件（fallback）
3. 代码默认值

### 11.3 管理库中的 AI 配置项

| config_key | 说明 |
|------------|------|
| AI_PRIMARY_API_KEY | 首选服务商 Key (4sapi.com) |
| AI_ANTHROPIC_API_KEY | Claude 专属 Key |
| AI_PRIMARY_BASE_URL | 首选服务商地址 |
| AI_FALLBACK_API_KEY | 备选服务商 Key (OpenRouter) |
| AI_FALLBACK_BASE_URL | 备选服务商地址 |
| AI_DEFAULT_MODEL | 默认模型 |
| AI_TIMEOUT | 请求超时（秒） |

### 11.4 容器环境变量配置（必须！）

每个后端容器的 `.env` 文件必须包含管理库连接信息：

```env
# 租户标识（用于从管理库查询配置）
TENANT_CODE=ex

# 管理库连接配置
ADMIN_DB_HOST=prod-mysql
ADMIN_DB_PORT=3306
ADMIN_DB_USER=root
ADMIN_DB_PASSWORD=ProdMySQL2025!@#
ADMIN_DB_NAME=kaopeilian_admin
```

> ⚠️ **重要**：修改 `.env` 文件后必须重启容器：`docker compose up -d --force-recreate`

### 11.3 已支持的 AI 功能

| 功能 | API 端点 | 服务文件 |
|-----|---------|---------|
| 知识点分析 | `/api/v1/courses/{id}/materials/{mid}/analyze` | `knowledge_analysis_v2.py` |
| 试题生成 | `/api/v1/exams/generate` | `exam_generator_service.py` |
| 答案判断 | `/api/v1/exams/judge-answer` | `answer_judge_service.py` |
| 陪练场景提取 | `/api/v1/practice/extract-scene` | `practice_scene_service.py` |
| 陪练分析报告 | `/api/v1/practice/sessions/{id}/analyze` | `practice_analysis_service.py` |
| 能力评估 | `/api/v1/ability/analyze-yanji` | `ability_analysis_service.py` |
| 课程对话 | `/api/v1/course/chat` | `course_chat_service.py` |

### 11.4 相关代码文件

| 文件 | 说明 |
|------|------|
| `app/services/ai/ai_service.py` | AI 服务（双服务商降级） |
| `app/services/ai/llm_json_parser.py` | LLM JSON 输出解析器 |
| `app/services/ai/knowledge_analysis_v2.py` | 知识点分析服务 |
| `app/services/ai/exam_generator_service.py` | 试题生成服务 |
| `app/services/ai/ability_analysis_service.py` | 智能工牌能力分析服务 |
| `app/services/ai/course_chat_service.py` | 课程对话服务 |
| `app/services/ai/answer_judge_service.py` | 答案判断服务 |
| `app/services/ai/practice_analysis_service.py` | 陪练分析报告服务 |
| `app/services/ai/practice_scene_service.py` | 陪练场景提取服务 |
| `app/services/ai/prompts/` | 提示词模板目录 |

### 11.5 依赖包

在 `requirements.txt` 中已添加：

```
json-repair>=0.25.0
jsonschema>=4.0.0
PyPDF2>=3.0.0
python-docx>=1.0.0
```

## 十二、课程对话会话管理

### 12.1 会话存储

课程对话使用 Redis 存储会话历史和会话索引：

| 配置 | 值 | 说明 |
|------|-----|------|
| 会话数据 Key | `course_chat:conversation:{id}` | Redis 存储 key |
| 会话索引 Key | `course_chat:user:{user_id}:conversations` | Sorted Set，按时间排序 |
| 会话元数据 Key | `course_chat:meta:{id}` | 会话课程ID等元信息 |
| ID 格式 | `conv_{user_id}_{course_id}_{uuid}` | 会话 ID 格式 |
| 窗口大小 | 10 轮 | 保留最近对话数 |
| TTL | 30 分钟 | 会话过期时间 |

### 12.2 API 端点

| 端点 | 说明 |
|------|------|
| `POST /api/v1/course/chat` | 课程对话（流式响应） |
| `GET /api/v1/course/messages` | 获取会话历史消息 |
| `GET /api/v1/course/conversations` | 获取会话列表 |

### 12.3 使用说明

**请求示例**：

```bash
# 流式对话（SSE）
curl -X POST "https://aiedu.ireborn.com.cn/api/v1/course/chat" \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"course_id": 1, "query": "什么是玻尿酸？"}'
```

**响应事件**：
- `conversation_started`: 会话开始，返回 conversation_id
- `message_chunk`: 文本块（逐字返回，打字机效果）
- `message_end`: 消息结束
- `error`: 错误信息

## 十四、SaaS 超级管理后台

> 2026-01-18 新增

### 14.1 概述

SaaS 超级管理后台用于统一管理所有租户的配置，替代原来分散在各 `.env` 文件中的配置方式。

**核心功能**：
- 租户管理：创建、编辑、启用/禁用租户
- 配置管理：统一管理各租户的 AI Key、数据库、Redis 等配置
- 提示词管理：查看和编辑 AI 提示词，支持版本控制
- 功能开关：按租户控制功能模块的启用/禁用

### 14.2 部署信息

| 项目 | 值 |
|------|-----|
| 域名 | admin.ireborn.com.cn |
| 前端容器 | kaopeilian-admin-frontend |
| 前端端口 | 3030 |
| 后端容器 | kaopeilian-admin-backend |
| 后端端口 | 8030 |
| 管理数据库 | kaopeilian_admin (prod-mysql:3309) |

### 14.3 数据库表结构

| 表名 | 说明 |
|------|------|
| admin_users | 平台管理员账户 |
| tenants | 租户基本信息 |
| tenant_configs | 租户配置（Key-Value） |
| ai_prompts | AI 提示词模板 |
| ai_prompt_versions | 提示词版本历史 |
| tenant_prompts | 租户自定义提示词 |
| feature_switches | 功能开关 |
| config_templates | 配置模板（元数据） |
| operation_logs | 操作审计日志 |

### 14.4 API 端点

| 端点 | 说明 |
|------|------|
| `POST /api/v1/admin/auth/login` | 管理员登录 |
| `GET /api/v1/admin/tenants` | 获取租户列表 |
| `POST /api/v1/admin/tenants` | 创建租户 |
| `PUT /api/v1/admin/tenants/{id}` | 更新租户 |
| `GET /api/v1/admin/configs/tenants/{id}` | 获取租户配置 |
| `PUT /api/v1/admin/configs/tenants/{id}/batch` | 批量更新配置 |
| `GET /api/v1/admin/prompts` | 获取提示词列表 |
| `PUT /api/v1/admin/prompts/{id}` | 更新提示词 |
| `GET /api/v1/admin/features/tenants/{id}` | 获取租户功能开关 |

### 14.5 默认账户

| 用户名 | 密码 | 角色 |
|--------|------|------|
| superadmin | Superadmin123! | 超级管理员 |

### 14.6 启动命令

```bash
# 启动管理后台
cd /root/aiedu && docker compose -f docker-compose.admin.yml up -d

# 查看日志
docker logs -f kaopeilian-admin-backend
docker logs -f kaopeilian-admin-frontend
```

### 14.7 相关文件

| 文件 | 说明 |
|------|------|
| `/root/aiedu/docker-compose.admin.yml` | Docker Compose 配置 |
| `/root/aiedu/nginx/conf.d/admin.conf` | Nginx 反向代理配置 |
| `/root/aiedu/kaopeilian-admin-frontend/` | 前端代码目录 |
| `/root/aiedu/kaopeilian-backend/app/api/v1/admin_portal/` | 后端 API 目录 |
| `/root/aiedu/kaopeilian-backend/app/core/tenant_config.py` | 租户配置加载器 |
| `/root/aiedu/kaopeilian-backend/migrations/admin_platform_schema.sql` | 数据库架构 |

### 14.8 配置优先级

租户配置加载优先级（从高到低）：
1. 数据库 `tenant_configs` 表
2. 环境变量 `.env` 文件（向后兼容）
3. 代码默认值
