收紧 V4 复核解阻边界

This commit is contained in:
andy
2026-07-19 11:56:12 +07:00
parent d0d26c7fbe
commit b4f1b3c856
6 changed files with 160 additions and 7 deletions

View File

@@ -472,7 +472,7 @@ RESERVATION_ROOMING_LIST_GENERATE
- M002 V4 CP2 订单任务与多卡领域模型设计已落到 `docs/project/requirements/M002-v4-order-task-card-domain-model-cp2.md`:后续前端 V4 页面应围绕 `order_task + source_message_card + basic_information_card + business_cards[]` 设计V4 工作台统一列表、业务订单任务列表 / 详情和 S10/S99 来源通知详情已实现。
- M002 V4 CP3 已新增 V4 订单任务、任务卡、S10/S99 来源通知三张表和 Repository 基线M002 V4 CP4 已把正式 V4 回调写入这些表M002 V4 CP5 已开放查询M002 V4 CP6 已开放普通卡片确认和 S10/S99 ackM002 V4 CP7 已开放复核解阻与复核场景订单归属确认。
- V4 订单任务和卡片 `availability` 已新增 `reviewable`。当前语义:`REVIEW_REQUIRED` 卡如果未被 Basic Information 或前置订单任务阻塞,会返回 `read_only=false``editable=true``confirmable=false``reviewable=true``readonly_reason_code=PROCESSABLE`;前端应调用 `review-resolution`,不要调用普通 `confirm`
- `review-resolution` 请求示例:`{"version":0,"reason":"确认房型映射","confirmed_order_id":"123456","field_overrides":[{"field_pointer":"/business_fields/room_items/0/pms_room_type_code","value":"RM2"}]}``confirmed_order_id` 在订单任务归属未解决时必填;`field_pointer` 必须来自当前卡允许编辑的 `basic_information.*``business_fields.*` 叶子字段,不允许提交来源邮件、路由、`target_order``order_ref`、缺失字段清单、`manual_review`、raw evidence校验诊断字段,也不能替换整个对象 / 数组。
- `review-resolution` 请求示例:`{"version":0,"reason":"确认房型映射","confirmed_order_id":"123456","field_overrides":[{"field_pointer":"/business_fields/room_items/0/pms_room_type_code","value":"RM2"}]}``confirmed_order_id` 在订单任务归属未解决时必填;如果订单任务已经绑定订单且 `target_resolution_status=RESOLVED`,只能不传或传当前同一个订单 ID不能借该接口切换到其它订单。`field_pointer` 必须来自当前卡允许编辑的 `basic_information.*``business_fields.*` 叶子字段;展示 payload 有 `missing_fields[]` 时只提交清单里的 pointer没有显式清单时只提交当前值为 `null` / 空字符串的未解决叶子字段。前端不要提交来源邮件、路由、`target_order``order_ref`、缺失字段清单、`manual_review`、raw evidence校验诊断字段,也不能替换整个对象 / 数组。
- V4 新模型确认口径是不保存后端草稿、卡片最终确认后锁定、技术异常不进入用户可处理卡、当前不生成 OPERA 模拟操作。Basic Information 必须先确认;其它业务卡第一版不强制逐张顺序确认。现有 V3 `draft``confirm``manual-review-resolutions` 和 OPERA 模拟接口仍只代表旧链路能力,不能直接等同 V4 多卡最终接口。
- V4 S10/S99 已采用来源通知模型入库:新 V4 `route_code=S10/S99` 不再挂隐藏技术订单,也不再创建旧 `SOURCE_MESSAGE_ONLY` 任务;对应工作台 / 来源通知详情查询接口和 ack 写接口已开放。旧 `SOURCE_MESSAGE_ONLY` 只读任务仅代表 V3 S10/S99 和旧 S000/S999 兼容数据。
- M002 V3 的结构化 `S10/S99` 入站、40 条 P0.1 路由枚举 / 稳定配置、`UNHANDLED_CURRENT_INTENT``adapter_contract_error` transition 最小落库、任务列表 / 订单时间线 / 任务详情 V3 路由字段和只读诊断块透出、type-known manual review 同卡解阻第一版、typed infrastructure error、P0 fixtures 回归基线和 Parent Group / Cancel Allotment 路由修订均已完成。

