a3bb78e06b
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Failing after 16m35s
196 lines
6.7 KiB
Markdown
196 lines
6.7 KiB
Markdown
# 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`
|