From c81ed9ca697d27ab012501ae88ae2f67f2ed69d8 Mon Sep 17 00:00:00 2001 From: shunli Date: Fri, 25 Sep 2026 19:55:28 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E5=A1=AB=E5=85=AC=E7=BD=91=E9=AA=8C?= =?UTF-8?q?=E6=94=B6=E4=B8=8E=E6=81=A2=E5=A4=8D=E8=AF=8A=E6=96=AD=E4=B8=AD?= =?UTF-8?q?=E5=8F=91=E7=8E=B0=E7=9A=84=E6=B5=8B=E8=AF=95=E8=A7=84=E5=88=99?= =?UTF-8?q?=20[08-23-isolated-backup-restore-drill]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 从孤儿 worktree(20260909-invoice-first、20260910-reimbursement-payment-integration) 合并回填两条实测中发现、从未提交的通用测试规则: - reimbursement-invoice-ocr.md:公网合成验收流程(provider 检查→锁定 SHA256→ 上传);Fastify 对无 body 的 DELETE 请求发送 application/json 会报 FST_ERR_CTP_EMPTY_JSON_BODY 的坑;批量分类后编辑需等视图更新, getByLabel 对已有内容的嵌套 textarea 可能定位失配。 - deployment-trialrun.md:buildSha 公网字段固定截断为 12 位、探针不得按 完整 40 位比较;readiness fixture 必须覆盖错误/过短/空/超长四种值并在 目标主机做无权限探测;附件引用校验失败前必须先保留已完成的 DB/解包 结果,不能让后续失败掩盖已核实的部分。 均为测试脚本经验教训,无产品代码改动。 Co-Authored-By: Claude Sonnet 5 --- .trellis/spec/hyb-oa/deployment-trialrun.md | 17 +++++++++++++++++ .../spec/hyb-oa/reimbursement-invoice-ocr.md | 14 ++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/.trellis/spec/hyb-oa/deployment-trialrun.md b/.trellis/spec/hyb-oa/deployment-trialrun.md index 3160ffa6..c68fa80d 100644 --- a/.trellis/spec/hyb-oa/deployment-trialrun.md +++ b/.trellis/spec/hyb-oa/deployment-trialrun.md @@ -727,6 +727,12 @@ const REQUIRED_ADMIN_NAV_KEYS = ["systemSettings"]; must explicitly provide both and must not publish `unknown`. - Deployment compares public `/ready` and the public bundle marker with the verified commit before reporting success. +- `/health.data.buildSha` and `/ready.data.buildSha` are normalized by + `server/src/config.js` to the first 12 characters. A probe with a pinned full + commit must compare the public value to exactly those 12 characters, not the + full commit or an arbitrary-length prefix. Runtime environment and backup + manifest identities remain full-SHA checks. A public identity mismatch is + not by itself proof that production changed. ### 4. Validation & Error Matrix @@ -759,6 +765,11 @@ const REQUIRED_ADMIN_NAV_KEYS = ["systemSettings"]; - Synthetic 40-character build: bundle contains the matching 12-character SHA and not the full value. - Local-stub readiness test for expected/observed SHA propagation. +- Readiness fixtures must derive the public SHA from the actual `getConfig` + contract; cover wrong, short, empty and unexpectedly full public values. + Before a privileged restore handoff, exercise the same public probe from the + target host without privileges; a stub that echoes the input full SHA cannot + substitute for this read-only check. - Public deployment still requires separate approval and post-deploy checks. ### 7. Wrong vs Correct @@ -1627,6 +1638,12 @@ validate_copied_batch(private/batch, source_metadata) - Emit the fixed diagnostic fields on the failure path before runtime teardown. Teardown remains in a trap/finally-equivalent path and must still run after diagnostic emission; callers retain stdout, not the private raw log. +- Before an attachment-reference failure, preserve completed DB checks, + extraction/file-count results and per-source reference/mismatch counts. + Classify missing files, size/hash mismatches, unsafe paths, malformed rows, + unreadable files and external storage without outputting identifiers or paths. + Check diagnostic totals against the unchanged validator; disagreement also + fails closed. Do not skip archived, test or duplicate references to gain PASS. - An ARM restore runner fixes `restore_execution_path=DOCKER_STDIN`. A private Docker proxy may observe the real `pg_restore --list` and apply calls and persist only their stage name and numeric exit code; it must not record argv, diff --git a/.trellis/spec/hyb-oa/reimbursement-invoice-ocr.md b/.trellis/spec/hyb-oa/reimbursement-invoice-ocr.md index 963775f5..68cf1875 100644 --- a/.trellis/spec/hyb-oa/reimbursement-invoice-ocr.md +++ b/.trellis/spec/hyb-oa/reimbursement-invoice-ocr.md @@ -38,6 +38,20 @@ duplicate detection or attachment behavior. ## Rules +- 公网合成验收先用明确标注测试用途、无真实交易的样票单独跑 provider 必填检查, + 通过后锁定 SHA256,再上传走队列/UI;provider 成功不替代上传整链。保留失败轮次, + 最终区分草稿、审批、付款证据。清理使用本轮精确对象,回读草稿为零、票据归档且 + 未绑定、测试会话已撤销;归档不等于物理附件/OCR/审计数据删除。 +- 测试 API 无 body 的 DELETE 不发送 application/json:Fastify 会报 + FST_ERR_CTP_EMPTY_JSON_BODY(400);省略该头应正常进入处理器。 + 登录按实际合同携带设备指纹,logout 使用对应浏览器 Cookie;无 Cookie 的 200 + 不是会话撤销证据。报销 precheck 虽为 POST 但不等于提交审批,测试应按实际副作用 + 控制白名单,不能拦截该接口后宣称正常页面请求完整通过。 +- 批量分类测试先等视图完成更新并核持久化类型,再开始另一项编辑,不能仅等待 + classify HTTP 响应就假定查询缓存已更新。嵌套 label 内已有内容的 textarea 可能 + 使 getByLabel 的精确文本定位失配;使用稳定字段标识或 label 的独立 span + textarea, + 同时覆盖空值与已有值,不靠延长超时反复消耗生产登录。 + - 隔离串联的 `RUN_JOB_QUEUE=1` 必须运行真实 startPgBossJobs 与上传入口 enqueue, 等对应 invoiceId 的队列任务 completed,再校验发票状态和页面,不用直接调用 worker 冒充调度。只连接脚本新建数据库;非关注周期任务不得在测试期间改其他对象。