# 上线部署 SOP（Standard Operating Procedure）

> 本文件是每次部署的唯一依据，执行前必须完整阅读并遵守。

---

## 零、核心原则

1. **不影响现有功能** — 改动必须向后兼容，已有的 API、前端行为一个都不能破
2. **增量提交** — 每次只改一个关注点，小步 commit，便于定位和回滚
3. **快速回滚** — 任何时候出问题，3 分钟内回滚到上一个正常版本
4. **部署前自检，部署后观察** — 绝不跳过任何一步

---

## 一、部署前 Checklist

在 `./tools/java-deploy.sh deploy` 之前，逐项确认：

- [ ] 代码已 push 到 git 仓库
- [ ] 编译通过（本地或 CI）
- [ ] 确认没有新增 `AccessDeniedException` 或 `No thread-bound request` 等已知异常
- [ ] 对关键接口心中有数：`/health`、`/api/v1/chat/stream`、`/api/v1/drug/search`
- [ ] 已知回滚路径（见第五节）
- [ ] 如果是数据库变更，已确认向前兼容

---

## 二、标准上线步骤

```bash
# Step 1: 确认当前状态
./tools/java-deploy.sh status

# Step 2: 一键部署（自动拉代码、编译、备份、重启）
./tools/java-deploy.sh deploy

# Step 3: 确认服务正常
curl -s http://localhost:9000/health | python3 -m json.tool

# Step 4: 检查启动日志无异常
./tools/java-deploy.sh logs 50

# Step 5: 等待 2-3 分钟，观察日志无新的 ERROR
sleep 180
tail -50 /var/log/pharmacopoeia/backend.log | grep -i "error\|exception\|access denied"
```

## 三、部署后验证

| 检查项 | 命令 | 预期 |
|--------|------|------|
| 健康检查 | `curl -s http://localhost:9000/health` | 200 OK |
| 药品库搜索 | `curl -s 'http://localhost:9000/api/v1/drug/search?keyword=布洛芬'` | 返回数据 |
| 对话流式 | 用浏览器访问首页，发送一条问题 | SSE 正常走完，无网络异常 |
| 日志无异常 | `tail -100 /var/log/pharmacopoeia/backend.log \| grep -i "error\|exception"` | 无新增报错 |

---

## 四、部署脚本说明

所有操作统一用 `./tools/java-deploy.sh`，不手动操作 jar 文件或进程。

| 命令 | 用途 |
|------|------|
| `./tools/java-deploy.sh status` | 查看运行状态 |
| `./tools/java-deploy.sh deploy` | 一键上线（pull → build → backup → restart） |
| `./tools/java-deploy.sh rollback` | 回滚到上一个备份 |
| `./tools/java-deploy.sh rollback <path>` | 回滚到指定备份文件 |
| `./tools/java-deploy.sh restart` | 重启（不重新编译） |
| `./tools/java-deploy.sh logs` | 最近 100 行日志 |
| `./tools/java-deploy.sh logf` | 实时日志跟踪 |

`deploy` 命令会自动：
- 拉取 git 最新代码
- 编译打包
- **备份当前 JAR** 到 `backend-java/backups/` 目录（按时间戳命名）
- 保留最近 5 个备份，自动清理更早的

---

## 五、紧急回滚

```bash
# 方式 1: 自动回滚（使用最新备份）
./tools/java-deploy.sh rollback

# 方式 2: 回滚到指定备份
./tools/java-deploy.sh rollback /opt/pharmacopoeia-ai/backend-java/backups/pharmacopoeia-ai-20260724-143000.jar

# 方式 3: 回退 git commit 后重新部署
cd /opt/pharmacopoeia-ai
git revert <坏commit> --no-edit
./tools/java-deploy.sh deploy
```

**回滚决策：**
- 用户反馈功能异常 → 立即回滚
- 日志 5 分钟内出现 5+ ERROR → 立即回滚
- 仅 UI 展示问题 → 评估是否需要回滚，优先热修复

---

## 六、数据库变更（额外谨慎）

任何表结构或索引变更，必须：

- [ ] 先在 dev 环境验证
- [ ] 使用 `IF NOT EXISTS`（向前兼容）
- [ ] 不删除列、不重命名列（除非确认无依赖）
- [ ] 变更完成后验证关键查询正常

---

## 七、禁止事项

- ❌ 跳过部署前 Checklist
- ❌ 手动 `kill` 进程或直接替换 jar（用脚本）
- ❌ 生产环境用 `-SNAPSHOT` 版本
- ❌ 不做备份就部署
- ❌ 部署后不观察日志就离开