View File

@@ -173,9 +173,10 @@ V4 新数据不再提供后端草稿保存。前端可以在页面本地维护
- 用户修正写入 `review_resolution_json``confirmed_payload_json`
- CP7 第一版只校验 JSON Pointer 是否指向当前卡允许编辑字段;目录值必须来自信息系统受控目录的校验放到受控目录 checkpoint。
- 通过校验后卡片直接进入 `CONFIRMED`,不再进入 V3 `READY` 状态。
- `field_overrides[].field_pointer` 必须是当前卡 `display_payload_json` 中允许编辑的 RFC 6901 JSON Pointer第一版只允许 `basic_information.*``business_fields.*` 下已经存在的叶子标量字段,不允许替换对象或数组。
- `field_overrides[].field_pointer` 必须是当前卡 `display_payload_json` 中允许编辑的 RFC 6901 JSON Pointer如果当前卡展示 payload 中存在显式 `missing_fields[]`,只允许提交该清单内的 pointer如果没有显式清单第一版只允许 `basic_information.*``business_fields.*` 下已经存在且值为 `null` / 空字符串的未解决叶子字段,不允许替换对象或数组。
- 来源消息、路由、订单定位关系、诊断、缺失字段清单、`manual_review`、raw evidence 等只读字段不得提交。
- 如果订单任务归属未解决,复核请求必须提交 `confirmed_order_id`;后端按当前订单任务酒店校验该订单存在、非逻辑删除且不是系统隐藏订单。
- 如果订单任务已经有 `order_id``target_resolution_status=RESOLVED`,复核请求不能提交不同的 `confirmed_order_id`,否则返回 `V4_ORDER_REBIND_NOT_ALLOWED`;普通任务任意切换订单继续后置。
- `availability.reviewable=true``card_status=REVIEW_REQUIRED` 时,前端可以展示复核提交入口;普通确认接口仍拒绝 `REVIEW_REQUIRED` 卡。
### 7.4 Basic Information 目录规则
@@ -226,7 +227,7 @@ V4 CP2 只设计复核场景下的订单归属确认,不开放普通任务任
- 订单归属确认必须写业务审计。
- 若确认到其他订单,原临时订单可在无其它任务引用时逻辑删除。
- 已确认锁定卡片不能通过该接口二次迁移订单。
- CP7 第一版只支持在复核解阻请求中提交 `confirmed_order_id` 完成一次性归属确认;不提供普通任务任意切换订单接口
- CP7 第一版只支持在复核解阻请求中提交 `confirmed_order_id` 完成未解决归属的一次性确认;如果订单任务已解析到某个订单且状态为 `RESOLVED`,只能确认同一订单,不能借复核接口切换到其它订单
- 如果确认到的订单下存在更早未完成 V4 订单任务,后端拒绝当前复核提交,避免绕过同订单阻塞规则。
## 9. 同订单阻塞规则
@@ -620,7 +621,8 @@ POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution
- 请求 JSON 必须携带卡片 `version`;可选 `reason` 写入业务审计摘要;`confirmed_order_id` 表示复核场景确认后的本地订单 ID。
- 如果订单任务当前 `order_id=null``target_resolution_status!=RESOLVED``confirmed_order_id` 必填;后端会按订单任务所属酒店查询并校验真实可见订单。
- `field_overrides[]` 每项包含 `field_pointer``value``field_pointer` 只允许指向当前卡展示 payload 中的可编辑业务字段,不允许指向 `source_message``route_code``card_type``target_order``order_ref``missing_fields``manual_review``raw_evidence``validation_errors` 等只读诊断字段。
- 第一版允许的写入容器是 `basic_information``business_fields`只能改已存在的叶子标量或 `null` 字段,不能替换整个对象数组或新增未知字段。
- 第一版允许的写入容器是 `basic_information``business_fields`如果展示 payload 中存在显式 `missing_fields[]`,只允许提交清单中的 pointer否则只能改已存在且值为 `null` / 空字符串的叶子字段,不能修改已有有效值、替换整个对象 / 数组或新增未知字段。
- 如果订单任务已经有 `order_id``target_resolution_status=RESOLVED``confirmed_order_id` 只能为空或等于当前订单 ID提交其它订单 ID 会返回 `V4_ORDER_REBIND_NOT_ALLOWED`
- Basic Information 必须先确认;如果 Basic Information 自身是 `REVIEW_REQUIRED`,允许通过本接口先复核并确认 Basic。
- 解阻过程不改写 `ai_payload_json`;用户修正写入 `review_resolution_json`,最终确认快照写入 `confirmed_payload_json`
- 校验通过后直接 `CONFIRMED`

