文件
hyb-oa/docs/试运行与自动化验证手册.md
T

18 KiB
原始文件 Blame 文件历史

试运行与自动化验证 Runbook

文档状态:当前操作手册,用于本地、公网、企业微信和真实 OCR 试运行验证。

当前状态(2026-07-18):最后有部署和公网复检证据的来源基线仍为 df26922;未做当前公网只读检查时,不据此断言服务器此刻仍运行该提交。07-18-small-team-internal-readiness 只收敛本地候选,完成上限为 LOCAL_CANDIDATE_PASS;它不代表已部署、可公网测试、企业微信真机通过或真实账号/数据验证。旧 7 天试运行只有 Day 1–Day 4 后中断,缺人工业务闭环和 Day 7 Go/No-Go;下一轮必须待当前可信基线部署并复核后,新建 Trellis task,从 Day 1 连续启动。正式能力继续保持 PDF-only OCR,不接真实支付、不接 ERP、不开放图片 OCR、不导入银行流水。

本文用于 hyb-oa 本地、企业微信和公网试运行。默认策略是:能自动化的先自动化,自动化无法覆盖的才请求人工配合。

测试分层、视觉验证、SKIP、状态回填和回归门禁的制度口径,以 docs/测试规约与回归门禁.md 为准;本文只保留本地、公网、企业微信和真实 OCR 的操作步骤。

