Files
ai-contract-platform/project-docs/V2-phase3-ui-display-derivation-design-2026-06-30.md
T
yuqei a3bb78e06b
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Failing after 16m35s
release: freeze V2 release candidate
2026-07-12 15:32:24 +08:00

9.8 KiB
Raw Blame History

AI 合同平台 V2 Phase 3 Slice 3.4 UI 展示字段派生设计评审

背景

本次继续对齐《AI 合同平台 V2 下一阶段开发优化方案》和 Phase 3 schema 硬化设计评审。

Slice 3.1 已完成 contract_versions。 Slice 3.2 已完成正式审批模型。 Slice 3.3 已完成治理字段和软删除,并已在权威 V2 smoke PostgreSQL/Docker 环境验证到 Alembic head 20260630_0021。

Slice 3.4 的目标不是新增业务页面,也不是立即删除数据库字段,而是把 status_label、status_tone、next_action、next_actions 这类 UI 展示字段逐步从事实表中迁出,转为 domain/serializer 派生。

当前问题

contracts 表仍保存以下 UI 展示字段:

  • status_label
  • status_tone
  • next_action
  • next_actions

这些字段目前还被以下路径使用:

  • 合同列表和合同详情响应。
  • 工作台待办卡片。
  • dashboard 状态统计标签。
  • 统一搜索文档的 status_label、summary 和 search_text。
  • 审批、审查、文件上传、条款修复等状态流副作用。
  • 前端 TypeScript service 和 OpenAPI schema 兼容字段。

直接删除字段风险较高,因为前端和搜索仍需要这些响应字段。

设计原则

  1. 不在 Slice 3.4 第一片删除数据库列。
  2. 不改变现有 API 响应字段名。
  3. 不改变前端读取字段方式。
  4. 先把派生规则集中到 domain/serializer 层。
  5. 旧字段暂时保留为兼容缓存,用于灰度和回滚。
  6. 当数据库缓存值与派生值不一致时,响应层优先使用派生值,并记录 warning。
  7. status_label 和 status_tone 可以直接从 status 强派生。
  8. next_action 和 next_actions 需要分阶段迁出,因为当前它们既包含状态默认动作,也包含少量合同上下文提示。

第一片实现边界

新增 contract_display.py,集中维护:

  • ContractDisplayFields
  • CONTRACT_DISPLAY_BY_STATUS
  • derive_contract_display
  • status_label_for_status
  • status_tone_for_status

第一片 read-switch:

  • 合同列表响应:status_label、status_tone 优先派生。
  • 合同详情响应:status_label、status_tone 优先派生。
  • 合同详情响应:next_action、next_actions 对已知旧状态默认文案做派生修正。
  • 统一搜索文档:合同类文档的 status_label、summary、search_text 使用派生结果。
  • in-memory dashboard:状态标签从 status 派生。

第一片暂不做:

  • 不删除 contracts.status_label 等旧列。
  • 不移除写路径中的旧字段写入。
  • 不修改 OpenAPI 字段。
  • 不修改前端字段名。
  • 不把所有合同特定 next_action 强制覆盖成状态默认值。

next_action 分阶段策略

next_action 当前有两类含义:

  1. 状态默认动作,例如“审批人处理”“修改后重新提交”“准备签署与归档”。
  2. 业务上下文提示,例如“法务确认付款和验收条款”“补充租赁期限后提交”“跟踪履约节点”。

第一片只覆盖明显属于旧状态默认文案、且与当前 status 不一致的缓存值。

后续要把 next_action 完全派生,需要先从结构化事实中提取上下文:

  • 审批实例和待办步骤。
  • 最新审查任务状态。
  • 未完成义务任务。
  • 条款修复动作。
  • 合同版本/草稿编辑状态。

验收标准

第一片验收:

  • 当数据库中 status_label/status_tone 与 status 不一致时,合同列表和详情响应返回派生值。
  • 当数据库中 next_action/next_actions 是已知旧状态默认文案且与当前 status 不一致时,合同详情响应返回派生默认动作。
  • 合同搜索文档重建后使用派生的 status_label。
  • 现有合同工作流测试继续通过。

后续完整验收:

  • 合同列表、详情、搜索、工作台展示不依赖手工维护 UI 文案。
  • 数据库字段表达业务事实,UI 文案集中在代码映射层。
  • PostgreSQL smoke 环境中搜索重建、合同列表、详情、workspace 抽样均通过。

回滚策略

第一片只新增集中派生层并切换响应读取,不删除旧列。

如出现前端展示异常,可以回滚 mapper/search 对 derive_contract_display 的调用,数据库旧字段仍可继续支撑响应。

后续拆分建议

  1. 权威 V2 smoke PostgreSQL 环境复跑合同列表、详情、搜索、workspace、runtime schema-check 抽样。
  2. 稳定后再评审是否进入 cleanup migration,删除或降级旧 UI 缓存列。

第二片实施记录

本次已实现 ContractActionContext,将 next_action 和 next_actions 从“状态默认 + 旧缓存兼容”推进到“状态 + 结构化上下文”派生。

