文件
hyb-oa/.trellis/tasks/08-30-b2-submit-error-ocr-fallback/implement.md
T

6.2 KiB

实施清单:B2 提交错误可解释性与 OCR 降级合同

1. 规划与证据冻结

  • 记录生产 OCR_PROVIDER=tencent,确认不回退 B2 flag。
  • 用生产只读数据复现 0014 当前三类 B2 判断与时间线,记录历史失败 details 不可恢复的证据边界。
  • PRD、design、implement 经用户审查并明确批准;批准前不运行 task.py start、不改业务代码。

2. 服务端门禁与 DTO

  • 抽取并独立测试只接收最小字段集的金额证据纯函数:verified / manual_review / ocr_failed;三个分支各含边界用例,不依赖 Prisma 记录形状。
  • 提交查询补齐最小 OCR 执行字段,将“无关联 PDF”“金额识别失败”“降级人工核对”“完整金额超额”分支按设计顺序实现。
  • 金额完整时继续用 Prisma.Decimal;混合降级票据时不做不完整金额比较,并把人工核对摘要返回成功响应。
  • 保持 invoice_item_guard_failed、既有字段与 flag off 语义,新增 unlinkedInvoiceIds、amountUnavailableItems 等定位字段。
  • 详情 DTO 增加发票金额证据状态和整单人工核对投影,不返回 OCR 原始结果或敏感票面字段。

3. 未归属发票恢复接口

  • 新增 bound 未归属发票关联本单明细的单事务接口;锁发票/报销、复用 ensureReimbursementParticipant 校验 owner/submitter,并校验状态和目标明细归属。
  • 只更新 linked_item_id 并留审计,不执行 unbind/bind、不短暂释放发票、不创建明细。
  • 覆盖不存在、非 bound、已有归属、跨单明细、非参与人、非草稿/驳回及并发状态变化,失败保持零写入。

4. PC 与移动端

  • 增加共享的 guard details 窄化解析器和安全摘要;未知 details 回退通用中文,不展示 UUID/原始 payload。
  • PC/移动提交失败同时显示可访问摘要和明细/票据就近错误;toast 仅作补充。
  • 未归属票据卡片显示显著状态、明细选择和原子“确认关联”动作;成功刷新详情,失败错误留在卡片。
  • 金额识别失败与降级人工核对使用不同文案;后者在提交前/成功后及审批只读详情持续可见,不宣称自动校验通过。
  • 不调整报销事由编辑、处理进度、关联项目顺序、自动生成明细或 PC sticky 操作布局。

5. 文档与规约

  • 更新 docs/报销发票附件规则.md:明确关联 PDF 与金额证据分层、off 人工核对、腾讯金额失败和混合票据行为。
  • 更新 .trellis/spec/hyb-oa/reimbursement-invoice-ocr.md 的提交合同、错误矩阵、测试矩阵和“取消/增加校验需核对降级合同”通用规则。
  • 不新建文档,不改员工手册中与本轮无关的填报粒度和日期口径。

6. 测试矩阵

  • 后端:未归属发票返回可定位 ID;需票明细无 bound PDF;Tencent/已尝试 OCR 但金额为空;完整金额超额;正常金额通过。
  • 后端:off/未执行 OCR 且金额为空允许提交并标人工核对;有金额 + 降级无金额进入人工核对;有金额 + 识别失败阻断;免票补助无票通过。
  • 后端:0014 类 5 明细/5 金额有效发票逐条关联时正常提交;B2 flag off 兼容路径不变。
  • 后端:原子重新归属接口的成功、权限、状态、跨单、已有归属和并发零写入矩阵。
  • 前端单元/组件:四类中文摘要、畸形 details 回退、ID 到明细/发票可读标签映射、无内部 ID 泄露、ARIA 告警语义。
  • PC/移动 E2E:错误就近呈现、未归属卡片原子选明细、人工核对提示、正常提交;使用合成数据,不保存真实票据截图。
  • 运行 cd server && npm run prisma:validate、聚焦 Vitest,必要时全量相关路由回归。
  • 运行 cd client && npm run typecheck && npm run build 及聚焦 Playwright。
  • 运行 node scripts/qa/check-process-contract.mjs --baseline --json、node scripts/qa/audit-docs.mjs --check-registry、node scripts/qa/check-trellis-governance.mjs 和 git diff --check。
  • 部署失败热修:运行 node scripts/qa/check-ui-design-rules.mjs --strict,确保四个普通用户禁用术语(绑定整单、不绑定明细、发票池、OCR)在报销 PC/移动错误态均无命中;strict 扫描 148 个文件为 0 findings,self-test PASS,该门禁已在重新提交和部署前通过。
  • 第二次部署失败热修:PC/移动提交 mutation 在 B2 onError 中关闭 warn / manual_review 确认弹窗,待模态层卸载后聚焦首个问题;双端回归分别走完两类预检的弹窗确认、B2 阻断、遮罩消失、就地关联和再次提交成功。

7. 只读复核、提交与部署门

  • 实施后执行只读专项 review,重点检查权限/状态机、金额证据三态、混合票据、API 兼容和 PC/移动数据流;reviewer 不改代码。
  • 用户明确批准本轮无障碍机械修正后直接提交并回填元数据;业务提交使用中文并引用 08-30-b2-submit-error-ocr-fallback。新候选须经用户最终 diff 复核后才可 push,部署仍需独立授权。
  • 部署前视觉门:确认 frontend-design 当前不可用后,经用户批准以 ui-ux-pro-max + Playwright 真实渲染替代。PC/390px 手机/667px 横屏无横向溢出,移动选择框与确认按钮均为 44px,sticky 底栏贴合视口且不遮挡问题卡片,提交失败后焦点落到首个具体问题;检查发现 red-600 / red-50 对比度约 4.42:1,已将 PC 与移动报销详情页内所有同类错误块统一为 red-700 / red-50(约 5.92:1),并为共享操作错误补齐 role=alert / aria-live=assertive,复跑通过。该替代门不冒充 frontend-design。全局错误语义色 token 化与视觉裁决 skill 引用修订作为后续治理债处理。部署后仍须用合成草稿完成公网验收,确认 /ready、bundle marker、B2 force_on + global 和真人单据状态;验收前不通知员工可以测试。

8. 回滚

  • 两次公网验收失败均停止员工测试并回滚到 0f3ecfa;本轮无 migration/seed/flag 写入,真人报销和票据关系未修改,合成草稿已删除、合成票据已归档。