入口顺序

  1. 读取 .trellis/workflow.md 和当前 Trellis task 的 PRD/设计。
  2. 读取 .trellis/spec/hyb-oa/ 与任务对应的业务事实源。
  3. 读取 AGENTS.md 并检查 git status --short,保护已有改动。
  4. 按任务读取事实源:
    • 页面体验事实:docs/产品设计规则.md;视觉与交互裁决使用 frontend-design
    • 报销发票:docs/报销发票附件规则.md
    • Agent 交付:docs/Agent开发交付实践.md
  5. 旧 issues/*.csv 只在需要历史追溯或外部导出时读取,不作为新任务执行合同。

本地验证

后端基础检查:

cd server && npm run prisma:validate
cd server && node --check src/routes/reimbursements.js
cd server && node --check src/routes/workflow.js

后端回归:

cd server && ./scripts/regression-workflow-actions.sh
cd server && ./scripts/regression-all.sh

若当前本地开发库存在 Prisma migration 漂移,禁止直接重置数据库。需要验证发票查重真实 HTTP 链路时,优先使用隔离临时库:

bash scripts/qa/check-local-migration-drift.sh
bash scripts/qa/run-isolated-regression-dedup.sh

check-local-migration-drift.sh 只读执行 prisma migrate status 并给出风险提示,不会执行 migrate reset。run-isolated-regression-dedup.sh 会创建临时 QA 数据库、执行迁移和种子、启动临时服务、运行 server/scripts/regression-dedup.sh,结束后默认删除临时库。若需要保留现场,可设置 QA_KEEP_DB=1。

前端检查:

cd client && npm run typecheck
cd client && npm run build

Playwright 视觉验证

页面或交互改动优先用 Playwright 验证:

  • PC viewport: 1440x960。
  • mobile viewport: 基础 390x844;涉及移动布局、企业微信或 R6 移动反馈时必须扩展到 320x568、360x740、375x667、390x844、393x873、414x896、430x932。
  • 企业微信 UA 使用 iPhone + wxwork 标识。
  • 截图放在 output/playwright/<trellis-task-id>/。

移动端必须检查:

  • 没有桌面表格。
  • scrollWidth <= viewportWidth + 2。
  • 底部导航高度合理,四个 Tab 中心点 elementFromPoint 命中自身或子元素。
  • 当前选中项不是黑色空心样式。
  • 弹窗不会默认聚焦搜索框导致键盘弹出。
  • 无明显文字截断、遮挡、按钮样式不一致。
  • 首页一级入口使用图标宫格时,图标、标题和容器不重叠,标题不逐字换行。
  • 深层 Push 页隐藏底部 Tab,使用顶部返回;吸底主操作不遮挡内容。
  • 移动验收采用“跨视口自动化 + 代表性真机确认”:自动化证明响应式基线,iPhone 12、iPhone 14、Redmi K60 或同类代表设备确认真实企业微信 WebView 行为。当前 ME6-3 已关闭;未来新增真机门禁若暂停,必须继续记录为 PAUSED,不能用自动化结果替代。

企业微信验证

自动化可模拟企业微信 UA,但真实登录态仍以手机企业微信为准。

需要人工配合的节点:

  • 企业微信后台应用主页、可信域名、回调域名、可见范围配置。
  • 手机企业微信实际点击应用入口。
  • 企业微信授权或绑定确认。

真机公网测试按 docs/trialrun/真机公网测试清单.md 执行。可先生成报告模板:

node scripts/qa/create-real-device-report.mjs

真机验证状态允许使用:

  • PASS:代表性真机和必要人工确认均通过。
  • FAIL:真机复现阻断或严重问题,必须登记设备、账号、URL、步骤和证据位置。
  • BLOCKED:缺少测试账号、企业微信后台配置、样票或网络等前置条件。
  • PAUSED:用户或现场条件暂停验证;自动化通过也不能据此关闭真机门禁或把当前 task 验收标为完成。

WF8 通知渠道验收矩阵

WF8 阶段采用“两渠道验收 + 邮件冻结说明”:站内通知和企业微信个人应用消息是当前正式验收通道,邮件通道按统一审批中心规约冻结,不作为当前硬门禁。任何缺少配置、账号、凭据或真机条件的渠道只能记录 SKIP、BLOCKED 或 PAUSED,不得写成 PASS。

渠道 前置条件 验收步骤 通过口径 不能替代的证据
站内通知 测试用户、审批或业务事件、OA 登录态 触发待办或状态变化;目标用户进入 OA 通知或目标业务页;核对未读、标题、目标类型和目标 ID 通知存在,deeplink 指向具体 OA 目标,权限拦截正确,非目标用户不可见 只跑后端单测不能替代 PC 或移动页面可达性
企业微信个人应用消息 IM_NOTIFIER_ENABLED=true、个人应用消息渠道启用、员工已绑定企业微信 userId、应用可见范围正确、公网域名可访问 触发待办;管理员检查 delivery;审批人在手机企业微信收到消息并点击回 OA delivery 成功且无 invaliduser、unlicenseduser、可见范围错误;手机端能进入 OA 移动审批或业务详情 企业微信 UA 自动化不能替代代表性真机消息接收和点击回流
邮件通道 用户确认邮件为正式通道、SMTP provider 和发件域确定、密钥存放和退信处理方案批准 当前 WF8 不执行;当前或独立 Trellis task 及对应规约记录冻结原因和解锁条件 当前结论为冻结或 SKIP,不参与 Go/No-Go PASS 统计 站内或企业微信成功不能证明邮件通道成功
失败追溯 通知 provider 可模拟失败或测试渠道返回失败 模拟发送失败;检查 notificationDelivery 摘要、错误类型、重试次数和管理员可见性;确认主业务不回滚 失败可追溯、敏感字段不外泄、业务状态保持正确 日志片段不能替代投递记录或管理员查询证据

验收结论必须区分四类环境:

  • 本地自动化:用于证明通知创建、投递记录、失败重试、权限和脱敏基线。
  • 公网匿名:只能证明入口、静态资源和未登录边界,不证明个人消息送达。
  • 公网带凭据:用于证明真实账号、权限、deeplink 和业务目标页面可达。
  • 企业微信真机:用于证明个人应用消息送达、点击回流、绑定状态和 WebView 行为。

公网 live smoke 和真实 OCR 准备按 docs/trialrun/公网LiveSmoke准备清单.md 执行:

node scripts/qa/check-live-smoke-env.mjs
LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-live-smoke-readiness.sh

当前可信度判定

  • 聚合状态为 PASS 时仍必须检查必要子项和 findingCount;必要 live smoke、真实 OCR、权限、来源校验出现 SKIP、PARTIAL、MISSING 或 SHA 不匹配时,不得给出最终 clean PASS。
  • 本地 runner 通过只证明当前代码;必须核对部署来源 commit、/ready observed build SHA 和公网 bundle marker,才能证明公网使用了同一基线。
  • 新连续试运行前必须确认部署 runner 已包含 7 月 P0 修复;旧 Day 1–Day 4 报告不得补证新的正式启用结论。

2026-05 SYSTEM-COMPLETE-GATE 历史完成门禁

系统开发完成收口采用以下最小门禁:

set -a && source ~/.hyb-oa/live-smoke.env && set +a
LIVE_SMOKE_BASE_URL=https://oa.hyinda.com node scripts/qa/check-live-smoke-env.mjs --strict
QA_ISSUE_ID=SCG LIVE_SMOKE_BASE_URL=https://oa.hyinda.com bash scripts/qa/run-live-smoke-readiness.sh
cd client && E2E_BASE_URL=https://oa.hyinda.com npx playwright test tests/e2e/dg7-mobile-information-dedupe.spec.ts tests/e2e/r124-mobile-entry-matrix.spec.ts tests/e2e/r6-wecom-mobile-rendering-hardening.spec.ts --workers=1 --reporter=list

完成门禁只核验系统可正式使用,不扩展功能边界。payment_batch_v1 应保持 force_on,erp_sync 应保持 force_off。图片发票 OCR、真实支付接口、ERP 实时凭证、银行流水导入、复杂 BPM、审批设计器和重预算控制继续冻结。

2026-05 LAUNCH-OPS-V1 历史首周运营检查

正式使用首周每日检查:

  • 公网 /ready、PC 登录、移动/企业微信入口。
  • 报销/PDF OCR、审批、请假、采购、通知、付款批次、AP 导出和审计日志。
  • payment_batch_v1 未意外关闭,erp_sync 未意外开启。
  • 出纳在银行侧完成真实付款后,可将经授权的付款回单作为 OA 留存证据,再执行 OA 已付款标记;误传回单必须填写理由并留痕作废,不物理删除。银行流水不导入 OA,银行侧原始材料仍按受控财务流程交接。
  • 当天问题按时间、角色、页面、步骤、影响等级和处理结论登记。

无法登录、无法审批、无法提交核心单据、付款状态错误、权限越权、/ready 异常或冻结项被误开启时,结论应为 Pause,并另建或更新最小修复 Trellis task;不得用重置数据库或生产恢复临时绕过。

发布候选进入公网或小范围试运行前,先按 docs/trialrun/发布试运行准备清单.md 完成证据整理、权限直连审计、部署预检、live smoke 和试运行分级。

系统应避免让已绑定用户反复登录。若手机企业微信能进入但仍要求登录,优先检查:

  • 回调 code 是否传到后端。
  • 后端是否拿到 UserId。
  • 本地账号是否绑定了企业微信 userId。
  • cookie domain、SameSite、Caddy 反代头是否正确。

OCR 验证

先确认当前 OCR provider:

  • mock 只用于自动化和本地回归。
  • 腾讯 OCR 需要真实环境变量和网络。

发票上传问题排查顺序:

  1. 上传接口是否成功返回 invoice id。
  2. 发票是否进入 pending_ocr。
  3. 单票识别任务是否立即入队,周期任务是否只作为兜底。
  4. OCR job 是否运行。
  5. OCR provider 是否为腾讯而不是 mock。
  6. OCR 是否返回结构化字段。
  7. 查重是否把发票转为不可添加。
  8. 前端事件流或轮询兜底是否触发刷新。
  9. 报销详情是否自动添加到明细。

发布前可执行 pending OCR 扫描,定位卡住的票据:

node scripts/qa/check-pending-ocr.mjs --thresholds=2,5,10

脚本只输出票据 ID、上传时间、尝试次数和最后错误摘要,不读取票据文件内容。缺少 DATABASE_URL 时应输出 SKIP,不视为真实数据库健康检查通过。

BIZ8 批量样票 OCR 回归设计

批量样票回归用于判断真实 OCR provider、异步终态和失败复核路径是否稳定,不替代 PDF-only 当前验收,也不代表图片 OCR 已开放。

推荐分层:

层级 用途 通过口径
mock OCR 验证上传、pending、状态刷新、失败提示和报销绑定流程 本地自动化通过;不得宣称真实 provider 通过
pending OCR 扫描 识别卡住的 pending_ocr 票据 check-pending-ocr.mjs 输出计数和摘要;缺 DATABASE_URL 记录 SKIP
单张真实 OCR 验证 live provider、凭据、网络和字段归一化 授权样票上传后进入可解释终态;重复票据可算可解释终态
批量真实 OCR 验证多样票稳定性、失败率和错误分类 仅使用授权或脱敏样票;失败逐张记录并人工复核

批量真实 OCR 只能在满足以下条件后执行:

  1. 样票已按 报销发票附件规则 完成授权、脱敏和别名登记。
  2. 文件名使用样票别名,不使用真实供应商、客户、员工姓名或业务说明。
  3. PLAYWRIGHT_OCR_LIVE_FILE、PLAYWRIGHT_OCR_LIVE_FILES 或 PLAYWRIGHT_OCR_LIVE_DIR 指向仓库外安全目录。
  4. 批量报告只作为本地辅助复核;未经脱敏的 artifacts/r70/live-ocr-batch-report.md 不得提交。
  5. 如缺少样票、凭据、授权或网络,只能记录 SKIP 和补测条件,不得标记 PASS。

示例命令:

cd client
PLAYWRIGHT_MANUAL=1 PLAYWRIGHT_OCR_LIVE=1 PLAYWRIGHT_OCR_LIVE_BATCH=1 PLAYWRIGHT_OCR_LIVE_DIR=<safe-sample-dir> npx playwright test tests/e2e/manual/live-invoice-ocr-batch.spec.ts --workers=1 --reporter=list

结果判读:

  • available 或可解释的重复票据终态表示 OCR 链路可继续人工复核。
  • pending_ocr 超过阈值必须结合 pending 扫描和 worker 日志排查,不能直接算失败或通过。
  • ocr_failed 必须记录错误摘要、provider、样票别名和是否可重试,不记录完整票面字段。
  • 批量样票结论必须区分 PDF、图片、mock 和真实 provider;图片 OCR 仍是后续候选,不进入当前 R7E 验收。

发布候选本地门禁

五人团队内部候选(2026-07-18)

内部部署规划前,先在当前 checkout 上执行两层本地门禁:

bash scripts/qa/run-web-gates.sh payment-concurrency-local
bash scripts/qa/run-local-candidate.sh full
  • payment-concurrency-local 使用回环 PostgreSQL 和 hyb_oa_payment_ 前缀的一次性合成数据库,执行当前全部 migration,并验证付款竞态与审计/通知唯一性;数据库清理失败即门禁失败。
  • run-local-candidate.sh full 执行无历史 Issue CSV 依赖的基础门禁、路由/流程反例和本地 Vite 合成浏览器行为。只有该模式成功时才输出 LOCAL_CANDIDATE_PASS。
  • focused 只重跑路由反例和浏览器行为,成功标记为 FOCUSED_BROWSER_PASS,不能替代 full;list 只证明 Playwright 资产可解析,标记为 LIST_ONLY。
  • 浏览器入口只允许无凭据、无路径参数的 loopback HTTP origin;候选 spec 排除 manual/live,测试数据、角色、账号和材料必须为合成内容。
  • 路由门禁要求所有注册路由完成分类,核心流程 witness 与 manifest 一一绑定,且全部候选用例不得 failed、skipped、unexpected 或来源漂移。

收口证据至少记录:本文件所在提交、命令与退出码、环境边界、migration/临时库清理、路由与流程统计、Playwright passed/skipped/failed 数、十个 witness 的最终 URL/H1/角色/允许与禁止动作、页面错误计数、代表 viewport/溢出指标、脱敏截图引用,以及 finding 的修复/部署/外部验证三层状态。所有路径使用仓库相对引用,不保留原始 payload、真实账号、银行资料或完整本地路径。

本地候选通过后仍只能表述为“本地候选通过,尚未部署”。真实账号分配、超级管理员托管、迁移执行、备份恢复、内部地址验收、公网检查和企业微信真机必须由后续获批 Trellis task 完成。

历史 A8 本地回归参数

首轮主线 A8 复跑本地门禁时,需要先用本地回归参数启动服务,再执行回归脚本。推荐参数:

SERVE_CLIENT_DIST=true
OCR_PROVIDER=mock
IM_NOTIFIER_ENABLED=true
FIELD_ENCRYPTION_KEY=<local-test-key>
PROJECT_DOMAIN_ENABLED=true
PROJECT_LINKING_ENABLED=true
PROJECT_COMMUNICATION_LOG_ENABLED=true
PROJECT_CLOSURE_CHECKLIST_ENABLED=true

注意:

  • FIELD_ENCRYPTION_KEY 只允许使用本地测试值;生产密钥不得提交或写入文档。
  • OCR_PROVIDER=mock 只证明本地 OCR 流程,不代表真实 OCR provider 通过。
  • IM_NOTIFIER_ENABLED=true 用于覆盖通知链路;缺真实企业微信配置时,企业微信真机仍必须标 SKIP。
  • 项目相关开关用于本地项目轻管理回归,不得被解释为扩展 P2 范围。

公网与部署

当前公网服务器信息以受控运维配置为准。历史基础设施信息已脱敏:

  • 服务器:由 DEPLOY_SERVER 在执行时显式提供,不写入仓库。
  • 反代:Caddy
  • 域名示例:oa.hyinda.com

远端操作原则:

  • 先备份配置和数据。
  • 先确认远端目录是否为 git 工作树。
  • 若远端不是 git 工作树,继续使用既有 rsync/部署脚本。
  • 修改 Caddy、数据库、系统服务前必须先说明风险并等待确认。

数据库迁移漂移

如果 npx prisma migrate status 显示本地迁移历史和数据库迁移表分叉,不要自动修复。

必须暂停并让用户确认处理策略:

  • 备份当前数据库。
  • 对齐缺失 migration 文件。
  • 或重建本地开发库并重新 seed。
  • 或对生产/试运行库执行受控迁移。

禁止在未确认时执行:

  • prisma migrate reset
  • 删除迁移记录。
  • 手工改生产表结构。
  • 破坏性数据库命令。

收口标准

每轮交付收口至少包含:

  • 当前 Trellis task 的 PRD、验收、状态和提交引用真实。
  • 明确区分本地 commit、部署来源 commit 和公网复检结果。
  • 自动化命令、结果和必要视觉证据路径记录完整。
  • 已知阻塞明确归类为代码、测试、环境、数据或人工配置。
  • task validate、Trellis governance 和任务要求的必要门禁通过。
  • 历史 Issue CSV 保持审计可追溯,但不要求作为当前状态合同。
  • 中文分批 commit。