新增上下文来源:

  • 最新审查任务状态:queued、running、succeeded、failed。
  • 审查风险项是否存在未处理风险。
  • 审查风险项是否已有 repair_status=applied 的条款修复记录。
  • 正式审批模型中的 pending approval instance/step。
  • 未完成履约任务的首个待处理节点。

派生优先级:

  1. 已应用条款修复:提示“复核已应用的条款修订”。
  2. 审查任务排队或运行中:提示“等待法律审查结果”。
  3. 审查失败:提示“重新发起法律审查”。
  4. 审查完成且存在未处理风险:提示“处理审查风险并应用推荐条款”。
  5. 审查完成且存在风险但无需条款修复:提示“根据审查结果修改或提交审批”。
  6. 正式审批待办:提示“等待审批人审批”。
  7. 已审批、已签署、已归档阶段存在未完成履约任务:提示具体履约节点。
  8. 否则回落到 status 默认动作。

接入范围:

  • SQLAlchemy 合同列表响应。
  • SQLAlchemy 合同详情响应。
  • 工作台待办响应。
  • 统一搜索文档同步/重建。
  • transition 写路径的即时响应。

仍未做:

  • 未删除 contracts.status_label/status_tone/next_action/next_actions 旧列。
  • 未移除旧写路径对 UI 缓存字段的写入。
  • 未修改 OpenAPI 和前端字段名。
  • 未把合同版本/草稿编辑状态纳入 ContractActionContext。

验证:

python -m compileall -q yuqei-contract-platform\services\contract-api\src\yuqei_contract_api
python -m pytest yuqei-contract-platform\services\contract-api\tests -q

结果:完整 Contract API 测试通过。

远端 PostgreSQL / Docker smoke 验证记录

验证环境:

  • 服务器:192.168.3.90
  • Compose project:yuqei-contract-v2-smoke
  • Contract API:http://192.168.3.90:18100
  • PostgreSQL 数据库:yuqei_contract
  • 部署 artifact:project-docs/qa-artifacts/v2-smoke-docker-deploy/2026-06-30T16-40-34

执行命令:

powershell.exe -NoProfile -ExecutionPolicy Bypass -File yuqei-infra\scripts\deploy-v2-smoke-docker.ps1 -UseSshpass -AllowDirtyWorktree -KeepRemoteBackup

结果:

  • Docker smoke:通过。
  • Web、Contract API、AI Platform API health endpoints:通过。
  • AI golden sample asset gate:通过,90 samples、6 suites、16 checks。
  • Remote database baseline:yuqei_contract、yuqei_ai、yuqei_ops 均存在。
  • Contract review worker smoke:通过。

/api/v1/runtime/schema-check 抽样结果:

  • 顶层状态:warning。
  • database_backend:ok,PostgreSQL。
  • database_name:ok,当前数据库为 yuqei_contract。
  • alembic_version:ok,actual/head 均为 20260630_0021。
  • core_tables:ok,检查 20 张核心表。
  • governance_columns:ok,检查 11 张表、36 个治理字段。
  • postgres_extensions:ok,已安装 pg_trgm。
  • display_cache_consistency:warning,检查 12010 条未软删除合同记录,发现 8000 条旧 UI 缓存字段与派生值不一致。

样例:

perf-contract-000001:status_tone
perf-contract-000004:status_label
perf-contract-000005:status_tone
perf-contract-000006:status_label,status_tone
perf-contract-000007:status_tone

处理说明:

  • 本片只做只读检查,不自动修复旧缓存。
  • 本片不删除 contracts.status_label/status_tone/next_action/next_actions 旧列。
  • 为避免报告型 warning 误伤容器健康状态,Contract API Docker healthcheck 已调整为只在 schema-check 顶层状态为 error 时失败;warning 继续保留在 runtime schema-check 报告中供后续治理。

第三片实施记录

本次已将 display cache consistency 纳入 Contract API runtime schema-check。

新增检查项:

  • display_cache_consistency

检查范围:

  • 只读扫描 contracts 表中未软删除记录。
  • 对比旧缓存字段与 derive_contract_display 派生值:
    • status_label
    • status_tone
    • next_action
    • next_actions

返回策略:

  • 全部一致:status=ok。
  • 存在不一致:status=warning,不自动修复。
  • contracts 表缺失:status=warning 并标记 skipped,由 core_tables 继续负责报 error。

返回 details:

  • checked_rows
  • mismatch_count
  • sample_limit
  • samples:最多 5 条,格式为 contract_id:field1,field2。

本片仍不做:

  • 不写库。
  • 不修复旧缓存。
  • 不删除旧列。
  • 不改变 OpenAPI 和前端字段。

验证:

python -m compileall -q yuqei-contract-platform\services\contract-api\src\yuqei_contract_api
python -m pytest yuqei-contract-platform\services\contract-api\tests\test_health.py::test_runtime_schema_check_warns_for_local_sqlite_auto_created_schema yuqei-contract-platform\services\contract-api\tests\test_health.py::test_runtime_schema_check_errors_for_missing_core_tables yuqei-contract-platform\services\contract-api\tests\test_health.py::test_runtime_schema_check_warns_for_stale_contract_display_cache -q
python -m pytest yuqei-contract-platform\services\contract-api\tests -q

结果:完整 Contract API 测试通过。