R93 记录公网部署复测与 OCR 运行手册

这个提交包含在:
2026-05-06 00:05:29 +08:00
父节点 c920e199d0
当前提交 79799018ab
共修改 14 个文件,包含 19114 行新增和 1 行删除
+6
查看文件
@@ -20,6 +20,7 @@
- [ ] 若要导数据,仅准备最小主数据:部门、员工、角色、在用资产、活跃项目、合同元数据
- [ ] 不导入历史审批单、通知历史、审计日志、聊天记录和涉密正文附件
- [ ] 已确认远端部署目录 `/opt/hyb-oa-trialrun` 不是 git 工作树,发布优先走 `bash deploy/trialrun/deploy.sh`
- [ ] 已确认 OA 前端静态资源由 server 容器内 `/app/client/dist` 提供,Caddy 只反代到 `127.0.0.1:3000`
## A. 发布前(Pre-flight)
- [ ] 确认当前版本已打 tag:`git tag -a trialrun-YYYYMMDD-NN -m "trialrun release"`
@@ -46,6 +47,8 @@
- [ ] external deps smoke:
- [ ] `docker-compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/.env exec -T server node src/scripts/smoke-external-deps.js`
- [ ] 若 external deps smoke 通过,已确认通过前提不是“企微关闭 + OCR mock”误通过
- [ ] 若启用腾讯 OCR,已脱敏核查 `OCR_PROVIDER=tencent`、`TENCENT_SECRET_ID` 长度、`TENCENT_SECRET_KEY` 长度和 `TENCENT_OCR_REGION`
- [ ] 若本次包含前端体验修复,已在容器内确认 `/app/client/dist` 含关键 test id 或公网 asset hash 已更新
- [ ] 登录验证已由 live smoke 与 release gate 覆盖;仅首次接入或第三方后台配置变更时补做人工确认
## C. 发布后(Post-check)
@@ -56,6 +59,8 @@
- [ ] `docker logs --tail=200 hyb-oa-trialrun-server`
- [ ] 已确认 smoke 账号为独立账号(`smoke-admin` / `smoke-employee`),且不参与真实业务
- [ ] 已确认 live smoke 仅检查 `/ready`、登录、Portal、项目、公告、个人设置和企微配置状态
- [ ] 若涉及票据/OCR,已执行真实 OCR 辅助复核或记录跳过原因:`PLAYWRIGHT_MANUAL=1 PLAYWRIGHT_OCR_LIVE=1 ... npx playwright test tests/e2e/manual/live-invoice-ocr.spec.ts`
- [ ] 若涉及移动端体验,已用 Playwright 390px 视口检查 `/invoice-pool`、`/reimbursements`、`/mobile/capture`,确认无桌面表格、无出屏按钮,上传 input 的 `multiple` 与预期一致
## D. 回滚(Rollback)
> 原则:如果涉及迁移,最快回滚通常是 “恢复备份 + 回到上个 tag”。
@@ -67,6 +72,7 @@
- [ ] 重启并探活:
- [ ] `docker-compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/.env up -d --build server`
- [ ] `curl -fsS http://127.0.0.1:3000/ready`
- [ ] 若仅为 OCR 应急降级,已把远端 `.env` 的 `OCR_PROVIDER` 临时切回 `mock`,重启 server,并在 Issue/发布记录中写明原因、影响范围和恢复时间
+77 -1
查看文件
@@ -22,7 +22,8 @@
- 部署目录:`/opt/hyb-oa-trialrun`
- 远端目录当前不是 git 工作树;发布应优先从本地执行 `bash deploy/trialrun/deploy.sh`,由脚本 `rsync` 到服务器
- 远端容器编排当前实际为 `docker-compose 1.29.2`;本 runbook 命令以 `docker-compose` 为准
- 当前公网 `.env` 已确认:`APP_ORIGIN=https://oa.hyinda.com`、`COOKIE_SECURE=true`、`PUBLIC_SECURITY_HARDENING_ENABLED=true`,但 `WECOM_*` 仍为 `false`,`OCR_PROVIDER=mock`
- 当前公网 `.env` 已确认:`APP_ORIGIN=https://oa.hyinda.com`、`COOKIE_SECURE=true`、`PUBLIC_SECURITY_HARDENING_ENABLED=true`
- 企业微信与 OCR 已进入公网试运行配置。核查时只检查开关、长度和 smoke 结果,不在日志、Issue 或文档中输出 secret 明文。
## 0. 前置条件
- Docker + Docker Compose(v1/v2 任一可用)
@@ -104,10 +105,54 @@ docker-compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/
- 推荐直接执行 `bash scripts/qa/run-release-gate.sh all`,让 static / local smoke / full-local / deploy / live smoke 形成单一放行链。
- 若再出现“数据库开了但功能被环境硬关”的情况,部署会直接失败,不再等到手工点页面才发现。
- 2026-05-04 公网只读巡检显示:`smoke-external-deps.js` 可以通过,但前提是 `WECOM_*` 未启用且 `OCR_PROVIDER=mock`;`smoke-trialrun-runtime.js` 当前会因 `announcements_v1` 为 `force_off` 失败。
- 2026-05-05 公网复核显示:`OCR_PROVIDER=tencent` 可用,真实发票上传后进入 `available`,provider 为 `tencent`;后续发布不能再把 OCR 回退到 mock 而不记录原因。
浏览器访问:
- `http://127.0.0.1:3000`(单域托管前端)
### 1.4.1 腾讯 OCR 试运行核查
远端 `.env` 是 OCR 配置事实源,禁止提交或复制密钥明文。只做以下脱敏检查:
```bash
cd /opt/hyb-oa-trialrun
set -a
source deploy/trialrun/.env
set +a
printf 'OCR_PROVIDER=%s\n' "$OCR_PROVIDER"
printf 'TENCENT_SECRET_ID length=%s\n' "${#TENCENT_SECRET_ID}"
printf 'TENCENT_SECRET_KEY length=%s\n' "${#TENCENT_SECRET_KEY}"
printf 'TENCENT_OCR_REGION=%s\n' "$TENCENT_OCR_REGION"
```
期望:
- `OCR_PROVIDER=tencent`
- `TENCENT_SECRET_ID` 和 `TENCENT_SECRET_KEY` 长度大于 0
- `TENCENT_OCR_REGION` 与腾讯 OCR 开通地域一致,例如 `ap-beijing`
发布后 smoke:
```bash
docker-compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/.env exec -T server node src/scripts/smoke-external-deps.js
docker-compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/.env exec -T server node src/scripts/smoke-trialrun-runtime.js
```
真实 OCR 辅助复核(本地执行,不提交发票文件):
```bash
cd client
PLAYWRIGHT_MANUAL=1 \
PLAYWRIGHT_OCR_LIVE=1 \
PLAYWRIGHT_OCR_LIVE_FILE=/path/to/invoice.pdf \
E2E_BASE_URL=https://oa.hyinda.com \
npx playwright test tests/e2e/manual/live-invoice-ocr.spec.ts --workers=1 --reporter=list --timeout=360000
```
回滚到 mock 只允许作为应急降级:
1. 在远端 `.env` 将 `OCR_PROVIDER=tencent` 改为 `OCR_PROVIDER=mock`。
2. 执行 `docker-compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/.env up -d server`。
3. 在 Issue/发布记录中写明降级原因、预计恢复时间和影响范围。
## 1.5 备份与恢复演练(强烈建议至少做一次)
> 备份建议做到“DB + 文件存储(票据上传目录)”双份齐全。
@@ -193,6 +238,37 @@ docker-compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/
docker-compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/.env run --rm init
```
### 2.2 前端部署一致性排障
当前 `oa.hyinda.com` 由 Caddy 反代到 `127.0.0.1:3000`,前端静态资源由 server 容器内的 `/app/client/dist` 提供,不是 `/etc/caddy/Caddyfile` 里的独立静态目录。
如果出现“本地源码已有功能,但公网仍显示旧 UI”,先按以下顺序核查:
```bash
# 1) 确认 Caddy 仍是反代到 3000
sudo sed -n '/oa.hyinda.com/,/}/p' /etc/caddy/Caddyfile
# 2) 比对公网首页引用的 asset hash
curl -fsS https://oa.hyinda.com/ | grep -o '/assets/[^" ]*' | head
# 3) 在容器内查构建产物是否包含关键 test id
docker exec hyb-oa-trialrun-server sh -lc \
'for pat in invoice-pool-mobile-list reimbursements-mobile-list mobile-capture-file multiple:!0; do printf "%s " "$pat"; grep -Rao "$pat" /app/client/dist/assets /app/client/dist/index.html 2>/dev/null | wc -l; done'
```
若远端源码已更新但容器内 `/app/client/dist` 仍旧,重建并重启:
```bash
cd /opt/hyb-oa-trialrun
docker-compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/.env up -d --build server
docker-compose -f deploy/trialrun/docker-compose.yml --env-file deploy/trialrun/.env run --rm -T init </dev/null
curl -fsS http://127.0.0.1:3000/ready
```
重建后必须补做:
- `smoke-external-deps.js`
- `smoke-trialrun-runtime.js`
- 公网页面视觉检查:至少覆盖 `/invoice-pool`、`/reimbursements`、`/mobile/capture` 的 390px 视口
发布/回滚 Checklist:
- `deploy/trialrun/checklist.md`