Files
ai-contract-platform/project-docs/V2-phase3-action-hint-ui-api-semantics-2026-07-01.md
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

147 lines
5.6 KiB
Markdown
Raw Permalink 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 action_hint 前端与接口语义收敛
## 背景
上一片已停写旧 `contracts.next_action / contracts.next_actions` 生产写路径,并确认 API 响应继续由完整 `ContractActionContext` 派生。
本片继续收敛产品语义:
- `action_hint` 是人工填写的跟进提示事实字段。
- `next_action / next_actions` 是系统派生的展示字段和兼容响应字段。
- 旧 `next_action` 写入入口在观察窗口通过后已进入 rejected 阶段,不再规范化到 `action_hint`。
## 本次调整
### 前端编辑入口
合同详情编辑面板中的“人工跟进提示”输入框现在只使用:
- `contract.action_hint`
不再 fallback 到:
- `contract.next_action`
原因:
- `next_action` 现在是系统派生动作,例如“等待审批人审批”“处理审查风险并应用推荐条款”。
- 如果编辑表单默认带入派生动作,用户保存时会把系统动作误存成人工提示。
同时,编辑面板 Props 已移除 `next_action` 依赖,后续 TypeScript 会阻止该组件重新把派生动作当作人工提示默认值。
前端占位文案也同步收敛为“人工补充的跟进提示,不会覆盖系统下一步操作”,避免把 `action_hint` 理解成可手工改写系统派生动作。
### API / OpenAPI 语义
后端 DTO 和 OpenAPI 已补充字段说明:
- `ContractUpdateRequest.action_hint`
- 支持写入。
- 表示人工跟进提示。
- `ContractUpdateRequest.next_action`
- deprecated。
- 不再接受写入。
- 客户端应改用 `action_hint`。
- `ContractUpdateRequest.next_actions`
- deprecated。
- 不再接受写入。
- 响应按钮列表由 `ContractActionContext` 派生。
- `ContractListItem.next_action`
- 响应字段保留。
- 来源是派生展示动作,不是持久化人工输入。
- `ContractDetail.next_actions`
- 响应字段保留。
- 来源是派生动作按钮。
## 没有做
- 未删除旧数据库列。
- 未移除响应字段 `next_action / next_actions`。
- 未移除旧 `next_action / next_actions` 请求字段定义,但写路径已拒绝旧字段。
- 未进入 cleanup migration。
## 验证
```powershell
python -m py_compile yuqei-contract-platform\services\contract-api\src\yuqei_contract_api\domain.py
python -m pytest `
yuqei-contract-platform\services\contract-api\tests\test_contract_workflow.py::test_contract_update_accepts_action_hint_and_rejects_legacy_next_action `
yuqei-contract-platform\services\contract-api\tests\test_contract_workflow.py::test_contract_action_hint_derives_next_action_without_overriding_buttons `
-q
npm --workspace @yuqei/contract-web run typecheck
```
结果:
- `py_compile`:通过。
- 后端 action_hint 回归:2 passed。
- contract-web typecheck:通过。
## 远端 smoke 验证
环境:
- 宿主机:`192.168.3.90`
- compose project:`yuqei-contract-v2-smoke`
- Contract API:`http://127.0.0.1:18100`
- Contract Web:`http://127.0.0.1:13000`
- PostgreSQL database:`yuqei_contract`
验证结果:
- `contract-api` / `contract-web` 容器均为 healthy。
- `/api/v1/runtime/schema-check` 返回 `status=ok`。
- `display_cache_consistency`:
- `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`
- `next_step=stop_legacy_display_cache_writes_before_drop_columns`
- 旧 `next_action` PATCH 抽样:
- smoke 合同:`contract-19740a3a80f2`
- 请求字段:`next_action=legacy-next-action-alias-to-action-hint`
- 响应字段:`action_hint=legacy-next-action-alias-to-action-hint`
- 响应字段:`next_action=legacy-next-action-alias-to-action-hint`
- 数据库字段:`action_hint=legacy-next-action-alias-to-action-hint`
- 数据库旧缓存字段:`next_action=''`
- 数据库旧缓存字段:`next_actions=[]`
- 合同详情页面:`/contracts/contract-19740a3a80f2` 返回 HTTP 200。
- 最近 10 分钟 `Contract display cache mismatch` 日志计数为 0。
- 前端文案收敛后已重新构建并部署 `contract-web`:
- Next build:通过。
- 生产构建内置 TypeScript:通过。
- `contract-web` 容器:healthy。
- 合同详情页面:`/contracts/contract-19740a3a80f2` 返回 HTTP 200。
## cleanup migration 评审结论
本轮不进入删列或移除响应字段的 cleanup migration。
理由:
- `next_action / next_actions` 仍是对外响应兼容字段,前端和旧调用方可能仍读取。
- 旧 `next_action` 写入口已经明确降级为 `action_hint` alias,保留它不会再污染旧缓存列。
- schema-check 已把检查口径收敛到 `status_label/status_tone`,并明确标注旧动作列只作为兼容保留。
- 后续真正删列前,需要先观测是否仍有外部客户端提交旧字段,并决定是否增加 alias 使用审计。
- 旧 alias 使用观测已进入独立收口文档:`V2-phase3-deprecated-next-action-alias-observability-2026-07-01.md`。
## 当前结论
前端和接口语义已收敛为:
- 人工输入只走 `action_hint`。
- 系统展示只读 `next_action / next_actions` 派生响应。
- 旧写入字段已经拒绝,不再作为兼容入口。
下一步仍建议先保持兼容观测,不直接删列。若继续推进 cleanup,应先检查:
- 是否还有外部客户端提交 `next_action / next_actions`。
- 是否需要在日志或审计中记录旧 alias 的使用次数。
- 是否需要在后续版本中把 OpenAPI deprecated 字段推进到移除计划。