docs: 老项目(jc/auto)完整迁移计划——5 阶段 runbook

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
浅念
2026-10-23 10:15:08 +08:00
parent cd3b58a83c
commit f1f08fb55c
@@ -0,0 +1,254 @@
# 老项目(jc/建材 + auto/汽车)迁移计划
- 日期:2026-10-23
- 前置:all-kefu 生产已上线(chat.ai.hnxinyouhe.com,8019 端口,路径模式)
- 迁移工具:scripts/import_legacy.py(已有,幂等、只读源库、四元组对账)
---
## 0. 现状盘点
### 老项目
| | jc/建材 | auto/汽车 |
|---|---|---|
| 容器 | hs-ai-kefu (8017) | cc-ai-kefu (8016) + redis |
| 域名 | chat2.agent.hnxinyouhe.com | chat.agent.hnxinyhe.com |
| 反代指向 | 127.0.0.1:8017 | 127.0.0.1:8016 |
| 数据库 | hesupipe_ai_kefu.db (308KB) | cc_ai_kefu.db (5.9MB) |
| 推送 | **disabled** (PUSH_ENABLED=false) | **enabled** (94 success / 2 failed / 1 skipped) |
| 推送前缀 | ai-kefu-jc | ai-kefu |
| AI | glm-4-flash | glm-4-flash |
| SMTP | 飞书邮箱(已迁移到新平台) | 同 |
### 老数据量
| 表 | jc | auto | 合计 |
|---|---|---|---|
| conversations | 135 | 4,427 | 4,562 |
| messages | 299 | 7,896 | 8,195 |
| customer_profiles | 135 | 4,427 | 4,562 |
| evaluations | 22 | 491 | 513 |
| lead_push_logs | 0 | 97 | 97 |
### 新平台现状(已就绪)
- 租户 auto / jiancai 已 bootstrap(出厂档案配置)
- 推送前缀已对齐:auto=`ai-kefu`,jiancai=`ai-kefu-jc`(与老项目一致——external_key 连续性)
- SMTP 飞书邮箱已配(平台默认)
- 通知邮箱:默认回退 brand.email
- 提示词差异已审计:新 = 老 + 增强(DEFLECTION_POOL 配置化 / CC 区号补全 / 防自拼号码 / 翻译规则)
### 需要补配的(老项目有 → 新平台缺)
| 项 | 说明 |
|---|---|
| auto 租户 push.api_key | 老项目有值 `650e0af0...`,新平台 auto 未配 |
| auto 租户 push.enabled | 需设 true(老项目是 true) |
| jc 租户 push.enabled | 保持 false(老项目就是 false) |
| push.api_url | 老项目 `https://uniservice.server.hnxinyouhe.com/open/v1/inquiry/push`——新平台 push.url 需确认 |
---
## 1. 阶段一:配置补齐(~5 分钟,不停老项目)
### 1a. 补 auto 租户推送配置
```
后台 → 配置中心 → auto → 凭据与通知 → 推送组:
url: https://uniservice.server.hnxinyouhe.com/open/v1/inquiry/push
api_key: (从老项目 env 拷贝)
prefix: ai-kefu(已配,不动)
enabled: true
```
或走 API(curl PUT config/push)。
### 1b. 确认 jc 推送保持 disabled
jc 老项目 PUSH_ENABLED=false——新平台 push.enabled 也应 false(或留空 = 默认 false)。
### 1c. 确认 AI 配置
两个租户走平台默认(ZHIPU_API_KEY in .env = glm-4-flash)——与老项目一致,无需改。
---
## 2. 阶段二:数据导出 + 导入(~5 分钟,不停老项目)
### 2a. 老库导出(VACUUM INTO 不停机快照)
```bash
# 在生产服务器执行
SITE=/opt/1panel/www/sites/chat.ai.hnxinyouhe.com/index
# jc
docker exec hs-ai-kefu python -c "
import sqlite3; c=sqlite3.connect('/app/data/hesupipe_ai_kefu.db')
c.execute(\"VACUUM INTO '/app/data/export-jc.db'\"); c.close()"
docker cp hs-ai-kefu:/app/data/export-jc.db $SITE/data/legacy-jc.db
# auto
docker exec cc-ai-kefu python -c "
import sqlite3; c=sqlite3.connect('/app/data/cc_ai_kefu.db')
c.execute(\"VACUUM INTO '/app/data/export-auto.db'\"); c.close()"
docker cp cc-ai-kefu:/app/data/export-auto.db $SITE/data/legacy-auto.db
```
### 2b. 导入新平台
```bash
cd $SITE
# jc
docker compose run --rm app python scripts/import_legacy.py \
--source /app/data/legacy-jc.db --tenant jiancai
# auto
docker compose run --rm app python scripts/import_legacy.py \
--source /app/data/legacy-auto.db --tenant auto
```
### 2c. 对账(脚本自动输出,人工核对)
每表四元组:源 = 导入 + 跳过已存在 = 目标合计
- 源 ≠ 目标 → 非零退出 → 人工排查后才继续
- 最近 10 条会话抽查 id/session_id/status 逐条对照
- MAX(conversation_id) 对照(ID 原样性)
- auto 的 97 条 push_logs:pending(如有)→ failed 转换
- 列差异标注确认无意外
### 2d. 后台验证数据
```
后台 → 会话与线索 → 切到 jiancai 租户 → 会话数 ≈ 135
后台 → 会话与线索 → 切到 auto 租户 → 会话数 ≈ 4,427
后台 → 统计分析 → 两租户统计图有数据
```
---
## 3. 阶段三:双模式域名切换(逐域名,先切一个)
**策略**:老域名反代从老端口(8016/8017)→ 新平台 8019。这样:
- 老嵌入代码(指向 chat./chat2. 域名)继续工作——Host 模式解析到新平台租户
- 新嵌入代码(指向 chat.ai.hnxinyouhe.com/t/xxx/)同时可用——路径模式
- 两模式共存,客户零感知
### 3a. 租户绑定域名(新平台侧)
```
后台 → 租户管理 → jiancai → 详情 → 站点 → main → 绑定域名 → chat2.agent.hnxinyouhe.com
后台 → 租户管理 → auto → 详情 → 站点 → main → 绑定域名 → chat.agent.hnxinyouhe.com
```
### 3b. 1Panel 切反代(先切 jiancai/chat2,观察半天再切 auto/chat)
```
1Panel → 网站 → chat2.agent.hnxinyouhe.com → 设置 → 反向代理
修改 proxy_pass 为 http://127.0.0.1:8019
→ 保存 → nginx -t 确认 → 自动 reload
```
**注意**:该站点的 `proxy/*.conf` 里可能有多个 location(root/ws)——都要改为 8019,或者删掉旧的 proxy 目录让 1Panel 重新生成。
### 3c. 立即线上验证
```bash
# 老域名 → 新平台(Host 模式)
curl -H "Host: chat2.agent.hnxinyouhe.com" http://127.0.0.1:8019/health
curl -H "Host: chat2.agent.hnxinyouhe.com" http://127.0.0.1:8019/ # 聊天页
curl -H "Host: chat2.agent.hnxinyouhe.com" http://127.0.0.1:8019/static/widget.js # 挂件
# 公共域名 → 同一租户(路径模式)
curl http://127.0.0.1:8019/t/jiancai/api/public/brand # 品牌一致
curl http://127.0.0.1:8019/t/jiancai/static/widget.js # 挂件一致
```
线上浏览器验证(真实域名):
- [ ] `https://chat2.agent.hnxinyouhe.com/` 聊天页加载、品牌正确
- [ ] `https://chat2.agent.hnxinyouhe.com/static/widget-test.html` 冒烟
- [ ] `https://chat2.agent.hnxinyouhe.com/t/jiancai/api/public/brand` 与 `/api/public/brand` 同 slug
- [ ] WS 握手 + AI 对话(中英各一句)
### 3d. 观察半天后切 auto/chat
同 3b/3c,域名换成 chat.agent.hnxinyouhe.com → 8019。
### 3e. 客户网站嵌入代码更新(可选,建议但非必须)
```
旧:<script src="https://chat.agent.hnxinyouhe.com/static/widget.js" async></script>
新:<script src="https://chat.ai.hnxinyouhe.com/t/auto/static/widget.js" async></script>
```
不更新也不影响——老域名反代已指向新平台,继续工作。更新的好处:
- 走公共域名(一张证书)
- 为将来删老域名做准备
- 嵌入代码里的品牌色/头像等资源 URL 也走公共域
---
## 4. 阶段四:观察一周(日检清单)
- [ ] `/health`:status=ok,无 degraded
- [ ] 后台统计 → 推送健康:auto 成功率正常(对比老平台 94/97 基线)
- [ ] 询盘邮件到达(检查 hesu@hesuu.com 或 brand.email)
- [ ] `breach_rate` 双向偏差(jc 期基线对比)
```bash
docker compose exec app python scripts/breach_rate.py --tenant jiancai
docker compose exec app python scripts/breach_rate.py --tenant auto
```
- [ ] `docker stats all-kefu-app-1`(内存 < 768m)
- [ ] `docker logs all-kefu-app-1 --tail 100`(无异常)
- [ ] 后台会话视图抽查:老域名来的新会话 + 路径域名来的新会话都正常入列表
---
## 5. 阶段五:收口(观察期满)
- [ ] 老容器 `docker stop hs-ai-kefu cc-ai-kefu cc-ai-kefu-redis`(**不 rm**)
- [ ] 老库文件归档:`cp /opt/1panel/www/sites/chat*/index/data/*.db /备份盘/`
- [ ] 1Panel 老站点(chat./chat2.)保留但不再指向流量(反代已改 8019)
- [ ] 客户网站嵌入代码全部切到公共域名后,可删除老域名站点
- [ ] DNS 如不再需要 chat./chat2. 解析,通知域名管理员
---
## 6. 回滚预案(任一阶段)
| 阶段 | 回滚动作 | 耗时 |
|---|---|---|
| 阶段二(数据导入) | 无需回滚——新平台租户库多了数据不影响老项目运行 | 0 |
| 阶段三(反代切换) | 1Panel 该站点 proxy_pass 改回老端口(8016/8017)→ reload | ~30 秒 |
| 阶段四(观察期) | 同上 | ~30 秒 |
| 阶段五(收口后) | docker start 老容器 + 反代切回 | ~1 分钟 |
**注意**:切换后新平台产生的会话回滚后留在新平台库(老平台没有)——属预期,UniService 线索不重复(external_key 保原样)。
---
## 7. 风险清单
| # | 风险 | 等级 | 缓解 |
|---|---|---|---|
| 1 | auto 数据量大导入慢 | 🟢 低 | 4,427 会话 < 6MB,几秒完 |
| 2 | 老项目配置差异遗漏 | 🟡 中 | 本计划 §1 已列差异清单;导入前对比 |
| 3 | 反代配置遗漏(WS/location 多块) | 🟡 中 | 逐块检查 proxy/*.conf;nginx -t 确认 |
| 4 | 客户网站未更新嵌入代码 | 🟢 低 | 老域名反代兼容过渡,不急 |
| 5 | 新平台提示词行为差异 | 🟢 低 | 新 = 老 + 增强,只多不少;有问题配置中心可调 |
| 6 | 推送 external_key 重复 | 🟢 低 | prefix 一致 + conversation_id 原样 = 不重复 |
| 7 | 通知邮箱地址变化 | 🟡 中 | 确认各租户 brand.email 是正确的通知地址 |
---
## 8. 执行排期(预计总耗时 ~30 分钟 + 观察 1 周)
| 步骤 | 耗时 | 何时执行 |
|---|---|---|
| §1 配置补齐 | 5 分钟 | 随时 |
| §2 数据导出+导入+对账 | 10 分钟 | 低峰(凌晨/早上) |
| §3a 租户绑定域名 | 2 分钟 | 导入验证后 |
| §3b 切 chat2(jc)反代 | 5 分钟 | 上午,观察半天 |
| §3d 切 chat(auto)反代 | 5 分钟 | jc 半天无问题后 |
| §4 观察一周 | 7 天 | 每天检查清单 |
| §5 收口 | 10 分钟 | 观察期满 |