# OPS7 运维交接 Runbook **文档状态**:草案。用于 R7 前运维交接和上线前检查;不代表已执行回滚、恢复或生产配置变更。 ## 1. 原则 - 所有生产或试运行配置变更必须先确认窗口、负责人和回滚路径。 - 不得记录密码、不得记录 token、不得打印 secret、不得提交真实票据或导出文件。 - 备份恢复、Caddy/systemd 调整、数据库写操作都必须单独确认,不在本 Runbook 中直接执行。 - 企业微信只承担入口、免登/绑定、个人应用消息和 deeplink;正式审批仍以 OA 审批历史和审计日志为准。 ## 2. 发布前检查 ```bash git status --short python3 /home/shunli/.codex/skills/plan/scripts/validate_issues_csv.py issues/.csv node scripts/qa/check-ui-design-rules.mjs --strict cd client && npm run typecheck && npm run build cd server && npm run prisma:validate ``` 公网检查: ```bash curl -fsS https://oa.hyinda.com/ready PUBLIC_BASE_URL=https://oa.hyinda.com node scripts/qa/check-public-bundle-copy.mjs LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-live-smoke-readiness.sh ``` 若缺少 live smoke 凭据或真实 OCR 样票,脚本应记录 `SKIP`,不得把 `SKIP` 写成真实业务通过。 ## 3. 部署 标准部署命令: ```bash DEPLOY_SERVER= \ REMOTE_DIR= \ COMPOSE_PROJECT_NAME= \ POSTGRES_DATA_DIR= \ STORAGE_HOST_DIR= \ DEPLOY_DATA_MODE=existing \ bash deploy/trialrun/deploy.sh ``` 默认不覆盖远端 `.env`。只有确认本地 `deploy/trialrun/.env` 可直接上服务器时,才允许在单独确认后使用: ```bash SYNC_ENV=1 \ POSTGRES_DATA_DIR= \ STORAGE_HOST_DIR= \ DEPLOY_DATA_MODE=existing \ bash deploy/trialrun/deploy.sh ``` 部署完成后必须记录: - 本地提交 hash。 - 公网 `/ready` 结果。 - public bundle 扫描结果。 - live readiness 报告目录。 - 如执行视觉矩阵,记录 `output/playwright//` 和 `artifacts/qa-flow//`。 ## 4. 回滚 回滚前先判断问题级别: - 阻断:主链路无法提交、审批、查看状态或权限泄露。 - 严重:影响多人使用或财务/审批可信度,但存在临时绕行。 - 一般:不阻断主链路的文案、视觉或效率问题。 回滚需要人工确认: 1. 确认回滚联系人和执行窗口。 2. 确认目标版本或上一个部署包。 3. 确认数据库是否需要回滚。多数前端/脚本问题不应回滚数据库。 4. 执行回滚后重新检查 `/ready`、public bundle、live readiness。 不得在未确认时执行: - 删除数据库。 - 手工修改生产表结构。 - 覆盖生产 `.env`。 - 清理真实票据、附件或审计记录。 ## 5. 备份与恢复 上线或 R7 前至少确认备份策略: - 数据库备份文件位置、时间、负责人。 - 附件或对象存储备份位置、时间、负责人。 - 恢复演练负责人和预估耗时。 - 恢复后检查命令:`/ready`、登录、报销详情、附件下载、财务台账。 恢复演练只在独立窗口执行。演练记录只写备份文件名、恢复环境、恢复耗时和检查结果,不记录真实文件内容。 QAOPS8 备份策略基线(只定义策略,不执行备份命令): | 对象 | 触发频率 | 保留口径 | 验证方式 | 仓库记录 | | --- | --- | --- | --- | --- | | PostgreSQL 数据库 | 每次受控部署或 R7E 窗口前;R7E 期间每日收口后 | 最近 7 天每日备份 + 每次部署前基线 | 非生产环境 `pg_restore --list` 或抽样恢复演练 | 只记录备份文件名、时间、负责人和校验摘要 | | 上传附件 / 对象存储 | 与数据库备份同窗口执行 | 与对应数据库备份保持同一批次 | 抽样校验文件数量、大小和关键附件下载 | 不提交真实附件,只记录路径占位和校验摘要 | | 运行配置 | 每次 `.env`、Caddy、Compose、systemd 或环境变量变更前后 | 最近 3 个可回滚版本 | 校验配置 hash、权限和敏感字段不外泄 | 不记录 secret 明文,只记录版本和外部安全存放位置 | | 部署包 / commit | 每次部署 | 当前版本 + 上一可用版本 + 本轮试运行基线 | 部署后 `/ready`、public bundle、live readiness | 记录 commit、部署时间和验证摘要 | QAOPS8 恢复演练方案(执行前必须再次确认窗口): 1. 确认演练窗口、负责人、回滚联系人、影响范围和停止条件。 2. 冻结演练期间的写入或改用隔离环境;生产恢复演练必须先备份当前状态。 3. 在非生产或隔离环境恢复数据库备份,确认 schema、迁移状态和关键表可读。 4. 恢复附件或对象存储备份,抽样检查报销详情、附件下载和财务台账。 5. 使用目标 commit 或部署包启动应用,执行 `/ready`、public bundle、登录、报销详情、附件下载和财务台账检查。 6. 记录 RTO/RPO 实测值、失败点、修正动作和是否允许进入 R7E 或上线窗口。 资金类数据恢复后的开放条件(2026-10-05 起备份策略为部署前手动轻量快照,恢复点只到最近一次快照): 1. 恢复旧快照或旧备份后,先暂停报销付款和公司借款还款的制单、付款登记及新还款申请,不对外宣布可用。 2. 对照银行流水核实快照时间点之后发生的付款与还款事实,在系统内按正常流程补齐登记,不直接改库。 3. 逐个出借人核对借款本金余额与在途额度占用(未结清的还款申请),确认没有因恢复而重新变成“可申请”的已还本金后,才开放还款与付款。 4. 未完成以上核对前,任何还款申请一律视为可能重复付款,不得复核或制单。 R7E 前演练口径:RTO/RPO 先作为演练实测值记录,不承诺正式 SLA;若无法在确认窗口内完成恢复验证,R7E Go/No-Go 必须判定为 Pause 或 No-Go。 QAOPS9 恢复演练 dry-run checklist(2026-05-16,先设计不执行生产恢复): 1. 演练环境:优先非生产或隔离临时库;生产只允许做备份清单和步骤复盘,不执行恢复、服务切换或写操作。 2. 前置确认:窗口、负责人、回滚联系人、停止条件、目标 commit、数据库备份名、附件备份名和验证账号范围均需登记;缺任一项判定 `HOLD`。 3. 数据恢复 dry-run:在隔离环境执行 `pg_restore --list` 或抽样恢复;记录 schema 可读、migration 状态和关键表抽样结果,不记录真实数据内容。 4. 附件恢复 dry-run:只抽样验证数量、大小、路径可读性和报销详情下载链路;不得提交真实附件内容。 5. 应用验证:使用目标 commit 或部署包启动隔离应用,执行 `/ready`、登录、报销详情、附件下载、财务台账只读检查和核心业务 smoke。 6. RTO/RPO 记录:只记录开始/结束时间、恢复耗时、备份时间点、失败点和修正动作;未实测不得写承诺值。 7. Go/Pause/No-Go:缺备份、缺负责人、缺隔离环境、恢复失败、附件不可读或验证账号不可用均为 Pause/No-Go;不得用重试次数替代通过证据。 8. 禁止项:不得生产恢复、不得 `migrate reset`、不得重置生产数据库、不得覆盖远端 `.env`、不得打印 secret 或远端 env。 ## 6. 账号交接 R7 前账号交接只记录角色和交付状态: | 账号/角色 | 检查项 | | --- | --- | | 员工 | active、employee、直属主管正确、可登录 | | 审批人 | active、正式审批角色、不是 admin-only 代批 | | 财务 `wangzhiling` | active、employee + finance、不授予管理员 | | 管理员 `wangshunli` | 系统管理、回滚联系人、问题登记负责人 | 一次性密码只能通过仓库外安全渠道交付,不写入 Issue、文档、截图或聊天摘要。 ## 7. 企业微信通知检查 执行前只读确认: ```bash curl -fsS https://oa.hyinda.com/api/auth/wecom/config ``` 检查点: - `status=ready`。 - 工作台入口指向 OA 移动入口。 - 个人应用消息通道启用。 - 回调和可信域名与公网域名一致。 - 配置接口不返回 secret。 人工检查点: - 企业微信工作台能看到海音达工作台。 - 已绑定用户从手机企业微信进入后不反复要求登录。 - 收到审批消息后能 deeplink 回 OA 移动审批或详情。 ## 8. 问题登记模板 每个问题至少记录: - 编号: - 等级:阻断 / 严重 / 一般 / 体验建议 - 角色与账号: - 设备与入口: - URL 或页面: - 操作步骤: - 期望结果: - 实际结果: - 证据位置: - 负责人: - 当日处理结论:修复 / 降级 / 回滚 / 后续 Issue ## 9. OPS8 R7E 前最小运维准备 当前公网部署追踪口径: - 本次 OPS8 起始基线:`0260bc7 R7EP/OPS8/QAF8/UX8/P2T 调整后续计划`。 - 最近已确认部署基线:2026-05-14 R7E 按最新代码部署包含 `4b14c92 DG9 统一全站 UI 布局样板迁移`;上一可用基线为 MIF7TD 的 `cf2bba0`。 - 本次部署说明:首次部署因远端缺少既有加性迁移 `20260513214500_biz8_purchase_project_link` 停止;创建 DB 和附件备份后执行 `prisma migrate deploy`,复跑部署脚本通过,远端 migration status up to date。 - `deploy/trialrun/deploy.sh` 默认 `SYNC_ENV=0`,不得覆盖远端 `.env`;需要同步 `.env` 时必须另行确认。 - R7E 前公网只读检查命令固定为:`curl -fsS https://oa.hyinda.com/ready`、`PUBLIC_BASE_URL=https://oa.hyinda.com node scripts/qa/check-public-bundle-copy.mjs`、带凭据 `scripts/qa/run-live-smoke-readiness.sh`。 R7E 前备份和回滚占位: | 项目 | 当前记录方式 | | --- | --- | | 数据库备份 | `hyb-oa-db-20260514_011940.dump`,远端 `deploy/trialrun/backups/`;本文不记录真实数据内容 | | 附件备份 | `hyb-oa-storage-20260514_011940.tar.gz`,远端 `deploy/trialrun/backups/`;不得提交真实附件 | | 回滚目标 commit | 当前 commit 为 `4b14c92`;上一可用 commit 为 `cf2bba0`;前端/脚本问题优先回滚应用版本,不默认回滚数据库 | | 回滚联系人 | `wangshunli`;真实联系方式放在仓库外企业微信或电话通讯录 | | 恢复演练窗口 | 由 `QAOPS8-16` 确认窗口、负责人、触发条件和停止条件;未确认前不得执行生产回滚或恢复演练 | live readiness 归档规则: - 报告统一放在 `artifacts/qa-flow/live-smoke-readiness-/`。 - 引用时至少记录 `summary.json`、`public-bundle-copy.txt`、`live-smoke.txt`、`live-ocr.txt`、`pending-ocr.txt`。 - `live-smoke.txt` 和 `live-ocr.txt` 不含 `SKIP` 才能作为真实通过证据;`pending OCR` 缺 `DATABASE_URL` 时可记录为非阻断 `SKIP`,不得写成数据库健康通过。 - R7EP 或上线前结论必须同时说明 `/ready`、public bundle、live smoke、真实 OCR 和移动矩阵状态。 2026-05-13 已按默认部署目标 `deploy@118.89.77.218:/opt/hyb-oa-trialrun` 补跑 OPS8-3 远端运行状态只读检查,证据目录 `artifacts/qa-flow/ops8-remote-readonly-20260513-152024/`:`/ready` ok,Caddy active,Docker Compose 中 db/server Up,Prisma migration status up to date。该检查未打印远端 env,未重启服务,未执行数据库写操作或 `migrate reset`。 后续每次 R7E 或上线前复跑 OPS8-3 时,仍只允许 `ps`、`status`、`config`、`docker compose ps`、`prisma migrate status` 等不改变状态的命令;不得打印远端 env,不得执行 migrate reset 或数据库写操作。