Files
ai-contract-platform/project-docs/V2-phase3-stop-legacy-next-action-writes-2026-07-01.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

6.7 KiB
Raw Blame History

AI 合同平台 V2 Phase 3 停写旧 next_action 缓存列

背景

本记录承接 V2-phase3-display-cache-context-prestate-2026-07-01.md。

上一片已确认:

  • contracts.status_label/status_tone/next_action/next_actions 旧列仍保留。
  • API 响应字段继续兼容输出。
  • 用户可见动作应由 derive_contract_display(...) 和完整 ContractActionContext 派生。

本片目标是继续保守推进:停写旧 contracts.next_action / contracts.next_actions 生产写路径,但不删列、不改响应字段。

本次调整

生产写路径

sync_contract_action_display_cache(...) 现在只同步:

  • contracts.status_label
  • contracts.status_tone

不再刷新:

  • contracts.next_action
  • contracts.next_actions

合同创建时,旧动作缓存列写入空兼容值:

  • next_action=""
  • next_actions=[]

人工下一步提示继续写入结构化事实字段:

  • contracts.action_hint

旧 next_action PATCH 入口仍兼容,但会规范化写入 action_hint,不会再写回旧 next_action 缓存列。

读路径和搜索

以下用户可见路径继续通过完整 ContractActionContext 派生动作字段:

  • 合同列表
  • 合同详情
  • workspace
  • 统一搜索合同文档
  • 条款修复后详情响应

因此 API 响应中的 next_action / next_actions 保持兼容,但来源不再是旧缓存列。

schema-check / display cache governance

display_cache_consistency 的语义调整为:

  • 检查 status_label/status_tone 是否与 status 派生值一致。
  • 确认 next_action/next_actions 旧列仍保留,但不再要求它们与完整上下文派生动作一致。

原因:

  • next_action/next_actions 已进入停写阶段。
  • 如果仍把旧动作列纳入 mismatch 统计,每次审查、审批、条款修复等结构化事实变化后都会把“停写后的旧缓存”误报为不一致。
  • 真正的动作展示一致性由读路径、搜索索引和对应回归测试保障。

display_cache_cleanup_prestate 仍要求四个旧列存在,继续作为删列前保护门。

没有做

  • 未删除数据库列。
  • 未修改 OpenAPI/前端响应字段。
  • 未停止 action_hint 写入。
  • 未迁移 in-memory demo 仓储;本片只处理生产 SQLAlchemy 写路径。
  • 未进入 cleanup migration。

验证

python -m py_compile `
  yuqei-contract-platform\services\contract-api\src\yuqei_contract_api\sqlalchemy_action_context.py `
  yuqei-contract-platform\services\contract-api\src\yuqei_contract_api\persistence\contract_core.py `
  yuqei-contract-platform\services\contract-api\src\yuqei_contract_api\display_cache_governance.py `
  yuqei-contract-platform\services\contract-api\src\yuqei_contract_api\schema_check.py `
  yuqei-contract-platform\services\contract-api\src\yuqei_contract_api\sqlalchemy_clause_repair_orchestration.py

python -m pytest yuqei-contract-platform\services\contract-api\tests\test_display_cache_governance.py -q
python -m pytest yuqei-contract-platform\services\contract-api\tests\test_health.py -q
python -m pytest yuqei-contract-platform\services\contract-api\tests\test_contract_workflow.py -q -k "action_hint or display_cache or action_display_cache or search_document_generation_uses_contract_action_context or contract_list_and_detail_expose_next_action or submit_reject_resubmit_and_approve_workflow or upload_file_and_start_review or clause_repair"

结果:

  • test_display_cache_governance.py:5 passed
  • test_health.py:10 passed
  • 合同工作流目标集:13 passed

当前结论

Phase 3 现在进入更明确的停写状态:

  • status_label/status_tone:仍作为兼容缓存保留,并保持由 status 派生同步。
  • next_action/next_actions:旧列仍保留,但生产写路径已停写;用户可见字段由完整上下文派生。
  • action_hint:作为人工提示事实字段保留。

下一步仍不建议删列。应先部署到 192.168.3.90 smoke,复跑:

  • /api/v1/runtime/schema-check
  • 合同创建、PATCH action_hint、提交审批、退回、重提
  • 发起审查、审查失败/成功、条款修复
  • 合同列表、详情、workspace、统一搜索抽样

通过后再评审是否继续收敛前端旧 next_action 输入文案,或进入更后面的 cleanup migration 设计。

远端 smoke 验证

验证环境:

  • Host:192.168.3.90
  • Contract API:http://192.168.3.90:18100
  • Contract Web:http://192.168.3.90:13000
  • Database:yuqei_contract
  • Compose project:yuqei-contract-v2-smoke

本次同步并重建:

  • contract-api
  • contract-api-migrate
  • contract-review-worker
  • contract-web

服务状态:

  • contract-api:healthy
  • contract-review-worker:healthy
  • contract-web:healthy
  • ai-platform-api:healthy
  • postgres:healthy
  • redis:healthy
  • minio:healthy

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

{
  "status": "ok",
  "display_cache_consistency": {
    "status": "ok",
    "checked_rows": 12020,
    "mismatch_count": 0,
    "checked_fields": "status_label,status_tone",
    "retained_compat_fields": "next_action,next_actions"
  },
  "display_cache_cleanup_prestate": {
    "status": "ok",
    "legacy_columns_retained": true,
    "display_cache_consistent": true,
    "checked_rows": 12020,
    "mismatch_count": 0
  }
}

接口抽样:

  1. 新建合同后,API 返回默认派生 next_action=补充后提交审批。
  2. PATCH action_hint=SMOKE_HINT_SEARCH_BEFORE_APPROVAL 后:
    • 详情 API 返回 next_action=SMOKE_HINT_SEARCH_BEFORE_APPROVAL。
    • 统一搜索能搜到该派生动作。
    • 数据库行中 action_hint 已写入,但 next_action=""、next_actions=[]。
  3. 提交审批后:
    • API 返回 status=approval_pending。
    • API 返回 next_action=等待审批人审批、next_actions=["审批通过","退回修改"]。
    • 数据库行中 action_hint 保留,但 next_action=""、next_actions=[]。
    • 搜索不再命中旧 action_hint,符合审批上下文优先级高于人工提示的规则。

日志抽样:

  • 最近 10 分钟 Contract display cache mismatch 计数:0。

结论:

  • 旧动作缓存列停写已在 smoke PostgreSQL 环境验证通过。
  • API/搜索仍由完整 ContractActionContext 派生动作展示。
  • schema-check 新口径正常工作。

后续语义收敛

2026-07-01 后续小片已完成前端和接口语义收敛:

  • 合同详情编辑面板中的人工提示输入只读取 action_hint,不再 fallback 到派生 next_action。
  • 后端 DTO 和 OpenAPI 已标明 action_hint 是推荐写入字段。
  • 旧 next_action / next_actions 写入字段标记为 deprecated 兼容入口。

详细记录见:

  • project-docs/V2-phase3-action-hint-ui-api-semantics-2026-07-01.md