View File

@@ -54,7 +54,7 @@
| `PUT /api/reservation/tasks/{taskId}/draft` | `FRONTEND_USER` | 第一版未全量强制登录actor 仍待迁移 | 登录 + `RESERVATION_TASK_EDIT` + 酒店访问权 | 写草稿审计可按业务需要记录 |
| `POST /api/reservation/tasks/{taskId}/confirm` | `FRONTEND_USER` | 第一版未全量强制登录actor 仍待迁移 | 登录 + `RESERVATION_TASK_CONFIRM` + 酒店访问权 | 必须写业务审计 |
| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/confirm` | `FRONTEND_USER` | 已实现 M002 V4 CP6强制 Bearer 登录 + `RESERVATION_TASK_CONFIRM` + 订单任务所属酒店访问权 + version 并发校验 | 保持Basic Information 前置确认,确认后卡片锁定,不返回 AI 原始 payload | 必须写业务审计actor 使用当前登录用户 |
| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution` | `FRONTEND_USER` | 已实现 M002 V4 CP7强制 Bearer 登录 + `RESERVATION_MANUAL_REVIEW_RESOLVE` + 订单任务所属酒店访问权 + version 并发校验 | 保持;仅用于 V4 `REVIEW_REQUIRED` 卡,不开放普通任务任意切换订单;字段指针只允许当前卡可编辑业务字段;订单归属未解决时必须提交当前酒店下真实可见订单 ID | 必须写业务审计,记录复核字段指针、复核说明和订单归属确认摘要;不返回或写入 AI 原始 payload |
| `POST /api/reservation/order-tasks/{orderTaskId}/cards/{cardId}/review-resolution` | `FRONTEND_USER` | 已实现 M002 V4 CP7强制 Bearer 登录 + `RESERVATION_MANUAL_REVIEW_RESOLVE` + 订单任务所属酒店访问权 + version 并发校验 | 保持;仅用于 V4 `REVIEW_REQUIRED` 卡,不开放普通任务任意切换订单;字段指针只允许当前卡可编辑业务字段,优先按显式 `missing_fields[]` 或未解决叶子值收口;订单归属未解决时必须提交当前酒店下真实可见订单 ID`RESOLVED` 的订单任务不得换绑不同订单 | 必须写业务审计,记录复核字段指针、复核说明和订单归属确认摘要;不返回或写入 AI 原始 payload |
| `POST /api/reservation/source-notifications/{notificationId}/ack` | `FRONTEND_USER` | 已实现 M002 V4 CP6强制 Bearer 登录 + `RESERVATION_TASK_CONFIRM` + 来源通知所属酒店访问权 + version 并发校验 | 保持;只用于 `route_code=S10/S99` 的 V4 来源通知确认已读 / 已处理,不创建订单、不参与订单阻塞;重复 ack 幂等返回当前状态且不新增审计 | 首次确认必须写业务审计,记录已读 / 已处理确认actor 使用当前登录用户 |
| `POST /api/reservation/tasks/{taskId}/manual-review-conversions` | `FRONTEND_USER` | 第一版已写业务审计,但 actor 待迁移 | 登录 + `RESERVATION_MANUAL_REVIEW_RESOLVE` + 酒店访问权 | 必须写业务审计和原因 |
| `POST /api/reservation/tasks/{taskId}/manual-review-resolutions` | `FRONTEND_USER` | 第一版已写业务审计,但 actor 待迁移 | 登录 + `RESERVATION_MANUAL_REVIEW_RESOLVE` + 酒店访问权 | 必须写业务审计 |