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

196 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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。
## 验证
```powershell
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` 结果:
```json
{
"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`