1d85329a6a
Build and Test Quality Gate / Contract Web typecheck and build (pull_request) Successful in 9m12s
Build and Test Quality Gate / Isolated Alibaba and Tencent KMS gateway (pull_request) Failing after 4m53s
Build and Test Quality Gate / Python tests and Contract API migration (pull_request) Failing after 24m55s
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Failing after 8m42s
8.2 KiB
8.2 KiB
V2 P1-04.1 可审阅 Playbook 兜底合同新版本实施与 UAT 报告
日期:2026-08-23
状态:已完成,隔离 UAT 通过。
1. 目标与验收结论
P1-04.1 的目标是把企业 Playbook 兜底从“直接修改正文”升级为“生成候选版本、审阅差异、明确采用”,确保系统不会在用户没有确认的情况下静默覆盖当前合同正文。
验收结论:通过。
- 一键生成的是独立候选版本,不会修改
contracts.body_content。 - 候选版本自动打开原文/新文差异审阅界面。
- “确认采用为当前正文”默认禁用,用户必须勾选明确确认。
- 采用请求必须同时携带
confirmed=true和已审阅的候选正文 SHA-256。 - 当前正文、合同状态或候选摘要发生变化时,系统停止采用并转人工处理。
- 采用成功后原正文仍保留为历史版本,可继续查看、比较和取证。
2. 两阶段状态机
审查快照命中规则
|
v
生成候选版本 candidate --------> 当前合同正文保持不变
|
| 用户打开差异、勾选确认、提交候选哈希
v
显式采用 adopted --------------> 候选正文成为当前正文
|
+------------------------> 原正文继续保留在版本历史
任一状态/正文/哈希冲突 --------> conflict + 审计证据 + 人工接管
兼容既有数据:历史 succeeded 执行记录继续按已采用处理,不要求回写迁移。
3. 产品与交互改造
3.1 生成候选
- 原“应用企业兜底文本”按钮改为“生成可审阅新版本”。
- 一次点击完成规则快照校验、候选正文生成、候选版本落库和审计记录。
- 生成成功后立即展示红绿差异,并明确提示“当前正文尚未修改”。
- 关闭差异对话框后,页面显示“候选版本待审阅 / 原正文未修改”。
3.2 明确采用
- 差异对话框同时显示原正文和候选版本的删除/新增内容。
- 采用按钮默认禁用;只有勾选“我已审阅原正文与候选版本差异”后才可点击。
- 用户可选择“暂不采用”,候选版本保留,当前正文不变。
- 采用后显示“兜底版本已采用”,下一步引导为“重新发起审查验证企业兜底文本”。
3.3 版本历史
- 候选未采用时标记“候选待审阅”。
- 采用后标记“已确认采用”。
- 版本列表保留原版本与候选版本,可分别查看正文并与当前版本比较。
- 候选生成或采用后,版本面板通过页面事件立即刷新,无需用户手动刷新页面。
4. 后端安全边界
4.1 生成阶段
- 锁定当前租户的合同记录。
- 校验审查任务成功、快照 ID、快照摘要、规则版本和来源正文哈希。
- 校验合同处于
draft、reviewing或rejected。 - 生成
playbook_fallback_candidate版本与执行台账,不更新当前合同正文。 - 写入
playbook_fallback_candidate_created审计事件,记录原文与候选正文哈希。
4.2 采用阶段
- 新接口:
POST /api/v1/contracts/{contract_id}/playbook-fallbacks/{execution_id}/adopt。 - 仅具备合同编辑权限的账号可以调用。
- 请求必须提交 64 位候选正文 SHA-256 和字面值为
true的确认字段。 - 在数据库事务中锁定合同和候选执行记录。
- 再次校验租户、合同状态、当前正文哈希、候选版本来源和候选正文哈希。
- 全部通过后才更新当前正文,并把候选版本标记为已采用。
- 写入
playbook_fallback_adopted审计事件和采用人、采用时间。
4.3 冲突与幂等
- 候选生成使用租户级幂等键,重复请求不会重复创建版本。
- 已采用候选再次提交采用请求时安全重放,不重复修改正文。
- 候选生成后如果有人编辑了当前正文,采用操作返回
conflict,当前正文保持编辑后的内容。 - 冲突记录包含
requires_manual_handoff=true、当前正文哈希和期望正文哈希。 - 文件审查仍保持只读,不自动改写原始附件。
5. 隔离 UAT 证据
5.1 环境与账号
- 租户:
uat-playbook-20260823(Playbook 隔离 UAT)。 - 法务/租户管理员:
uat.legal.20260823@example.test。 - 独立审批人:
uat.approver.20260823@example.test。 - 两个账号为独立用户,报告不记录密码。
5.2 验收对象
- 合同:
contract-a9323e1ded7f。 - 标题:
UAT P1-04.1 可审阅兜底版本合同。 - 审查任务:
review-045068122a21。 - 快照:
playbook-snapshot-045068122a21。 - 快照摘要:
4b66f02e671ecfbdb7fd42784aa1db2ad4020ca4654e8998530be10c0f273a4e。 - 执行记录:
playbook-fallback-c3c35c792911。 - 候选版本:
version-970c07ed14bd。 - 最终执行状态:
adopted。
5.3 Chrome 可视化验收
- 法务账号创建包含“承担全部且无限责任”的合同并完成 AI 审查。
- 页面命中租户规则
UAT 禁止无限责任,聚合快照显示 1 条可用兜底。 - 点击“生成可审阅新版本”后自动打开差异对话框:
- 原无限责任表述显示为删除内容;
- 企业兜底文本显示为新增内容;
- 页面明确显示“当前正文尚未修改”;
- 确认采用按钮默认禁用。
- 关闭差异对话框后,正文预览仍显示原无限责任表述,证明候选生成没有覆盖正文。
- 切换独立审批账号:
- 可以查看候选待审阅状态和版本证据;
- 看不到生成、审阅、采用或编辑按钮。
- 切回法务账号,打开候选差异并勾选确认,随后采用:
- 当前正文切换为企业兜底文本;
- 页面显示“兜底版本已采用”;
- 下一步提示为重新发起审查。
- 版本面板显示版本 1 和版本 2:
- 版本 2 标记“已确认采用”;
- 打开版本 1 仍能完整看到原无限责任正文。
6. 主要实现位置
- 状态与请求模型:
yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/enterprise_playbook.py - 候选生成与采用事务:
yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/sqlalchemy_playbook_fallback_orchestration.py - API 路由:
yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/api/review.py - 数据模型:
yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/persistence/models.py - 数据库迁移:
yuqei-contract-platform/services/contract-api/migrations/versions/20260823_0052_add_playbook_candidate_adoption.py - 前端差异与确认:
yuqei-contract-platform/apps/contract-web/src/app/contracts/[id]/apply-playbook-fallback-button.tsx - 版本证据展示:
yuqei-contract-platform/apps/contract-web/src/app/contracts/[id]/contract-version-panel.tsx - Web 采用代理:
yuqei-contract-platform/apps/contract-web/src/app/api/contract-platform/contracts/[id]/playbook-fallbacks/[executionId]/adopt/route.ts - OpenAPI:
yuqei-contract-platform/packages/contract-openapi/openapi.yaml
7. 自动化、迁移与构建
- 后端核心回归:98 项通过。
- 新增断言覆盖:候选生成不改正文、未确认请求拒绝、候选采用、采用幂等、租户隔离、审批人无编辑权限、生成前漂移冲突、生成后漂移冲突。
- 前端测试:全部通过。
- TypeScript 类型检查:通过。
- Python
compileall:通过。 - OpenAPI YAML 解析:通过。
- Next.js 生产构建:通过,114 个页面路由完成构建。
- PostgreSQL 迁移:
20260823_0052 (head)。 - 全新 SQLite 数据库从 0 到
0052完整迁移:通过。
非阻断告警:测试环境仍有 Starlette TestClient 上游弃用提示,以及 Windows .pytest_cache 已存在导致的缓存写入提示,不影响测试结果和产品功能。
8. 当前运行状态与下一步
- Web:
http://127.0.0.1:3000,运行中。 - Contract API:
http://127.0.0.1:8100,启用 Web 代理鉴权,运行中。 - AI API:
http://127.0.0.1:8101,运行中。 - Review Worker:运行中。
- Chrome 保留在合同
contract-a9323e1ded7f的采用后验收页面。
建议后续进入 P1-04.2:支持一次审阅多个规则候选、逐条勾选或跳过、组合差异预览,以及候选版本主动撤销;仍应保持“未经明确确认不更新当前正文”的发布门槛。