Files
th-hotel-simple/docs/project/requirements/M002-task-field-control-contract-v1.md
2026-07-13 08:50:06 +08:00

252 lines
15 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.

# M002 任务卡字段控件契约 V1
## 文档信息
| 项目 | 内容 |
| --- | --- |
| 文档版本 | 0.1 |
| 日期 | 2026-07-13 |
| 状态 | 当前有效;后端 CP9 第一版已实现;前端待接入 |
| 适用范围 | 任务详情 `fields[]`、保存草稿、最终确认、type-known manual review 同卡解阻、前端字段控件渲染 |
| 不适用范围 | Prompt / Skill 业务裁决、SuperAgent 输出根结构重设计、真实 OPERA / OHIP、PMS / Rate 配置中心真实接入 |
## 1. 文档定位
本文把 `docs/import/20260712/前端字段控件修改说明_给信息系统小伙伴Codex_2026-07-12.md` 中适合本系统当前阶段的字段控件要求,落为项目内可开发契约。
0712 导入文档的方向是正确的:前端不应继续只依赖旧矩阵里的“是否输入 / 是否下拉”列,而应消费后端返回的字段控件契约;同卡人工复核也不应把所有 `missing_fields[]` 都渲染成普通文本输入。
但当前项目还没有 PMS 房型目录、Rate 配置中心、真实 lookup 和真实 OPERA 参数 adapter因此 V1 先做“可执行最小闭环”:
- 后端在任务详情 `fields[]` 中补齐稳定控件元数据。
- 前端只消费后端返回的控件元数据,不自行发明字段、枚举或目录。
- 人工复核使用 `field_pointer` 定位字段,复用同一套控件渲染和校验。
- 用户修正值写入 `review_resolution.field_overrides[]` 和确认 payload不回写 `ai_payload_json`
## 2. 输入资料
| 来源 | 用途 |
| --- | --- |
| `docs/import/20260712/前端字段控件修改说明_给信息系统小伙伴Codex_2026-07-12.md` | 控件类型、编辑边界、只读证据和验收用例来源 |
| `docs/import/20260711/开发交付_P0冻结基线_2026-07-11/01_Adapter_Frontend/任务卡前端字段变更与路由说明_3.0_to_current.md` | 0711 P0 路由、S10/S99、type-known manual review 和 fail-closed 规则 |
| `docs/import/20260712/开发交付_P0_to_P0.1_增量修订说明_给开发Codex_2026-07-11.md` | Parent Group / Cancel Allotment P0.1 修订 |
| `docs/project/requirements/M002-order-task-workflow-v3.md` | 当前 M002 业务主流程权威基线 |
| `docs/project/frontend-backend/backend-to-frontend-notes.md` | 前端接入注意事项 |
## 3. 当前系统现状
当前后端已经具备以下基础:
- `GET /api/reservation/tasks/{taskId}` 返回 `fields[]`
- `fields[]` 已包含 `field_path``field_pointer``legacy_field_path``editable``input_editable``select_editable``date_picker``number_input``file_display``table_editable``enum_options``required_rule``validation_rule` 等旧矩阵字段。
- 0711 P0 房型字段已经第一版迁移到 `room_items[0]` 主路径。
- type-known manual review 已在同一张业务卡上解阻,保存 `review_status``review_resolution.field_overrides[]``confirmed_payload`
- 解阻接口已经支持 `field_pointer`、P0 主 `field_path` 和旧扁平 `field_path`,并校验只能指向当前任务卡可编辑字段。
当前后端 CP9 第一版已经补齐:
- `fields[]` 已显式返回 `control_type``edit_scope``write_target``options_source``raw_readonly``control_hint`
- `fields[]` 是后端按当前任务生效规则过滤后的字段集合,已应用 `visible``result_type``task_type``task_subtype``display_condition`;前端不得自行补齐未返回的完整字段矩阵。
- `room_items[0]` 主路径字段已返回 P0 JSON Pointer 和控件元数据。
- type-known manual review 的 `manual_review.missing_fields[]` 可匹配到对应 `fields[].field_pointer`,缺失字段返回 `edit_scope=manual_review_only``write_target=review_resolution.field_overrides`
- `S10/S99` 源邮件只读通知卡不返回可编辑字段控件。
当前仍有缺口:
- 前端字段渲染器仍主要通过旧矩阵开关推断控件。
- 前端人工复核面板仍把缺失字段统一渲染为普通文本输入。
- PMS 房型目录、Rate 配置中心、lookup 查询和结构化表格编辑还没有真实后端能力。
## 4. 后端 `fields[]` V1 控件契约
后端已在 `ReservationTaskFieldResult` 中新增以下字段,并在 `GET /api/reservation/tasks/{taskId}``fields[]` 中返回。
`fields[]` 的返回口径是“当前任务可展示 / 可编辑字段全集”,不是原始矩阵全集。后端在组装详情时复用保存草稿、最终确认和复核解阻同一套 active definition 规则;如果某个字段没有出现在 `fields[]`,前端应视为当前任务不展示、不校验、不提交。示例:`new_group_block` 不返回 FIT 专属 `case_keys.confirmation_number`,也不返回 Allotment 专属 `extracted_fields.child_room_items[]`;无附件时可以不返回 `attachments`
| 字段 | 类型 | 中文说明 |
| --- | --- | --- |
| `control_type` | string | 前端应使用的控件类型。 |
| `edit_scope` | string | 字段可编辑范围。 |
| `options_source` | string / null | 选项来源。没有选项或暂不接目录时返回 `null``none`。 |
| `write_target` | string | 用户修改值写入目标。 |
| `raw_readonly` | boolean | 是否属于原文、证据或 AI 原始值,必须只读保留。 |
| `control_hint` | string / null | 后端给前端的补充渲染提示,第一版可为空。 |
### 4.1 `control_type`
V1 支持以下枚举:
| 值 | 说明 |
| --- | --- |
| `readonly` | 只读文本、证据、路由、状态或审计字段。 |
| `text` | 普通短文本输入。 |
| `textarea` | 较长业务备注输入。 |
| `number` | 数字输入。 |
| `date` | 酒店本地业务日期输入,格式 `YYYY-MM-DD`。 |
| `select` | 后端返回固定枚举时使用的下拉。 |
| `lookup` | 未来查询当前系统对象或目录的组合框V1 没有真实查询能力时前端可降级为 `text` 或只读提示。 |
| `multiselect` | 多选字段V1 若无选项来源则只读展示。 |
| `structured_table` | 结构化数组 / 表格字段,例如 `before_after[]``room_items[]``fix_charge_items[]``trace_items[]`。V1 未实现表格编辑时只读展示。 |
| `file` | 文件 / 附件展示。 |
| `workflow_state` | `review_status`、解阻动作等流程状态,不作为普通字段保存。 |
旧矩阵列到 V1 控件的默认推导规则:
| 旧矩阵字段 | 推导 |
| --- | --- |
| `file_display=是` | `control_type=file` |
| `table_editable=是``field_path``[]` 结尾 | `control_type=structured_table` |
| `date_picker=是` 或字段名以 `_date` 结尾 | `control_type=date` |
| `number_input=是` 或校验规则包含数字 / 正整数 / 非负 | `control_type=number` |
| `select_editable=是``enum_options` 非空 | `control_type=select` |
| `input_editable=是``editable=是` | `control_type=text` |
| 其他情况 | `control_type=readonly` |
如果字段属于备注、说明、取消原因等长文本,后端可返回 `textarea`。如果字段语义是目标对象定位,例如 `case_keys.group_code``case_keys.confirmation_number`,后端可返回 `lookup`;在没有真实 lookup 接口前,前端不得自行查询数据库或外部系统。
### 4.2 `edit_scope`
V1 支持以下枚举:
| 值 | 说明 |
| --- | --- |
| `never` | 永远只读。 |
| `normal_task` | 普通任务草稿 / 最终确认可编辑。 |
| `manual_review_only` | 仅 type-known manual review 解阻时可编辑。 |
| `normal_and_manual_review` | 普通编辑和同卡复核均可编辑。 |
| `workflow_only` | 只能通过专用流程动作改变,例如复核解阻状态。 |
| `system_only` | 只能由后端系统派生或写入。 |
默认规则:
- `raw_readonly=true` 时必须是 `never``system_only`
- `result_type=manual_review` 且字段由 `manual_review.missing_fields[]` 指向时,返回 `manual_review_only`
- type-known manual review 中其他可编辑业务字段第一版返回 `normal_and_manual_review`,前端仍应优先只渲染 `missing_fields[]` 指向的字段。
- `source_message`、附件、邮件原文、AI 路由字段、`event_type``task_type``task_subtype``route_code``source_event_index`、关系索引、raw evidence 一律 `never`
### 4.3 `write_target`
V1 支持以下枚举:
| 值 | 说明 |
| --- | --- |
| `none` | 不写入用户字段值。 |
| `draft_payload.field_values` | 保存草稿和最终确认写入任务 payload。 |
| `review_resolution.field_overrides` | type-known manual review 解阻写入复核覆盖值。 |
| `draft_payload_and_review_resolution` | 普通编辑和复核都可使用同一字段。 |
| `system_state` | 写入系统状态,不走普通字段 payload。 |
约束:
- `ai_payload_json` 永远不是 `write_target`
- 前端保存草稿和最终确认继续提交 `field_values`;不要按 `write_path` 自己组 OPERA 参数。
- 前端提交复核解阻时继续提交 `field_overrides[]`;优先带 `field_pointer`,可同时带 `field_path`
### 4.4 `options_source`
V1 支持以下值:
| 值 | 说明 |
| --- | --- |
| `static_enum` | 选项来自 `enum_options`。 |
| `active_pms_room_type_catalog` | PMS 房型目录后续接真实目录接口V1 不得由前端硬编码全集。 |
| `rate_code_catalog` | Rate Code 配置中心后续接真实目录接口V1 不得硬编码旧 Excel 全集。 |
| `system_case_lookup` | 当前系统订单 / 任务 / 对象查询,后续接 lookup 接口。 |
| `none` | 无选项来源。 |
| `pending_contract` | 业务路径或枚举尚未冻结,前端应只读或容错展示。 |
如果 `control_type=select``options_source` 不是 `static_enum` 且后端没有返回实际选项,前端不得擅自造选项。可以显示只读值、普通文本兜底,或展示“目录待接入”的状态。
当前后端第一版推导口径:
- `pms_room_type_code` 返回 `options_source=active_pms_room_type_catalog`,同时保留旧矩阵 `enum_options` 作为过渡展示参考;前端不得把它当成真实 PMS 全量目录。
- `rate_code` 返回 `options_source=rate_code_catalog`,真实 Rate Code 配置中心后置。
- `case_keys.*` 返回 `options_source=system_case_lookup`,真实 lookup API 后置。
- 其他普通下拉字段若有 `enum_options`,返回 `options_source=static_enum`
- 目录、lookup 和结构化表格待接入时,后端可通过 `control_hint=catalog_backend_pending``lookup_backend_pending``structured_table_editor_pending` 提醒前端降级。
## 5. 只读和禁止编辑规则
以下字段或字段族必须只读:
- `source_message``source_message_id`、邮件主题、发件人、接收时间、邮件正文、附件引用。
- `message_events[].event_type``event_role``current_or_history``source_event_index`
- `attachments[]``file_references[]``context_used`、QBD sheet / row / highlight / raw evidence。
- `relevant_message_excerpt``text_raw``room_type_raw`、价格 raw marker。
- `manual_review.reason_code``manual_review.visible_reason``blocking_points``conflicting_points``suggested_human_actions``evidence_to_check`
- `route_code``result_type``task_type``task_subtype``system_process_category`
- S10 / S99 / `infrastructure_input_error` / `adapter_contract_error` / `unhandled_current_intent` 的诊断字段。
前端不得通过修改字段控件来切换 `event_type`、业务任务类型、任务 subtype 或 Adapter 路由。跨路由转换若未来需要,必须另行设计专用后端接口和审计契约。
## 6. Type-known manual review 渲染规则
type-known manual review 的页面行为:
```text
manual_review.missing_fields[]
→ 使用 JSON Pointer 匹配任务详情 fields[].field_pointer
→ 读取对应 field 的 control_type / edit_scope / options_source / validation_rule
→ 渲染字段控件
→ 提交 review_resolution.field_overrides[]
→ 后端校验并流转 READY
```
前端要求:
- 只渲染能在 `fields[]` 中匹配到、且后端标记可复核编辑的字段。
- 匹配不到的 pointer 不应临时生成任意输入框,应展示稳定错误或空态,由后端 / 契约修复。
- `field_overrides[]` 优先提交 `field_pointer`;同时提交 `field_path` 时必须使用 `fields[]` 中返回的主路径。
- 当前订单归属确认仍按现有 `confirmed_order_id` 提交V1 只能确认当前任务订单,不开放普通任务任意切换订单。
后端要求:
- `missing_fields[]` 不是 RFC 6901 pointer 或无法映射到可编辑字段时,入站阶段应 fail closed 或解阻阶段返回 `TASK_REVIEW_POINTER_INVALID`
- 复核解阻不得调用通用确认接口绕过审计。
- 解阻成功后写入 `review_resolution``confirmed_payload`、审计和 OPERA 模拟操作,不改写 AI 原始 payload。
## 7. V1 暂不做
- 不接真实 PMS 房型目录接口。
- 不接真实 Rate Code 配置中心。
- 不实现通用 lookup API。
- 不实现所有结构化表格的可编辑 UI。
- 不做普通任务任意切换订单。
- 不做真实 OPERA / OHIP 参数映射。
- 不允许前端根据旧 Excel 自行硬编码完整枚举全集。
## 8. 开发顺序
### 8.1 文档 checkpoint
已完成:已落本文档和相关索引。
### 8.2 后端 checkpoint
已完成第一版:
- 扩展 `ReservationTaskFieldResult`,返回字段控件契约元数据。
- 基于现有矩阵列推导 `control_type``edit_scope``write_target``options_source``raw_readonly`
- 更新 `GET /api/reservation/tasks/{taskId}` 测试,覆盖 room_items、只读证据、S10/S99、type-known manual review。
- 保留 `manual-review-resolutions` 的可编辑 pointer 校验,非法或只读 pointer 仍返回 `TASK_REVIEW_POINTER_INVALID`
- 更新前后端沟通文档中的接口字段说明。
### 8.3 前端 checkpoint
前端后续建议:
- 扩展 `ReservationTaskFieldResult` TypeScript 类型。
- 更新字段渲染器,优先按 `control_type` 渲染,旧矩阵开关只作为兼容兜底。
- 人工复核面板复用同一套字段控件,不再统一使用 text input。
- `options_source=pending_contract` 或目录未接入时 fail closed / 只读 / 明确提示,不硬编码业务目录。
- 补充字段渲染、复核提交、只读诊断卡、S10/S99 的前端测试。
## 9. 验收标准
- 任务详情 `fields[]` 能告诉前端“显示什么控件、何时可编辑、写到哪里、选项从哪来”。
- 前端可以在不理解业务矩阵中文说明的情况下渲染基本字段控件。
- 同卡人工复核缺失字段按 `field_pointer` 复用字段控件,并提交 `field_overrides[]`
- raw evidence、source message、route、关系索引和审计字段不可编辑。
- 前端不硬编码 PMS 房型目录、Rate Code 全集或 P1/P2 未冻结枚举。
- 后端仍负责最终校验、审计、payload 写入和状态流转。