57 KiB
后端提醒前端注意事项
1. 文档定位
本文记录后端侧提醒前端开发时必须注意的项目规范、业务规则、接口边界和安全要求。当前内容服务于 Reservation 任务详情、订单详情、任务列表、S10/S99 源邮件只读通知卡、旧 S000/S999 兼容展示、历史 Message Notification、系统管理后台等第一版页面。
2. 项目开发注意事项
- 前端只调用本项目后端接口,不直接调用 SuperAgent、AgentBus、OPERA、OHIP 或数据库。
- API 调用应统一放在前端
src/services,页面组件不要直接拼接后端 URL。 - 业务判断必须使用后端返回的稳定 code,不使用中文或英文展示文案做判断。
- 后端返回的时间点字段统一是带
Z的 ISO 8601 UTC 时间,例如created_at、updated_at、received_at、last_updated_at;前端展示时再按用户或酒店时区格式化。 - 入住日期、离店日期、酒店营业日属于酒店本地业务日期,不要按 UTC 时间点自动换算日期。
- 详细时间设计参考
docs/project/backend-time-design.md,不要把数据库 UTC 时间直接当酒店当地时间展示。 - 前端不得保存或传递后端 Secret、replay access key、Provider API Key、Oracle 凭证、AgentBus Token。
- 后端数据库 ID 未来应尽量以字符串形式给前端,避免 JavaScript 长整型精度问题;如果当前接口仍返回数字,前端不要自行做数学运算。
- 接口字段发生变化前,需要先更新本目录沟通文档或对应需求文档。
- 前端接口新增或字段变更时,后端需同步更新
docs/project/security-access-control-boundary.md,前端也应按该文档区分普通业务、系统管理、Debug 和第三方接口。 - 前端页面不得把 Debug、Demo、Replay、Probe 等系统调试接口当成普通用户能力;这类入口需要环境开关和专门权限。
3. 字段来源注意事项
docs/import/20260711/开发交付_P0冻结基线_2026-07-11/01_Adapter_Frontend/任务卡前端字段变更与路由说明_3.0_to_current.md是 0711 P0 前端 / Adapter 路由说明,覆盖 S10/S99、type-known manual review 和 fail-closed 口径;其中 Parent split / 42 路由口径已被 0712 P0.1 覆盖。docs/project/requirements/M002-v3-p0.1-parent-group-routing-update.md是当前 Parent Group / Allotment 路由修订说明:前端应按 40 路由口径处理 Parent split。docs/import/20260712/前端字段控件修改说明_给信息系统小伙伴Codex_2026-07-12.md是前端字段控件、人工复核编辑和只读证据的外部输入资料;本项目开发以docs/project/requirements/M002-task-field-control-contract-v1.md的落地口径为准。docs/project/requirements/M002-task-field-control-contract-v1.md是后端已扩展fields[]和前端后续控件渲染的字段控件契约 V1。docs/import/20260711/开发交付_P0冻结基线_2026-07-11/01_Adapter_Frontend/任务卡前端字段变更说明_3.0_to_当前版_2026-07-10.xlsx是当前前端展示 / 编辑白名单和三元组路由表。docs/import/20260708/任务卡前端展示字段表 3.0.xlsx是历史前端展示 / 编辑白名单,已被 0711 P0 冻结基线承接。docs/import/20260706/任务卡展示编辑矩阵.xlsx是后端校验、最终确认写入、OPERA 映射和展示条件的完整规则来源。- 前端不要直接把整个旧
ai_task_results[]或 V3message_events[]渲染成表单,只展示白名单允许的字段。 - 如果 3.0 白名单与旧矩阵冲突,应记录为前后端待确认问题,不由前端单方面放宽必填、枚举或校验规则。
4. 业务规则注意事项
- 任务详情页里,保存草稿和最终确认是两个独立动作,不能合并。
- 用户可以修改任务字段内容;最终确认后,后端使用
confirmed_payload_json作为 OPERA 模拟输入来源。 - 同一订单下,前置任务未结束时,后续任务只能查看,不能编辑、确认或执行 OPERA 模拟操作。
- 任务状态
FAILED第一版视为结束状态,不阻塞后续任务;但失败的 OPERA 操作不能跳过,必须展示失败原因并允许重试。 - M002 V3 新入口采用结构化
S10/S99:S10表示未匹配当前支持的业务事件,S99表示输入不足或无法形成业务素材包;旧S000/S999继续按历史数据兼容展示。 S10/S99后端会创建只读源邮件通知卡,任务列表可见,订单列表不可见;当前代码中的旧SOURCE_MESSAGE_ONLY任务仍按同一只读语义展示。- 源邮件只读通知卡不允许编辑、确认、人工转换订单、执行 OPERA 或重试 OPERA;不参与订单任务执行队列,不阻塞其他任务,也不被其他任务阻塞。
- type-known manual review 已支持同卡复核解阻第一版:应展示为原业务任务卡的复核模式,不应统一展示成 Fallback。只有业务类型或 subtype 本身未知时才进入 Fallback。
- 复核场景下允许用户确认订单归属;当前第一版只允许确认当前任务所属订单,不等于开放普通任务任意切换订单。
- 历史 Message Notification 挂临时订单,只读展示,不参与订单任务执行队列,不阻塞其他任务,也不被其他任务阻塞。
- Fallback / manual_review 转为 New / Update / Cancel 时需要展示审计轨迹;登录权限底座已提供,具体业务审计 actor 迁移仍后置。
- 普通任务切换订单接口已确认后置,前端第一版不要把普通任务拖拽或切换订单做成可提交能力。
5. 当前前端可用接口注意事项
| 接口 | 用途 | 前端注意 |
|---|---|---|
POST /api/auth/login |
用户名密码登录 | 成功后返回 access_token、当前用户、可访问酒店、权限码和可见菜单;token 只放 sessionStorage,不要放 localStorage、URL、日志或错误上报。 |
GET /api/auth/me |
恢复当前登录态 | 前端启动后带 Authorization: Bearer <access_token> 调用;401 时清理 token 并进入登录页。 |
POST /api/auth/logout |
登出当前 session | 带 Authorization: Bearer <access_token>;成功后前端必须清理本地 token 和当前用户上下文。 |
GET /api/reservation/orders |
查询订单列表 | 必须带 Authorization: Bearer <access_token>,需要 RESERVATION_ORDER_READ;默认返回全部订单状态;按后端维护的订单最近业务活动时间倒序,当前落库字段为 workflow_reservation_order.latest_activity_at,前端不要自行重排;open_task_count 排除 COMPLETED 和 FAILED;隐藏技术订单不返回,因此 S10/S99 和旧 S000/S999 不会在订单列表形成订单。 |
GET /api/reservation/tasks |
查询任务列表 / 工作台 | 必须带 Bearer token,需要 RESERVATION_TASK_READ;未传 order_id 时按来源消息接收时间倒序,传 order_id 时按同订单队列顺序正序;用 can_process 和 readonly_reason_code 控制入口按钮;列表不返回 AI 原始 payload、邮件正文或附件 URL;已返回来源邮件会话摘要字段,并支持 order_status 按任务所属订单状态筛选;旧 S000/S999 和新 S10/S99 都以 task_type=SOURCE_MESSAGE_ONLY 只读任务返回,列表已透出 result_type、ai_task_type、route_code、system_process_category。 |
GET /api/reservation/orders/{orderId} |
查询订单详情与任务时间线 | 必须带 Bearer token,需要 RESERVATION_ORDER_READ,后端按订单所属酒店做访问校验;include_tasks=false 可只取订单摘要;时间线按后端队列顺序返回,前端不要自行按创建时间重排;tasks[] 已返回来源邮件会话摘要字段和 V3 路由字段;隐藏技术订单详情不可作为普通订单页打开。 |
GET /api/reservation/tasks/{taskId} |
查询任务详情 | 必须带 Bearer token,需要 RESERVATION_TASK_READ,后端按任务所属酒店做访问校验;以返回的可处理状态和只读原因控制按钮,不只看任务状态;fields[] 已包含 P0 字段元数据;源邮件只读通知卡字段列表和 OPERA 操作列表为空;结构化 S10/S99 通过 source_message_only_result.agent_assessment、notification、manual_review 展示;普通业务任务可通过 adapter_contract_errors[] 和 unhandled_intents[] 查看同批次未建任务的诊断信息;type-known manual review 会返回顶层 review_status、review_resolution 和 manual_review。 |
PUT /api/reservation/tasks/{taskId}/draft |
保存任务草稿 | 只保存草稿,不代表用户最终确认。 |
POST /api/reservation/tasks/{taskId}/confirm |
最终确认任务 | 后端会做第一版字段校验,通过后进入 READY。 |
POST /api/reservation/tasks/{taskId}/manual-review-conversions |
Fallback 人工转换 | 只用于 manual_review / fallback,不用于普通任务切换订单。 |
POST /api/reservation/tasks/{taskId}/manual-review-resolutions |
type-known manual review 同卡复核解阻 | 只用于已知业务类型的 result_type=manual_review 任务;提交 field_overrides[] 和当前订单归属确认,通过后进入 READY 并生成两条 OPERA 模拟操作。 |
POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/execute |
执行 OPERA 模拟操作 | 当前是模拟,不调用真实 OPERA。 |
POST /api/reservation/tasks/{taskId}/opera-operations/{operationId}/retry |
重试失败 OPERA 模拟操作 | 重试会追加 attempt 历史,前端不要覆盖旧失败记录。 |
GET /api/reservation/tasks/{taskId}/audits |
查询任务审计流水 | 必须带 Bearer token,需要 RESERVATION_AUDIT_READ,后端按任务所属酒店做访问校验;用于展示人工确认、转换、模拟操作等轨迹。 |
GET /api/source-messages |
查询来源消息安全摘要 | 必须带 Bearer token,需要 SOURCE_MESSAGE_READ;列表不返回邮件正文、HTML、附件 URL 或原始 payload;查询参数以 hotel_id、external_message_id、external_conversation_id、page_num、page_size 为准,后端暂兼容早期 camelCase 参数。 |
GET /api/source-messages/{id} |
查询来源消息安全详情 | 必须带 Bearer token,需要 SOURCE_MESSAGE_READ,后端按消息所属酒店做访问校验;只用于安全摘要详情。 |
GET /api/source-messages/{id}/original |
读取来源消息原文 | 必须带 Bearer token,需要同时拥有 SOURCE_MESSAGE_READ 和 SOURCE_MESSAGE_ORIGINAL_READ;后端按消息所属酒店做访问校验;返回 HTML 时前端展示前必须 sanitize。 |
GET /api/source-messages/{sourceMessageId}/conversation |
读取邮件会话详情 | 必须带 Bearer token,需要同时拥有 SOURCE_MESSAGE_READ 和 SOURCE_MESSAGE_ORIGINAL_READ;返回同一外部会话全部邮件的完整 text/html、html_body_sanitized、附件外链、内联图片和关联订单 / 任务摘要;前端不传原文读取 key,展示 HTML 时优先使用 html_body_sanitized。 |
POST /api/system/debug/eml-superagent-runs |
Debug 页面上传 .eml 并调用 SuperAgent |
仅 dev/test 受控调试使用;会写入 SourceMessage Inbox,但不创建订单和任务。 |
GET/POST/PUT /api/admin/users... |
系统管理用户维护 | 需要 Bearer token 和 SYSTEM_USER_MANAGE;用户 ID 返回字符串;禁用用户会撤销其 ACTIVE session。 |
GET/POST/PUT /api/admin/roles... |
系统管理角色权限维护 | 需要 SYSTEM_ROLE_MANAGE;内置角色只读,自定义角色可新增、编辑和分配权限。 |
GET /api/admin/permissions |
权限码只读列表 | 需要 SYSTEM_ROLE_MANAGE;前端只展示和选择已有权限码,不自行造权限码。 |
GET/POST/PUT /api/admin/menus... |
系统管理菜单维护 | 需要 SYSTEM_MENU_MANAGE;允许保存未知路由,前端必须有未知路由兜底页;已提供完整菜单树查询和批量树排序保存。 |
GET/POST/PUT /api/admin/hotels... |
系统管理酒店维护 | 需要 HOTEL_MANAGE;新增酒店默认 DISABLED,单酒店阶段不能启用第二家 ACTIVE。 |
GET /api/admin/audits |
系统管理操作审计 | 需要 SYSTEM_ADMIN_CONSOLE_ACCESS;用于查看管理后台写操作审计,不包含密码、token、secret。 |
POST /api/reservation/rooming-lists/generations |
生成 Rooming List Excel | 必须带 Bearer token,需要 RESERVATION_ROOMING_LIST_GENERATE;请求为 multipart/form-data,成功后直接返回 .xlsx 文件流,前端按 Blob 下载处理。 |
5.1 本轮新增 / 修改接口说明
本轮后端新增或补齐了以下前端 P0 查询能力。前端后续开发时,应优先以本节作为接入口径。
| 接口 | 本轮变化 | 前端接入注意 |
|---|---|---|
GET /api/reservation/orders |
新增订单列表接口。 | order_status 不传时默认查询全部订单状态;page_num 从 1 开始;page_size 后端有最大值保护;open_task_count 排除 COMPLETED 和 FAILED;next_processable_task_id 为空表示当前没有可继续处理的任务。 |
GET /api/reservation/tasks |
补齐来源邮件会话摘要字段,并新增 order_status 查询参数。 |
order_status 按任务所属订单状态过滤,支持 TEMPORARY、ACTIVE、ENDED、LOGIC_DELETED;列表仍然只返回安全摘要,不返回正文、HTML、附件 URL 或 AI 原始 payload;点击邮件入口时使用 source_message_id 调会话详情。 |
GET /api/reservation/orders/{orderId} |
补齐 tasks[] 每条任务的来源邮件会话摘要字段。 |
include_tasks=false 可只取订单摘要;时间线顺序由后端按订单队列返回,前端不要自行按创建时间重排。include_source_summary 第一版不作为前端裁剪字段的强约束,前端暂不要依赖它减少返回字段。 |
GET /api/reservation/tasks/{taskId} |
补齐顶层来源邮件字段,并扩展 fields[] 元数据。 |
顶层来源字段用于打开邮件会话;fields[] 中的 result_type、task_type、task_subtype、default_value_source 用于前端字段分组、调试和白名单对齐。 |
GET /api/source-messages/{sourceMessageId}/conversation |
新增邮件会话详情接口,并补齐 html_body_sanitized / html_render_mode。 |
当前唯一推荐路径是这个接口;前端渲染邮件 HTML 时优先使用 html_body_sanitized;不要调用历史讨论过的 /api/source-message-conversations/{externalConversationId}。 |
POST /api/system/debug/eml-superagent-runs |
新增 Debug EML 上传到 SuperAgent 调试接口,并补齐独立 Debug 外部消息 ID、原始 Message-ID 保留、安全 HTML 字段和入口通知识别。 | 只用于调试页面;请求为 multipart/form-data;必须传 X-TH-Hotel-Debug-Upload-Key,但该 key 不能写进前端源码、构建产物、URL、localStorage 或错误上报;SuperAgent 返回旧 S000/S999 或新 S10/S99 入口通知时都不应被前端视为 JSON 解析失败。 |
酒店上下文注意:Reservation 列表、订单详情、任务列表和 Debug EML 上传的 hotel_id 第一版都是可选参数。对已收口的 Reservation / SourceMessage 只读接口,前端必须先登录并带 Bearer token;不传 hotel_id 时后端按当前登录用户默认酒店或对象所属酒店校验,传了当前选中酒店时后端会校验该酒店是否可访问。Debug EML 仍按调试入口规则受控,不属于本轮登录权限收口范围。
5.2 登录权限接入注意
后端已提供 M003 登录和权限底座第一版接口:
POST /api/auth/login
GET /api/auth/me
POST /api/auth/logout
前端注意:
- 登录成功后只把
access_token保存到sessionStorage;刷新同一浏览器会话可恢复,关闭浏览器后需要重新登录。 - 所有需要登录态的后端请求使用
Authorization: Bearer <access_token>。 - 当前后端已强制拦截第一批 Reservation / SourceMessage 只读接口:任务列表、订单列表、订单详情、任务详情、任务审计列表、SourceMessage 摘要列表和摘要详情。调用这些接口必须带 Bearer token。
- 第一批只读接口权限码分别是:
RESERVATION_TASK_READ、RESERVATION_ORDER_READ、RESERVATION_AUDIT_READ、SOURCE_MESSAGE_READ。前端菜单、按钮和路由守卫应使用/api/auth/me返回的permissions[]与menus[]。 - 后端会按当前登录用户的可访问酒店集合做隔离;显式传
hotel_id时会校验该酒店是否可访问,按orderId、taskId、sourceMessageId定位的详情接口会反查对象实际所属酒店并校验访问权。 - 邮件原文 / conversation 完整正文接口已完成权限收口,必须带 Bearer token 且同时需要
SOURCE_MESSAGE_READ和SOURCE_MESSAGE_ORIGINAL_READ;Reservation 写操作、Debug / Demo / Replay / Probe 等接口仍按../security-access-control-boundary.md的分阶段计划继续收口。 /api/auth/me返回user、default_hotel_id、hotels[]、permissions[]、menus[];菜单入口应优先使用menus[],不要继续硬编码订单列表、任务队列、Debug EML。menus[]只包含可见菜单;订单详情、任务详情和邮件会话详情是隐藏详情路由,不会作为菜单项返回。DEBUG_EML_SUPERAGENT菜单第一版只授予SYSTEM_ADMIN;这只表示页面入口是否可见,不代表后端会把X-TH-Hotel-Debug-Upload-Key下发给前端。user.id是字符串;前端不要把任何后端 ID 转成 JavaScript number。- 登录失败统一显示用户名或密码错误,不要根据错误文案推断账号是否存在或是否禁用。
- 401 的
AUTH_TOKEN_REQUIRED/AUTH_SESSION_INVALID应统一走清理 token、回登录页的逻辑。 - 403 的
FRONTEND_PERMISSION_DENIED表示当前用户没有对应业务权限;HOTEL_ACCESS_DENIED表示用户无权访问目标酒店或对象所属酒店,前端应展示无权限状态,不要重试或静默降级为 404。
5.3 来源邮件会话字段说明
任务列表、订单详情任务时间线、任务详情顶层会返回以下来源邮件字段:
| 字段 | 说明 | 前端使用方式 |
|---|---|---|
source_message_id |
本系统内部 SourceMessage Inbox ID。 | 打开邮件会话详情时作为路径参数传入 /api/source-messages/{sourceMessageId}/conversation。 |
source_subject |
来源邮件主题安全摘要。 | 用于列表或任务详情标题旁展示,不代表完整邮件主题一定无敏感信息。 |
source_sender_summary |
来源发件人展示值,当前不打码。 | 用于辅助用户判断邮件来源。 |
source_received_at |
邮件来源接收时间,UTC;优先取 AgentBus payload received_at,缺失时使用本系统接收时间。 |
前端展示时按用户或酒店时区格式化。 |
external_conversation_id |
外部邮件会话 ID。 | 仅用于展示或调试,不作为当前会话详情接口路径参数。 |
conversation_message_count |
同一外部会话下的邮件数量。 | 用于提示用户打开的是整段会话,不是单封邮件。 |
5.4 邮件会话详情接入注意
GET /api/source-messages/{sourceMessageId}/conversation只接收路径参数sourceMessageId;第一版不接收hotelId、includeBody、includeRelated;请求必须带Authorization: Bearer <access_token>,且当前用户需要同时拥有SOURCE_MESSAGE_READ和SOURCE_MESSAGE_ORIGINAL_READ。- Reservation 列表、任务列表和订单详情默认不需要前端传
hotel_id;如果前端已经接入酒店选择器,可以把当前选中酒店作为可选hotel_id传给后端。任务详情、任务写操作和邮件会话详情当前仍按对象 ID 定位,不接收该参数。 - 后端会根据
sourceMessageId定位external_conversation_id,并返回同一会话下全部邮件;如果来源消息没有外部会话 ID,会降级返回当前单封邮件。 messages[]按邮件来源接收时间正序返回,前端不要重新按创建时间或任务时间排序。- 返回内容包含完整
text_body、html_body、inline_images[]、attachments[]、related_orders[]、related_tasks[]。 html_body是原始 HTML 兼容字段;html_body_sanitized是后端第一版清洗结果,已移除脚本标签、事件属性和危险协议链接。前端生产展示必须优先使用html_body_sanitized,并可用html_render_mode=SANITIZED_HTML判断渲染模式。- 第一版仅处理 HTML 内容安全;
inline_images[]和attachments[]的externalUrl来自本系统 OSS 服务,暂不做额外拦截,但前端仍不得写入普通日志、错误上报、localStorage 或 URL query。 - 会话详情接口由后端内部写原文读取审计,actor 使用当前登录用户稳定 ID;前端不传
X-TH-Hotel-Source-Original-Read-Key、X-TH-Hotel-Actor或X-TH-Hotel-Access-Scene。 - 会话详情外层字段主要是 snake_case,但媒体对象沿用原文读取接口字段,当前是
mediaType、fileName、contentType、sizeBytes、externalUrl、externalMediaId这种 camelCase,前端类型定义需要单独处理。
5.5 订单列表接入注意
GET /api/reservation/orders默认返回全部订单状态,包括TEMPORARY、ACTIVE、ENDED、LOGIC_DELETED。keyword会匹配订单业务号、临时订单号、展示名、订单状态,也会匹配来源消息安全摘要命中的 SourceMessage ID;前端可以用邮件主题、外部消息 ID 或会话 ID 辅助查订单。open_task_count只统计未关闭任务,排除COMPLETED和FAILED。next_processable_task_id是后端按同订单队列实时计算出的下一条可处理任务;前端可以用它做“继续处理”入口。display_order_key是前端优先展示的订单业务号或临时订单号;group_code和confirmation_number只有在当前订单业务号类型匹配时返回。- 订单 ID、任务 ID、SourceMessage ID 在这些前端接口中按字符串返回,前端不要转换成 JavaScript number。
- 当前 V3 / 过渡实现中,源邮件只读通知卡背后有隐藏技术订单用于满足后端任务外键,但订单列表不会返回该订单;任务列表中该类任务的
display_order_key、temporary_order_no、group_code、confirmation_number可能为空,前端不要因此隐藏整条任务。V4 S10 目标模型已改为独立来源通知,不再挂隐藏技术订单。 - 当前前端已按
SOURCE_MESSAGE_ONLY展示旧 S000/S999;后端回调已支持结构化route_code=S10/S99、result_type=source_message_review_notification的新入口通知,并继续只在任务列表和任务详情提供只读查看入口;INFORMATIONAL_MESSAGE仅作为历史 Message Notification 兼容路径保留。 - 任务列表里旧
task_type=SOURCE_MESSAGE_ONLY、task_subtype=S000/S999或新task_subtype=S10/S99的记录只展示邮件来源和 SuperAgent 入口结果,不展示处理按钮。 - 任务详情里
source_message_only_result仅对SOURCE_MESSAGE_ONLY返回,包含entry_result_code、entry_result_meaning、entry_result_description、entry_result_source_message_id、result_type、route_code、agent_assessment、notification、manual_review和raw_answer;普通业务任务该字段为空。 - 任务列表、订单任务时间线和任务详情顶层已透出
result_type、ai_task_type、route_code、system_process_category。前端展示任务卡标题和标签时优先用这些稳定 code,不要只靠旧task_type判断。 - P0.1 后,Parent split 父事件不再是独立 Parent Cancel Booking 卡;前端应展示为
Parent Group / Cancel Allotment / cancel_allotment_control_block。route_code=R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_NORMAL是普通业务卡,route_code=R08_CANCEL_ALLOTMENT_CONTROL_BLOCK_REVIEW是同卡人工复核业务卡,不应展示成adapter_contract_error。linked_parent_release_after_child_split只作为关系字段或详情信息,不作为任务 subtype 筛选项。 manual_review.reason_code=target_object_unclear时,前端需要在任务详情展示manual_review.visible_reason、missing_fields、blocking_points、conflicting_points、suggested_human_actions、evidence_to_check,并展示context_used.parent_identity_candidates[]辅助确认 Parent Group identity。当前前端已兼容顶层context_used.parent_identity_candidates[]或manual_review.context_used.parent_identity_candidates[];若后端 DTO 不透出 candidates,页面会显示候选空态。Cancel Allotment / cancel_allotment_control_block第一版复用旧Cancel Booking字段矩阵。后端在确认和复核解阻时会派生extracted_fields.cancel_object_type=allotment_control_block,并接受extracted_fields.cancel_scope=entire_allotment_control_block;前端不需要为了这两个 P0.1 系统字段额外阻塞人工复核提交。- P0.1 的“40 条路由”表示当前合法 route definition 数量;
route_code保持历史稳定且不连续重编号,因此R41_FALLBACK_BUSINESS_EVENT_REVIEW和R42_UNHANDLED_CURRENT_INTENT仍是合法展示 code。 adapter_contract_errors[]和unhandled_intents[]只在任务详情返回,表示同一 SuperAgent 入站批次中没有生成业务任务的诊断块;前端只读展示并提供来源邮件入口,不显示保存、确认、执行或重试按钮。
5.5.1 Type-known manual review 同卡复核解阻接入注意
result_type=manual_review且system_task_type不是MANUAL_REVIEW时,前端应在原业务任务卡上展示复核模式,不要跳到 Fallback 转换页面。- 任务详情顶层返回
review_status。PENDING表示等待用户补字段或确认订单归属;RESOLVED表示同卡复核已解阻。 - 任务详情顶层
manual_review返回 SuperAgent 原始复核原因、缺失字段、阻塞点和建议动作,前端只读展示;不要把它当成可编辑表单直接提交。 - 解阻接口使用
POST /api/reservation/tasks/{taskId}/manual-review-resolutions。请求体:
{
"confirmed_order_id": "20001",
"reason": "确认 PMS 房型代码后解阻。",
"field_overrides": [
{
"field_pointer": "/extracted_fields/room_items/0/pms_room_type_code",
"value": "RM3"
}
]
}
field_pointer必须是 RFC 6901 JSON Pointer,并且只能指向当前任务卡可编辑字段;后端会映射到矩阵field_path。非法或只读字段会返回TASK_REVIEW_POINTER_INVALID。- 复核解阻也可以提交
field_path,支持 P0 主路径和旧扁平路径;如果同时提交field_pointer和field_path,两者必须指向同一个字段。前端新页面优先用任务详情fields[].field_pointer,无法方便处理 JSON Pointer 时可用fields[].field_path。 - Parent / Allotment 场景中,SuperAgent 可能在
manual_review.missing_fields[]同时返回/case_keys/group_code和/case_keys/block_code。本系统第一版任务卡只暴露case_keys.group_code,后端复核解阻会把/case_keys/block_code视为同一业务字段的输入侧别名;前端按fields[]渲染并提交/case_keys/group_code即可,不需要额外造block_code输入框。 - 0711 P0 的房型字段主路径已迁移到
room_items[0]。任务详情fields[]中,房量、房型原文、PMS 房型代码分别返回:field_path=extracted_fields.room_items.0.room_quantity,field_pointer=/extracted_fields/room_items/0/room_quantityfield_path=extracted_fields.room_items.0.room_type_raw,field_pointer=/extracted_fields/room_items/0/room_type_rawfield_path=extracted_fields.room_items.0.pms_room_type_code,field_pointer=/extracted_fields/room_items/0/pms_room_type_code
legacy_field_path仅用于前端过渡显示旧扁平字段;新页面保存草稿、最终确认和复核解阻应优先提交field_pointer或 P0 主field_path。- 后端仍兼容旧提交 key:
extracted_fields.room_quantity、extracted_fields.room_type、extracted_fields.pms_room_type_code;同卡复核也兼容旧field_path/ 旧 pointer。响应会归一化到 P0 主field_path;当只提交field_path时,响应里的field_pointer使用 P0 主 JSON Pointer。confirmed_payload.legacy_field_values/draft_payload.legacy_field_values只供旧前端回显,不作为新逻辑判断依据。 - 当前第一版只支持
room_items[0];/extracted_fields/room_items/1/...或更大下标不会自动落到 0。 - 同一次请求不能重复提交同一字段;重复
field_pointer或重复映射到同一field_path会返回TASK_REVIEW_POINTER_DUPLICATE。 confirmed_order_id第一版必须等于当前任务的order_id;如果前端需要选择其他订单,仍属于后续“复核场景订单归属选择”细化,不要复用普通任务切换订单能力。- 解阻成功后返回
task_status=READY、review_status=RESOLVED、review_resolution.field_overrides[]、confirmed_payload和两条opera_operations[]。前端应刷新任务详情并显示 OPERA 模拟操作入口。 - 解阻过程不改写
ai_payload_json;用户修正值保存在review_resolution、confirmed_payload.field_values和confirmed_payload.effective_payload中。effective_payload是后端第一版嵌套结构,后续真实 OPERA 参数仍会在 OPERA 层重新组装。 - 历史
field_contract_version=code-v1的任务卡如果已经有draft_payload_json或confirmed_payload_json,后端迁移不会强行改成20260711-p0。前端读取历史任务时,如果看到旧版本,应优先使用legacy_field_path/legacy_field_values做过渡回显;新保存或新确认后再以 P0 主路径为准。 review_resolution.resolved_at是 UTCZ时间点。- type-known manual review 不允许调用通用
POST /api/reservation/tasks/{taskId}/confirm;前端必须使用本节解阻接口,否则后端返回TASK_REVIEW_RESOLUTION_REQUIRED。
5.6 前端联调演示数据 seed 接口
后端提供一个受控的 dev/test 演示数据入口,方便前端在空库或本地环境快速看到页面效果。
POST /api/system/reservation/demo-data
Header: X-TH-Hotel-Demo-Data-Key: <本地演示数据访问口令>
Content-Type: application/json
{
"run_label": "frontend-smoke"
}
启用方式:
- dev profile 默认开启;test 默认关闭,需要后端环境显式设置
reservation.demo-data.enabled=true或环境变量RESERVATION_TEST_DEMO_DATA_ENABLED=true。 - 必须配置
reservation.demo-data.access-key;dev 优先使用RESERVATION_DEV_DEMO_DATA_ACCESS_KEY,test 优先使用RESERVATION_TEST_DEMO_DATA_ACCESS_KEY,旧通用变量RESERVATION_DEMO_DATA_ACCESS_KEY仅作为兼容兜底。 - 该接口只用于 dev/test 联调,不允许放进生产普通页面,也不要把访问口令写进前端仓库、浏览器环境变量或构建产物。
返回内容:
demo_run_id:本次 seed 的唯一关键词,可用于任务列表 / 订单列表搜索。source_messages[]:本次生成的 SourceMessage ID、外部消息 ID 和会话 ID。orders[]:本次生成的订单 ID、订单状态和展示键。tasks[]:本次生成的任务 ID、任务类型、任务 subtype 和任务状态。entrypoints:可直接访问的后端查询入口,包括任务列表、订单列表、队列订单详情、失败任务详情和邮件会话详情。
当前 seed 覆盖的页面效果:
- 同订单前置任务未完成,后续任务只读不可处理。
- 已完成 New Booking 任务和两条 OPERA 模拟成功记录。
- OPERA 模拟失败任务,可在任务详情看到失败 attempt 和重试入口。
- Fallback / manual_review 任务。
- 历史 Message Notification 只读任务;旧 S000/S999 和新 S10/S99 特殊只读任务可通过 SuperAgent 回调补充,前端 fixture 已补 S10 和同卡人工复核最小样例。
- 同一邮件会话下多封邮件、完整 HTML、附件外链和内联图片外链。
5.7 任务详情字段元数据接入注意
- M002 V3 CP9 后,
GET /api/reservation/tasks/{taskId}的fields[]是后端已经按visible、result_type、task_type、task_subtype和display_condition过滤后的当前任务生效字段集合。前端必须直接以fields[]为权威列表渲染、校验和提交,不再按完整字段矩阵自行补齐后端未返回的字段。 - 后端未返回的字段应视为“当前任务不展示 / 不可提交”,不是接口错误。例如
new_group_block不再返回 FIT 专属case_keys.confirmation_number,无附件时也可能不返回attachments字段;前端不得为了旧矩阵完整性临时合成这些字段。 - 保存草稿、最终确认和同卡人工复核解阻只允许从当前
fields[]中选择字段提交。manual_review.missing_fields[]如果指向的字段没有出现在当前fields[],前端只展示“当前字段后端未开放编辑”,不要自行构造field_pointer或field_path。 fields[]第一版服务于任务详情动态展示,字段来源与白名单规则后续以docs/import/20260711/开发交付_P0冻结基线_2026-07-11/01_Adapter_Frontend/任务卡前端字段变更说明_3.0_to_当前版_2026-07-10.xlsx和同目录路由说明为准;当前代码中仍有 20260708 白名单兼容口径。result_type、task_type、task_subtype、default_value_source已透出给前端,用于和最新前端白名单对齐。- 后端校验、最终确认写入、OPERA 映射和展示条件仍以
docs/import/20260706/任务卡展示编辑矩阵.xlsx为完整规则来源。 - 前端保存草稿时不要自行按
write_path重组 OPERA 参数;第一版按任务详情返回的字段和值提交即可,真实 OPERA 参数组装后续由后端 adapter / 转换层处理。 - 任务详情页控制按钮时以
availability.editable、availability.confirmable、availability.executable、availability.read_only和availability.blocked为准;can_process和readonly_reason_code只出现在任务列表 / 订单时间线摘要里。
5.7.1 字段控件契约 V1 接入注意
后端已按 docs/project/requirements/M002-task-field-control-contract-v1.md 返回字段控件契约 V1。前端接入时注意:
- 任务详情
fields[]已新增control_type、edit_scope、write_target、options_source、raw_readonly、control_hint。 - 任务详情
fields[]是后端按当前任务生效规则过滤后的字段集合,不是完整字段矩阵;前端不得自行补齐后端未返回的字段,也不要依赖固定fields.length。 - 未出现在
fields[]的字段表示当前任务不展示、不校验、不提交。例如new_group_block不返回 FIT 专属case_keys.confirmation_number,也不返回 Allotment 专属extracted_fields.child_room_items[];无附件时可以不返回attachments。 - 前端应优先按
control_type渲染字段;旧input_editable、select_editable、date_picker、number_input、file_display、table_editable只作为兼容兜底。 raw_readonly=true、edit_scope=never/system_only或write_target=none的字段不能展示普通编辑控件。source_message、邮件正文、附件引用、raw evidence、event_type、source_event_index、关系索引、route_code、result_type、task_type、task_subtype、manual_review.reason_code等字段必须只读。extracted_fields.room_items.0.room_type_raw是房型原文证据,第一版返回control_type=readonly、edit_scope=never、raw_readonly=true;用户应确认或修改pms_room_type_code,不要覆盖 raw 原文。extracted_fields.room_items.0.room_quantity返回control_type=number;extracted_fields.room_items.0.pms_room_type_code返回control_type=select、options_source=active_pms_room_type_catalog。- type-known manual review 的
manual_review.missing_fields[]应按 JSON Pointer 匹配fields[].field_pointer,并复用对应字段控件提交field_overrides[];匹配不到的 pointer 不要临时生成任意输入框。 - 缺失字段会返回
edit_scope=manual_review_only和write_target=review_resolution.field_overrides;同卡复核中其他可编辑业务字段可能返回normal_and_manual_review,前端第一版仍优先只渲染missing_fields[]指向的字段。 field_overrides[]新页面优先提交field_pointer,可同时提交fields[]中的主field_path;不要提交旧扁平 key 作为新逻辑首选。options_source=active_pms_room_type_catalog、rate_code_catalog、system_case_lookup第一版仅代表选项来源,真实目录 / lookup 未接入前,前端不得硬编码 PMS 房型、Rate Code 或系统对象全集。- 后端可能返回
control_hint=catalog_backend_pending、lookup_backend_pending、structured_table_editor_pending,用于提示前端目录、lookup 或表格编辑后端能力仍未接入。 control_type=structured_table第一版如未实现编辑控件,可以只读展示或按后端edit_scope/options_source给出待接入提示;不要把对象数组压成单行自由文本再提交。control_type=workflow_state表示流程状态或动作入口,例如复核解阻状态;不要把它作为普通field_values保存。
5.8 Debug EML 上传接口接入注意
后端已提供 Debug 页面专用的 .eml 上传和 SuperAgent 调试入口:
POST /api/system/debug/eml-superagent-runs
Header: X-TH-Hotel-Debug-Upload-Key: <调试访问口令>
Content-Type: multipart/form-data
file: .eml 文件
hotel_id: 可选;缺省使用后端系统酒店,显式传值时必须是当前可访问酒店
run_label: 可选调试标签
页面级对接细节请优先阅读 docs/project/frontend-backend/debug-eml-page-integration-guide.md。
前端注意:
- 该接口只用于 dev/test 调试页面,不是生产普通业务页面接口。
hotel_id第一版可不传;单酒店阶段后端按平台酒店表唯一ACTIVE酒店解析。只有在调试人员明确要覆盖当前酒店时,前端才传当前选中酒店。- 接口会解析
.eml,上传原始邮件、内联图片和附件到本系统阿里云 OSS,替换 HTML 内cid:图片,再写入 SourceMessage Inbox。 - SourceMessage 来源 provider 固定为
DEBUG_EML_UPLOAD,用于和 AgentBus 入库邮件区分。 - AgentBus 实时收到邮件后自动推 SuperAgent 由 M007 单独建设;这个接口是人工 Debug 上传链路,不代表实时生产链路。
external_message_id是后端生成的 Debug 独立 ID,格式类似debug-eml-run-{debugRunId}-{sha256前缀};原始邮件Message-ID不再放入agentbus_like_payload,需要排查时看原始 EML OSS 文件和后端 Debug run / SuperAgent metadata。- 邮件会话解析支持
References、In-Reply-To和Thread-Index,但 Debug EML 的external_message_id不使用原始Message-ID做幂等。 agentbus_like_payload是后端发送给 SuperAgent 的 AgentBus Outlook-like 主输入,前端只做只读展示;该对象会包含普通reply_policy.mode=manual、reply_policy.final_only=true,但不再包含schema_version、source.provider=DEBUG_EML_UPLOAD、debug_context或旧的 Debug 专属reply_policy.mode=debug_only。- Debug 来源版本仍由后端 SourceMessage payload 表
schemaVersion=debug-eml-upload-v1记录,前端页面不要再依赖agentbus_like_payload.schema_version。 - 第一版只返回 SuperAgent 结果,不创建订单、不创建任务、不调用任务结果通知接口。
X-TH-Hotel-Debug-Upload-Key只能由调试人员在受控环境手动提供,不能放入VITE_*、源码、构建产物、URL query、localStorage、错误上报或普通日志。- 返回的
html_body_sanitized复用邮件会话详情的安全策略,前端展示 HTML 时优先使用;html_body_with_oss_urls只作为调试原始处理结果,不建议直接渲染。 - 返回的
uploaded_media[]、original_eml_oss_url、html_body_with_oss_urls、html_body_sanitized可能包含 OSS URL;前端不要写入普通日志、埋点、错误上报或 URL query。 superagent_parsed_json为空时,前端展示superagent_raw_answer和warnings[],不要假定 SuperAgent 总能返回业务 JSON;旧 S000/S999 和新 S10/S99 都属于可解释入口结果,不是普通解析失败。
5.9 系统管理后台接口接入注意
系统管理后台 V1 已提供 /system 前端入口和 /api/admin/** 后端接口。所有管理接口都必须带 Authorization: Bearer <access_token>,无 token 返回 401,已登录但缺少权限返回 403。
前端路由和按钮注意:
/system入口需要SYSTEM_ADMIN_CONSOLE_ACCESS;子页面按SYSTEM_USER_MANAGE、SYSTEM_ROLE_MANAGE、SYSTEM_MENU_MANAGE、HOTEL_MANAGE展示。- 如果用户只有酒店管理权限,进入
/system时应跳到/system/hotels,不要固定跳/system/users。 - 系统管理入口只代表可进入后台,不代表拥有所有子页面操作权限;按钮仍需按具体权限控制。
- 直接访问未知菜单路由时前端必须展示安全兜底页,不要让页面白屏。
接口分页和字段注意:
- 分页统一使用
page_num、page_size,响应统一是{ items, page: { page_num, page_size, total } }。 - 后端
BIGINTID 返回字符串,前端不要转成 JavaScript number。 - 时间点字段是带
Z的 UTC 时间,展示时按用户或酒店时区格式化。 - 写操作失败时前端应展示后端
message或error_code,尤其是启用第二家ACTIVE酒店、禁用最后一家ACTIVE酒店、修改内置角色、用户名重复等 409 场景。
用户管理注意:
- 新增用户必须传初始密码,后端只保存哈希。
- 用户启用 / 禁用通过
PUT /api/admin/users/{userId}的user_status完成,没有单独 enable / disable 路径。 - 禁用用户会撤销该用户全部 ACTIVE session;前端若正用该用户 token,会在下一次
/api/auth/me或业务请求时收到 401。 - 重置密码接口
POST /api/admin/users/{userId}/password-reset只在本次响应返回temporary_password,前端不能写入日志、埋点、URL、localStorage 或错误上报。 - 用户授权酒店必须全部是
ACTIVE酒店,默认酒店必须在授权酒店列表内。
角色、菜单、酒店注意:
- 内置角色
system_builtin=true时只读,前端应禁用编辑和权限分配按钮;后端仍会返回 409 兜底。 - 新增自定义角色后,用户需要重新登录或刷新
/api/auth/me才能拿到最新权限上下文。 - 新增菜单允许未知路由;未知路由可以保存,但正式开放可见前要确认前端页面已经存在或兜底页可接受。
- 菜单管理交互升级已提供
GET /api/admin/menus/tree和PUT /api/admin/menus/tree-order:前者返回完整菜单树,后者批量保存parent_id和sort_order。这两个接口仍属于/api/admin/menus/**,必须带 Bearer token,并需要SYSTEM_MENU_MANAGE。 PUT /api/admin/menus/tree-order只能修改菜单父级和排序,不能顺带修改菜单名称、路由、权限码、可见性或状态;后端会校验父级存在、自引用和循环树,并写入platform_admin_audit_log。sort_order可为空;为空时后端按请求items[]顺序生成100、200、300... 的稳定排序号。- 新增酒店默认
DISABLED,hotel_id新增后不能修改。 - 单酒店阶段只允许一家
ACTIVE酒店,后端会拒绝启用第二家ACTIVE,也会拒绝禁用最后一家ACTIVE。 - 系统管理写操作会写入
platform_admin_audit_log;审计接口GET /api/admin/audits可按target_type、target_id、action查询。
5.10 Excel 转 PDF 手动上传接口接入注意
后端已提供 M008 CP2 Excel 转 PDF 手动上传接口:
POST /api/system/document-conversions/excel-to-pdf
Header: X-TH-Hotel-Document-Conversion-Key: <文件转换访问口令>
Content-Type: multipart/form-data
file: .xls / .xlsx 文件
hotel_id: 可选;用于 OSS 对象路径分组
成功响应:
{
"conversion_status": "SUCCEEDED",
"source_file_name": "booking-request.xlsx",
"source_size_bytes": 12345,
"pdf_file_name": "booking-request.pdf",
"pdf_url": "https://oss.example.test/document-conversions/excel-to-pdf/HOTEL-TEST/2026-07-16/.../booking-request.pdf",
"object_key": "document-conversions/excel-to-pdf/HOTEL-TEST/2026-07-16/.../booking-request.pdf",
"content_type": "application/pdf",
"pdf_size_bytes": 67890,
"duration_millis": 1200
}
前端注意:
- 该接口当前属于受控调试 / 后台工具能力,不是普通公开上传接口。
X-TH-Hotel-Document-Conversion-Key不能写入VITE_*、源码、构建产物、URL query、localStorage、错误上报或普通日志。- 只允许上传
.xls/.xlsx;.xlsm第一版不支持。后端会做扩展名和文件头轻量校验,改后缀的非 Excel 文件会返回DOCUMENT_CONVERSION_FILE_CONTENT_INVALID。 - 后端默认大小限制是 20 MB,测试机可以通过环境变量调整。
pdf_url来自本系统 OSS,可用于预览或下载,但不要写入普通日志、埋点、错误上报或 URL query。DOCUMENT_CONVERSION_DISABLED表示后端未开启文件转换能力,页面应提示联系管理员或切换到已开启环境。DOCUMENT_CONVERSION_BUSY表示后端 LibreOffice 并发已满,页面可以提示稍后重试。DOCUMENT_CONVERSION_TIMEOUT/DOCUMENT_CONVERSION_FAILED通常需要后端排查 LibreOffice、字体、文件格式或临时目录权限。- CP2 不会创建转换任务记录,也不会自动处理邮件附件;邮件附件自动派生 PDF 是 M008 后续 checkpoint。
5.11 Manual Invoice 手工开票页面接入方向
M009 后端 CP2 已实现:页面可不依赖订单或任务,用户手工填写 / 选择字段后由后端填充 Excel 模板、转换 PDF 并上传 OSS。
前端注意:
- 前端 V1 已按
invoice.html的业务排版和字段关系实现为项目内页面,但不是直接上线原始 HTML。 - 前端 V1 已新增
/reservation/invoices/new页面,按RESERVATION_INVOICE_GENERATE路由权限保护,使用登录态 Bearer token 调用正式业务接口。 - 页面标题、关键输入占位符和主要操作按钮已接入中 / 英 / 泰 i18n;第一版仍保留原型中的部分英文业务字段标签,后续若 Manual Invoice 全量纳入三语言范围,再统一清理。
- 页面已支持无订单 / 无任务独立生成,固定提交
source_type=MANUAL,order_id=null,task_id=null;暂不做订单 / 任务自动预填。 - 侧边栏入口不由前端硬编码公开,仍依赖后端登录态
menus[]。如需菜单中展示,建议菜单管理配置menu_code=RESERVATION_MANUAL_INVOICE、route_path=/reservation/invoices/new、permission_code=RESERVATION_INVOICE_GENERATE。 - 第一阶段入口建议是独立页面,例如
/reservation/invoices/new或/invoices/new;不要求必须从任务详情或订单详情进入。 - 无订单 / 无任务时,页面按
source_type=MANUAL提交,task_id和order_id可以为空。 - 从任务进入时,后续可以使用
GET /api/reservation/tasks/{taskId}的fields[]、草稿或确认 payload 预填;从订单进入时,需要明确选择具体任务或提示仅使用订单摘要,避免一个订单多任务时字段来源不清。 - Company、Attention、Address、Tel、Email、Booking Date 第一阶段可以按“选择 + Manual 手填”控件处理。
- Company、Attention、Address、Tel、Email 是一组收件方联系人档案,不是五个互相独立字段;选择 Company 后应刷新 Attention 候选,选择 Attention 后应带出 Address、Tel、Email。Booking Date 展示在同一区域,但不属于联系人档案,应作为
document.booking_date独立提交。 - 第一阶段已确认三组客户 / 旅行社种子数据:
LIAN_TAI/LIAN TAI TRAVEL (THAILAND) CO., LTD.+Khun Ann;QBD/Q.B.D. TRAVEL GROUP CO., LTD+Jitdanun Panaphuchong;HANATOUR/HANATOUR TD CO., LTD.+ 7 个联系人。完整数据以docs/project/requirements/M009-manual-invoice-generation-v1.md为准。 - Room Type、Room Rate、Extra Bed 建议也预留“选择 + 可手填 / 可覆盖”能力,后续接 PMS 房型、Rate Code 或价格配置。
- Amount、Sub-Total、VAT、Total 是只读计算字段;前端可展示预览,但最终金额以后端计算和模板公式为准。
- 酒店名称、Tax ID、法人主体、银行账户、Logo 和固定付款文案不应作为每张 Invoice 的手工输入;第一阶段可由模板或酒店发票配置提供。
- 正式业务生成接口为
POST /api/reservation/invoices/manual-generations,需要 Bearer token、酒店访问权和RESERVATION_INVOICE_GENERATE权限。 - 第一版后端只支持
source_type=MANUAL,task_id/order_id可以为空;传入时后端会反查对象所属酒店;如果两者同时传入,任务必须属于该订单,否则返回RESERVATION_INVOICE_CONTEXT_MISMATCH。 - 第一版后端最多支持 10 条费用明细;超过 10 条会返回
RESERVATION_INVOICE_VALIDATION_FAILED。 pdf_url前端会优先用fetch + Blob下载;如果 OSS CORS 不允许浏览器读取文件,则只能退回打开 PDF 页面。若测试环境或正式环境需要稳定下载按钮,建议后端后续提供带Content-Disposition的下载代理或签名下载 URL。- 错误响应里的
error_code用于普通用户主提示;message/details[]前端仅折叠为技术详情,避免把字段路径、模板异常等内部信息直接铺到主提示区。 - 第一版暂未提供 Invoice 历史列表、详情查询、任务 / 订单预填接口和客户联系人目录查询接口;前端客户 / 联系人候选可先按 M009 文档中的种子数据实现。
- 前端不得直接调用
POST /api/system/document-conversions/excel-to-pdf来完成业务开票;该接口是 M008 调试 / 后台工具能力,受 access key 控制,不具备业务开票审计和权限边界。
5.12 Rooming List Excel 生成页面接入方向
M010 后端 CP1 已实现。第一版生成结果直接下载 .xlsx,不落库、不上传 OSS,不依赖订单或任务。
接口:
POST /api/reservation/rooming-lists/generations
Authorization: Bearer <access_token>
Content-Type: multipart/form-data
权限:
RESERVATION_ROOMING_LIST_GENERATE
前端注意:
- 前端 V1 已新增
/reservation/rooming-lists/new页面,按RESERVATION_ROOMING_LIST_GENERATE路由权限保护,并使用登录态 Bearer token 调用正式业务接口。 - 侧边栏入口不由前端硬编码公开,仍依赖后端登录态
menus[]。如需菜单中展示,建议菜单管理配置menu_code=RESERVATION_ROOMING_LIST、route_path=/reservation/rooming-lists/new、permission_code=RESERVATION_ROOMING_LIST_GENERATE。 - 该页面上传来源名单 Excel,后端默认识别
护照全名列。 - 姓名支持
LI/CHUNHONG和LI CHUNHONG两类格式;后端会把第一段写入目标Name,剩余部分写入目标First Name。 - 前端必须让用户输入
people_per_room,后端按名单顺序分组,并用ceil(total_people / people_per_room)生成房间行。 - 每组第一位旅客写入
Name/First Name,同组剩余旅客写入Accompanying Guests,多人用英文逗号分隔。 - 除
Line、Name、First Name、Number of Rooms、Accompanying Guests外,目标 Excel 其他字段第一版都由前端输入或选择,例如Title、Arrival、Departure、Room Type、Rate Code、Payment Type、Nationality。 - 第一版接口成功后直接返回 Excel 文件流,前端应按 Blob 下载处理,不要期待 JSON 里的 URL。
- 失败时返回统一 JSON 错误,例如
ROOMING_LIST_VALIDATION_FAILED、ROOMING_LIST_SOURCE_FILE_INVALID、HOTEL_ACCESS_DENIED或FRONTEND_PERMISSION_DENIED。 - 该上传接口会在 multipart 参数绑定前先校验 Bearer token 和
RESERVATION_ROOMING_LIST_GENERATE权限;未登录时优先返回 401,不会因为缺少业务字段先返回 400。 ROOMING_LIST_VALIDATION_FAILED已覆盖 multipart 必填字段缺失、日期格式错误和数字格式错误,details[]会返回字段级提示。- 页面不要把上传文件内容、客人名单、生成文件内容写入浏览器日志、埋点、错误上报、URL 或 localStorage。
- 第一版没有 preview 接口、生成记录接口、OSS URL、历史下载和订单 / 任务预填;前端不要在页面上承诺这些能力。
6. 不给前端直接调用的接口
POST /api/system/reservation/demo-data只用于 dev/test 联调造数,不是生产业务页面接口;访问口令不能进入前端代码。POST /api/system/debug/eml-superagent-runs只用于 dev/test Debug 页面,不是生产普通业务页面接口;访问口令不能进入前端代码或构建产物。POST /api/integrations/superagent/task-results是 SuperAgent 到后端的服务到服务入站接口。POST /api/integrations/superagent/task-results已支持 M002 V4 入站解析基线;这是第三方回调能力,不是前端页面接口,前端只通过任务列表 / 任务详情观察后端派生后的结果。POST /api/ai-query/v1/case-context和POST /api/ai-query/v1/object-detail是 SuperAgent 查询上下文接口,不是前端页面接口。GET /api/source-message-conversations/{externalConversationId}是历史讨论过的候选路径,当前后端不提供,前端不要接入。- AgentBus probe、fixture、replay、system 类接口不应放到普通业务前端页面。
7. 需要持续提醒的后置事项
- 普通任务切换订单接口继续后置。
- M002 V4 入站解析与数据模型基线已完成第一版:后端可接收
source_message + order_contexts[] + message_events[],识别NEW_BOOKING、UPDATE_BOOKING、CANCEL_BOOKING、TRACE_RESERVATION_NOTES、ROOMING_LIST、PAYMENT,并保存 V4 原始 payload、route_code、系统处理分类和field_contract_version=20260718-v4。前端暂不需要直接调用 V4 回调接口。 - V4 可映射 event 现阶段仍复用现有任务详情结构;任务详情中若出现
field_contract_version=20260718-v4或 AI payload 内的v4_source_message、v4_order_context、v4_message_event,前端第一版只读展示即可,不要据此假定完整 V4 多卡页面已经完成。 - V4
PAYMENT.attachment_ids[]不匹配、UPDATE_BOOKING携带rate_code等问题会出现在任务详情同批次的adapter_contract_errors[]只读诊断块中,不展示保存、确认、执行或重试按钮。 - V4 包级契约错误只会保存在 AI transition 中,不会出现在普通任务列表;V4 event 级契约错误如果同批次存在其它业务任务,前端仍按任务详情里的
adapter_contract_errors[]只读展示诊断信息。 - 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 工作台统一列表草案为GET /api/reservation/workbench-items,业务订单任务草案为/api/reservation/order-tasks/**,S10 来源通知详情草案为GET /api/reservation/source-notifications/{notificationId},但当前还没有实现,不要提前接入草案路径。 - V4 新模型确认口径是不保存后端草稿、卡片最终确认后锁定、技术异常不进入用户可处理卡、当前不生成 OPERA 模拟操作。Basic Information 必须先确认;其它业务卡第一版不强制逐张顺序确认。现有 V3
draft、confirm、manual-review-resolutions和 OPERA 模拟接口仍只代表旧链路能力,不能直接等同 V4 多卡最终接口。 - V4 S10 后续采用来源通知模型:任务列表 / 工作台展示,进入纯通知详情页后只显示邮件展示卡和确认按钮;不再挂隐藏技术订单,不创建订单、不进订单列表、不参与订单阻塞,也不支持编辑、复核、OPERA 或人工终止。当前代码里旧
SOURCE_MESSAGE_ONLY只读任务仍属于过渡实现。 - M002 V3 的结构化
S10/S99入站、40 条 P0.1 路由枚举 / 稳定配置、UNHANDLED_CURRENT_INTENT、adapter_contract_errortransition 最小落库、任务列表 / 订单时间线 / 任务详情 V3 路由字段和只读诊断块透出、type-known manual review 同卡解阻第一版、typed infrastructure error、P0 fixtures 回归基线和 Parent Group / Cancel Allotment 路由修订均已完成。 - 系统管理后台 V1 已完成;后续若要做用户搜索更多筛选、批量操作、密码策略增强、MFA、登录设备管理,应单独开需求。
- 现有 Reservation / SourceMessage 业务接口的强制登录、强制权限和业务审计 actor 全量迁移仍后置。
- 真实 OPERA / OHIP 接入继续后置。