385 lines
24 KiB
Markdown
385 lines
24 KiB
Markdown
# M012 酒店预订邮件识别到人工确认端到端 V0.1
|
||
|
||
| 项目 | 内容 |
|
||
| --- | --- |
|
||
| 文档状态 | V0.1 已实现并验收;2026-08-08 补充 BR00 订单卡双区块后端收口 |
|
||
| 业务基线 | `BR00-BASELINE-1`,高于本仓库旧样例、旧 prompt 和旧字段语义 |
|
||
| 适用范围 | 员工上传真实 `.eml` 或 AgentBus 投递邮件后,到任务卡关键参数被用户确认为止 |
|
||
| 非适用范围 | 确认后的 Opera / PMS API 调用、客户回复、Invoice、独立 Manual RateCode、Rooming List 名单解析 |
|
||
| Catalog 版本 | `booking-catalog-v20260808` |
|
||
| Parser 版本 | `booking-email-parser-v0.1` |
|
||
|
||
本次“已实现并验收”指三封指定真实邮件覆盖的固定渠道纵向切片:普通员工手工导入、LIANTAI/QBD workbook 确定性解析、V4 建卡、字段复核与人工确认。第 4 节仍完整保存 BR00 业务语义,但未被这三封样本覆盖的 Allotment、独立 Rooming List、独立 Payment、图片语义和统一 Booking Agent fallback,不因本次切片通过而宣称已完成;其现状和边界见第 15 节。
|
||
|
||
## 1. 背景与架构位置
|
||
|
||
AgentBus 同时承担邮件消息入口和 Agent 平台。本项目不能把“附件解析”孤立成一次文件读取:邮件正文、当前回复、历史往来、附件版本和本次附件中的更新行共同决定业务动作。
|
||
|
||
本期沿用七层架构,并把邮件入口耦合进去:
|
||
|
||
1. **信息系统接入与编排**:接收 AgentBus 邮件或员工上传的 `.eml`,建立 SourceMessage、附件摘要、幂等键和处理批次。
|
||
2. **材料预处理**:拆分 current 与 quoted history,识别附件版本,对固定渠道 Excel 只选择本次候选业务行,并保留 sheet/行号/底色等证据。
|
||
3. **确定性 Parser + Catalog**:用版本化业务目录把渠道字段、动作别名、房型写法和数值编码归一为标准事实;不能可靠解析的字段保持未解决,不猜测。
|
||
4. **当前态与邮件上下文**:按会话读取历史 SourceMessage 和既有业务任务,向业务识别提供“当前邮件事实 + 必要历史事实”,历史内容不重复触发动作。
|
||
5. **业务识别**:程序先处理固定渠道可确定部分;失败或存在语义歧义时,把隐私最小化的材料交给 Booking Agent。输出业务事件、关联事件和通知,不直接调用 PMS。
|
||
6. **确定性校验与人工确认**:同一 Catalog 校验程序或 Agent 输出,生成可编辑任务卡、缺失字段、告警和证据;即使全部字段符合目录,也必须由用户确认。
|
||
7. **执行适配器**:确认后调用 PMS/Opera,明确不在 M012 V0.1 范围。
|
||
|
||
Catalog 不单独构成业务层。它是第 3 层的版本化确定性知识,同时被 Parser、第 5 层 Agent reference 和第 6 层校验器消费。三者必须记录同一个 Catalog 版本,避免同一来源词在不同环节被翻译成不同业务代码。
|
||
|
||
## 2. 目标
|
||
|
||
- 提供普通员工可用、受现有权限保护的 `.eml` 导入 API 和可点击页面,不依赖 Debug Key。
|
||
- 保存一封实际邮件一次;相同实际邮件重复投递命中幂等,分别发送的邮件分别处理。
|
||
- 对固定渠道 Excel 按“业务范围内整行均有非白色底色”选择候选行,而不是任一单元格有颜色。
|
||
- 将候选行确定性解析成统一事实,生成 New / Update / Cancel 及 Trace、Rooming List、Payment 或 General/Risk 通知。
|
||
- 复用 SourceMessage 与 Reservation V4 任务卡、目录 lookup、人工复核、确认和审计主线。
|
||
- 在 UI 展示邮件证据、解析证据、告警、关键字段和确认阻断;用户可修正允许字段并逐卡确认。
|
||
- 用三封 2026-08-08 指定真实邮件做只读验收输入,并用去隐私合成 fixture 建立自动化回归。
|
||
- 提供 PostgreSQL 项目专属 Schema `th_hotel_booking` 的版本化迁移与验证脚本;远程执行前必须只读确认无同名冲突及权限边界。
|
||
|
||
## 3. 非目标
|
||
|
||
- 不在本期执行 PMS/Opera 操作,也不伪造执行成功。
|
||
- 不自动回复邮件、发送通知或修改 AgentBus 外部状态。
|
||
- 不以 Tour Code 代替 Group Code,也不根据样例猜 Account / Market / Source / Rate Code 映射。
|
||
- 不把价格作为前端结构化确认字段;价格只参加未来 Rate Code 映射并留在来源证据中。
|
||
- 不解析 Rooming List 旅客名单、不导入旅客信息、不做名单差异比对。
|
||
- 不将真实邮件、真实附件、旅客信息、邮箱地址或数据库密码提交到 Git。
|
||
|
||
## 4. 统一业务语义
|
||
|
||
### 4.1 生命周期与任务
|
||
|
||
订单生命周期事件:
|
||
|
||
- `NEW_BOOKING`
|
||
- `UPDATE_BOOKING`
|
||
- `CANCEL_BOOKING`
|
||
|
||
同订单可附带的独立任务卡:
|
||
|
||
- `TRACE_RESERVATION_NOTES`
|
||
- `ROOMING_LIST`
|
||
- `PAYMENT`
|
||
|
||
来源邮件级通知:
|
||
|
||
- `S10` General:整封当前邮件没有任何支持的业务任务时最多一条。
|
||
- `S99` Risk:当前邮件存在无法分类或高风险歧义时最多一条;已识别的清晰任务仍继续创建。
|
||
|
||
已知类型但缺字段时保留原类型卡并进入 `REVIEW_REQUIRED`,不得降格成 Risk。
|
||
|
||
### 4.2 名称和订单字段
|
||
|
||
- `Tour Code` 是 `Name` 的一个可能来源值。
|
||
- `Name of Group`、`Group Name` 在本期统一为 `Group Name = Block Name`。
|
||
- `Group Code` 是独立字段,不能由 Tour Code 推导。
|
||
- 一个清晰预订分组生成一个订单任务;多个 Name、多个房型、多个日期段可以属于同一订单,不按 Name 拆卡。
|
||
- New Booking 的实际总房数 `< 5` 为 `FIT`,`>= 5` 为 `GROUP`。
|
||
- 所有订单相关任务均有 Basic Information 与 Room Information。
|
||
- Basic Information 只允许由已确认发件人映射生成;映射未配置时 Account/Market/Source 留空并阻断确认。
|
||
|
||
### 4.3 New Booking 确认条件
|
||
|
||
通用必填:
|
||
|
||
- Booking Type
|
||
- 一个或多个 Name
|
||
- Arrival Date、Departure Date;Nights 由日期派生
|
||
- 至少一个 Room Type + Quantity
|
||
- 一个订单级 Rate Code
|
||
|
||
Group 额外必填:
|
||
|
||
- Group Code
|
||
- Group Name / Block Name
|
||
|
||
Rate Code 根据公司、房型、价格、早餐信息映射,但当前映射仍待配置。零候选或多候选都保留 New Booking,让用户选择并阻断确认;系统不得自动选择。
|
||
|
||
### 4.4 Update、Cancel 与关联任务
|
||
|
||
- `AMEND`、`AMD`、`AMEND TO` 等归一为 Update;旧 Group Code → 新 Group Code 仍视为同一订单链。
|
||
- 每封实际 Update 邮件、每个订单生成一张新的 Update 卡,不按历史内容做业务去重。
|
||
- Cancel 只在未来 PMS 执行成功后结束订单;本期只确认 Cancel 动作参数。
|
||
- Allotment:N 个实际团生成 N 张 New 卡,并生成一个共享来源扣减/取消动作;来源动作失败不阻断实际团。
|
||
- Extra Bed 是 Trace,不是 Room Type;同一 Group Code、同一当前邮件的多个 Trace item 合并一张卡。
|
||
- Trace 的 Department 必须由用户选择 FO、HSK 或 FO+HSK 才能确认。
|
||
- Rooming List 与 Payment 的原生事项卡仍是通知型卡,不解析名单、不核验付款;其 companion Room 只补订单上下文,不改变该业务边界。
|
||
|
||
### 4.5 订单任务双区块与 companion Room
|
||
|
||
- 每个可定位订单的 Order Task 固定包含一张 `BASIC_INFORMATION`;New、Update、Cancel、Trace、Rooming List、Payment 都必须同时具备 `ROOM_INFORMATION`,General/Risk 来源通知不适用。
|
||
- New、Update、Cancel 继续由生命周期 event 直接生成 Room Information。若同一 `source_message + order_ref` 已有任一生命周期 event,不再为同组 Trace、Rooming List、Payment 重复生成 Room。
|
||
- 若一个 Order Task 只有 Trace、Rooming List、Payment,则以后端接收顺序中的首个关联 event 生成一张共享 companion Room,并保留该 event 的类型、transition 和 `source_event_index` 以便追溯;不能伪装成新的 `UPDATE_BOOKING` event。
|
||
- companion Room 只展示同订单已确认完成态或前置 New 计划完成态:`current_values` 与 `final_values` 使用该投影,`proposed_values` 为空,`change_summary` 为空;辅助 event 自身字段不得被当成房间变更。
|
||
- 同一 Order Task 的多张业务卡仍分别确认;Basic Information 保持前置门禁。Trace、Rooming List、Payment 专属卡、附件安全边界和确认副作用不因 companion Room 改变。
|
||
- 本增量只改变新建订单任务的 intake 行为;已持久化且已有卡片的历史 V4 Order Task 受现有幂等门禁保护,不在重放时隐式补卡。若存量也要补齐,必须另做可审计、可回滚的受控回填。
|
||
|
||
## 5. 邮件与上下文边界
|
||
|
||
### 5.1 current/history
|
||
|
||
- 当前邮件的正文、当前附件和明确的当前指令可以触发业务。
|
||
- quoted history 只用于解释当前语义、继承订单身份和检测重复,不可再次触发旧动作。
|
||
- 没有附件时不经过 Excel 预处理,直接进入上下文组装和业务识别;并非跳过 SourceMessage 接入。
|
||
- 当前正文仅有标题/签名、但附有明确更新附件时,附件是本次动作核心证据。
|
||
|
||
### 5.2 附件版本
|
||
|
||
- 当前邮件明确写 `REV.n`、`use this file` 等版本指令时,优先当前附件。
|
||
- 当前版本没有严格候选行或只有部分底色时,可以和同会话前版本做差异,差异只作为复核证据,不直接成为自动执行事实。
|
||
- 同一事实再次出现时仍展示重复/陈旧告警,由用户判断,不静默吞掉新邮件。
|
||
|
||
## 6. 固定渠道预处理
|
||
|
||
### 6.1 共同底色口径
|
||
|
||
- 只认单元格底色,不认字体颜色、批注、筛选或条件格式推测。
|
||
- 白色、默认色、无填充不算。
|
||
- 只检查渠道 Catalog 定义的业务列范围;该范围内每个业务列都必须有非白色底色,才是 `STRICT_CURRENT_CANDIDATE`。
|
||
- 一条渠道业务记录可以由 anchor row 与后续 continuation rows 组成;Tour Code/酒店明细在 anchor,当前动作在后续行时,以该 logical record block 的业务列底色并集判断完整性,并同时记录 anchor/action row。不得要求所有字段出现在同一物理行。
|
||
- 只有部分业务列有底色时记为 `PARTIAL_FILL_REVIEW_EVIDENCE`,不自动生成事实。
|
||
- 表头颜色不触发业务行。
|
||
|
||
### 6.2 渠道 Profile
|
||
|
||
| Profile | 表头 | 业务列 | 动作列 | 主要来源列 |
|
||
| --- | ---: | --- | --- | --- |
|
||
| `LIANTAI_FIT` | 3 | A:F | F | Tour Code=B;酒店明细=D/E |
|
||
| `QBD_MONTHLY` | 3 | B:H | H | Tour Code=C;酒店明细=E |
|
||
| `LIANTAI_UPDATE` | 2 | A:I | G | Tour Code=A;酒店明细=D;状态=H;备注=I |
|
||
|
||
动作别名必须由 Catalog 版本管理,至少包含:
|
||
|
||
- New:`NEW BOOKING`
|
||
- Update:`UPDATE`、`AMEND`、`AMD BOOKING`、`AMEND TO`
|
||
- Cancel:`CANCEL`、`CXL`、`ยกเลิก`
|
||
|
||
不得为了“程序识别”无限穷举整句。Parser 先分离动作核心 token、动作日期和自由文本,再用有限别名字典归一;不能可靠归一时降级 Agent 或人工复核。
|
||
|
||
### 6.3 当前日期与异常年份
|
||
|
||
- 候选行的动作 marker 优先按日/月与邮件接收或发送日期匹配。
|
||
- FIT 文件若因 Excel 自动填充出现 2026、2027……2041 的异常连续年份,日/月匹配的行仍保留为候选,并加 `ACTION_DATE_YEAR_ANOMALY`。
|
||
- 异常年份不能作为真实业务年;入住/离店年份以邮件业务日期和 sheet 月份解析,并在不唯一时留待复核。
|
||
- QBD 中严格底色但动作日期早于当前邮件日期的行保留证据并加 `STALE_STRICT_CANDIDATE`,不得静默当成本次唯一事实。
|
||
|
||
## 7. Parser 与 Agent 分工
|
||
|
||
### 7.1 确定性 Parser 输出
|
||
|
||
Parser 输出事实,不输出 PMS 命令:
|
||
|
||
```json
|
||
{
|
||
"catalog_version": "booking-catalog-v20260808",
|
||
"parser_version": "booking-email-parser-v0.1",
|
||
"source": {
|
||
"attachment_name": "safe-name.xlsx",
|
||
"profile": "LIANTAI_UPDATE",
|
||
"sheet": "safe-sheet",
|
||
"row_number": 57,
|
||
"selection_status": "STRICT_CURRENT_CANDIDATE"
|
||
},
|
||
"action": "NEW_BOOKING",
|
||
"names": ["TOUR-CODE-VALUE"],
|
||
"group_code": null,
|
||
"group_name": null,
|
||
"arrival_date": "2026-08-12",
|
||
"departure_date": "2026-08-15",
|
||
"room_items": [
|
||
{
|
||
"source_label": "U-TWN8.5",
|
||
"room_type_code": "RM3",
|
||
"room_count": 12
|
||
}
|
||
],
|
||
"rate_code": null,
|
||
"warnings": ["RATE_CODE_UNRESOLVED"]
|
||
}
|
||
```
|
||
|
||
固定渠道优先走程序:
|
||
|
||
1. Profile、严格候选行、动作和字段均可确定时,由 Parser 生成标准事实。
|
||
2. 某个字段失败时保留已确定字段,标注具体 warning;不丢弃整行。
|
||
3. 需要自然语言语义、图片、复杂历史关系或未知格式时,将最小必要材料交给 Booking Agent。
|
||
4. Agent 输出仍必须经过相同 Catalog 版本的确定性校验和人工确认。
|
||
|
||
### 7.2 初始房型映射
|
||
|
||
当前可确定映射:
|
||
|
||
- `U-DBL`、`Sup DBL` → `RM2`
|
||
- `U-TWN`、`Sup TWN` → `RM3`
|
||
- `U-TRP`、`Sup TRP`、`TRP` → `RM2`
|
||
- `DBL SUITE` → `SU1`
|
||
- 明确 `TWN SUITE` → `SU2`
|
||
- `FAM 6+4` → `RM4`
|
||
- Family 3/4 → `SU3`
|
||
|
||
`ST:1卧双标 TWN` 等未被当前目录唯一覆盖的变体必须留空并复核。即使不同原始房型映射到同一 PMS code,也必须分别保留 raw label 与数量,不能按 PMS code 合并。
|
||
|
||
## 8. 后端接口
|
||
|
||
### 8.1 普通员工 EML 导入
|
||
|
||
`POST /api/reservation/booking-email-intakes`
|
||
|
||
- `multipart/form-data`
|
||
- `file`:必填,只接受 `.eml`
|
||
- `hotel_id`:可选,仍以当前登录用户酒店上下文校验
|
||
- 权限:`RESERVATION_TASK_EDIT`
|
||
- 文件大小遵循 Spring multipart 和本模块安全上限
|
||
- 不接收 Debug Key,不直接接受外部附件 URL
|
||
|
||
成功返回 HTTP 201:
|
||
|
||
```json
|
||
{
|
||
"source_message_id": "123",
|
||
"duplicate": false,
|
||
"status": "TASKS_CREATED",
|
||
"catalog_version": "booking-catalog-v20260808",
|
||
"parser_version": "booking-email-parser-v0.1",
|
||
"order_task_ids": ["501"],
|
||
"source_notification_ids": [],
|
||
"warnings": [
|
||
{
|
||
"code": "RATE_CODE_UNRESOLVED",
|
||
"message": "Rate Code 需要人工选择"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
重复投递返回同一 SourceMessage 和已有任务/通知,不重复创建。
|
||
|
||
### 8.2 内部 V4 契约增量
|
||
|
||
- `names[]` 是 Agent/Parser 的标准数组;V0.1 前端投影为换行分隔 `names_text` 便于编辑。
|
||
- `group_code` 与 `group_name` 分别保存;兼容读取旧 `group_block_name` / `fit_name`,新入口不再错误默认。
|
||
- `booking_type`、`group_code`、`group_name`、`names_text`、日期、房型数量、Rate Code 进入 Room Information 的最终值。
|
||
- `nights` 为派生只读字段。
|
||
- `block_id` 不展示。
|
||
- Confirmation Number 仅当当前邮件明确提及时展示。
|
||
- `recognition` 安全块保留 profile、sheet、anchor row、action row、版本、选择状态和 warning code,不包含完整原始行、附件 URL 或旅客隐私。
|
||
- 新订单在确认前允许 `order_id` / target binding 未解决;人工复核不得强制用户输入已存在本地订单 ID。Update/Cancel 等既有订单动作仍要求可靠归属。
|
||
- V4 intake 必须按 4.5 的规则保证每个订单任务具有 Room Information;这是同一 Order Task 的展示/确认上下文补齐,不要求 Parser 或 Agent 在 Trace、Rooming List、Payment event 中复制完整房间字段。
|
||
- `GET /api/reservation/order-tasks/{orderTaskId}` 对 companion Room 返回与生命周期 Room 相同的安全 `display_payload.room_information` 和 `fields[]` 结构;辅助 event 采用 current-only 模型,不返回 Agent `target_order`、邮件正文、附件 URL 或原始 evidence。
|
||
|
||
## 9. 前端验收
|
||
|
||
新增路由:`/reservation/email-intake`,权限 `RESERVATION_TASK_EDIT`。
|
||
|
||
页面必须是真实可操作页面并连接后端:
|
||
|
||
- 点击或拖放选择一封 `.eml`;显示文件名、大小和移除/重新选择。
|
||
- 导入按钮有 idle、uploading、success、partial warning、duplicate 和 error 状态。
|
||
- 成功后展示 SourceMessage ID、解析版本、任务数、通知数和 warning。
|
||
- 每个创建结果可点击进入现有订单任务详情或来源通知详情;可返回任务队列。
|
||
- 任务列表提供“导入邮件”入口。
|
||
- 任务详情展示识别证据和 warning;Basic Information 必须先确认,随后业务卡可编辑/确认。
|
||
- New Booking 未绑定既有订单时隐藏或明确标注“无需现有订单 ID”,不得用不可理解的强制输入阻塞用户。
|
||
- 具备键盘焦点、可见 label、错误关联、响应式布局及 loading/empty/error 状态。
|
||
|
||
## 10. 安全、隐私与审计
|
||
|
||
- 原始 EML 与附件内容仅在受控 SourceMessage 原文能力或临时解析内使用;普通任务 API 只返回安全摘要。
|
||
- 日志、错误、前端结果和 migration 不输出原始正文、真实邮箱、完整原始行、OSS 签名 URL、数据库密码或其他 Secret。
|
||
- 真实样本不得复制到 `server/src/test/resources`;测试 fixture 必须合成并去隐私。
|
||
- 用户对 Basic、Room、Trace 等卡的复核/确认继续写现有审计日志。
|
||
- 业务操作记录保留要求为 3 个月;V0.1 先保存 `retention_until`/可清理时间语义,清理调度不在本期强制范围。
|
||
|
||
## 11. PostgreSQL 项目专属 Schema
|
||
|
||
- Schema 固定为 `th_hotel_booking`。
|
||
- migration 必须显式 `CREATE SCHEMA IF NOT EXISTS th_hotel_booking` 并限定 `search_path` 或使用全限定名。
|
||
- 不修改 `public`,不复用旧脚本中的 `booking` schema,不删除或改名其他项目对象。
|
||
- 远程执行顺序:只读读取 `current_database/current_user` → 列出同名 schema/对象 → 检查 CREATE/USAGE 权限 → 创建本 schema → 只在本 schema 运行 migration → 对比其他 schema 对象计数/更新时间。
|
||
- 密码只通过进程环境或交互输入,绝不写入仓库、planning 文件、命令回显或交付文本。
|
||
- 当前 Spring 应用仍以 MySQL/H2 为运行基线;PostgreSQL migration 是项目专属目标模型,数据库方言切换不在本期暗中完成。
|
||
|
||
## 12. 测试与完成定义
|
||
|
||
### 12.1 自动化
|
||
|
||
- EML:Message-ID、Conversation-ID、current/history、无附件和多个附件。
|
||
- Excel:三种 Profile、整行业务列有非白底色、部分底色、白色、表头颜色、异常年份、陈旧严格行、多个日期段。
|
||
- Parser:动作别名、房型/价格/数量、New 房量阈值、Update、Cancel、Extra Bed Trace、未解决字段。
|
||
- 业务:一单多 Name/房型/日期段不误拆;三封样本中的生命周期/linked Trace;无确定事实时单封通知;重复投递幂等。Allotment、独立 Rooming List/Payment 与图片语义不属于本次固定渠道切片的完成证据。
|
||
- API:权限、文件类型/大小、201、重复结果、错误安全、任务创建。
|
||
- V4:新订单不要求既有 order ID;Basic 先确认;关键字段阻断;确认审计。
|
||
- V4 双区块:独立 Trace、Rooming List、Payment 各自创建 Basic + companion Room + 专属卡;同组已有 New/Update/Cancel 时不重复 Room;详情返回 current-only Room 模型。
|
||
- 前端:上传成功/失败/重复、结果链接、字段渲染、warning、复核与确认请求。
|
||
|
||
### 12.2 三封真实邮件验收
|
||
|
||
真实样本只从用户指定绝对路径读取:
|
||
|
||
1. FIT LIANTAI:动作日/月候选可被选中;异常连续年份产生 warning,不被当成 2041 年业务日期。
|
||
2. QBD REV.2:当前严格行与陈旧严格行被区分;同一 Tour Code 的多个日期段和房型保持一个订单任务。
|
||
3. Update Booking ครั้งที่2:严格底色行生成 9 New/1 Update;Honeymoon 和 Extra Bed 分别生成同订单 Trace;未确认映射保持待复核。
|
||
|
||
### 12.3 完成定义
|
||
|
||
只有以下条件同时满足才可宣布 V0.1 完成:
|
||
|
||
- 普通员工可在可点击页面上传三封真实邮件。
|
||
- 后端真实创建 SourceMessage、订单任务/通知和任务卡,重复上传不重复建任务。
|
||
- 页面可查看证据、warning、关键参数,并能完成允许范围内的修正与确认。
|
||
- 没有执行 PMS/Opera。
|
||
- 后端和前端自动化通过;本地全栈 smoke 通过。
|
||
- PostgreSQL migration 通过本地语法/作用域验证;若远程测试库凭据可安全注入且只读检查无冲突,则项目 schema 已创建并证明未触碰其他 schema。
|
||
- 自主推断规则、应用代码位置、未解决业务映射和测试证据已记录。
|
||
|
||
## 13. 与 M011 的关系
|
||
|
||
M011 仍描述“给 SuperAgent 的通用 Excel 高亮证据增强”,其 V1 规则是任一业务单元格有底色即可抽取。M012 在固定渠道、本期业务入口中采用更严格且已获业务确认的“业务范围整行均有非白底色”规则,并直接形成标准事实候选。
|
||
|
||
两者不应静默混用:
|
||
|
||
- M011 通用 extraction 继续供 Debug/AgentBus 证据预览。
|
||
- M012 deterministic parser 使用独立的版本化 Channel Profile 和严格行选择器。
|
||
- 后续若把 M012 规则推广到 M011,需单独 Change Request 和回归验证。
|
||
|
||
## 14. 待配置而非待猜测
|
||
|
||
- 发件人/渠道 → Account Code / Account Name / Market Code / Source Code 映射。
|
||
- 公司 + 房型 + 价格 + 早餐 → 唯一 Rate Code 映射。
|
||
- `TWN SUITE` 的正式房型代码。
|
||
- Allotment 来源扣减动作在未来 PMS 适配器中的命令结构。
|
||
- AgentBus 生产投递的认证/重试配置和 Booking Agent profile 版本。
|
||
|
||
这些项不阻止识别和建卡,但相关卡必须保持 `REVIEW_REQUIRED` 或明确 warning,不能用样本值代填。
|
||
|
||
## 15. 实施与验收结果
|
||
|
||
2026-08-08 已完成以下纵向闭环:
|
||
|
||
- 普通员工页面 `/reservation/email-intake` 可选择或拖放 `.eml`,调用真实 `POST /api/reservation/booking-email-intakes`,显示解析结果、warning,并跳转到真实 V4 订单任务或来源通知。
|
||
- 三封外部真实 EML 的 API 验收结果依次为 20、1、10 张订单任务;业务构成为 19 Update + 1 Cancel、1 Update、9 New + 1 Update,并在第三封中生成 3 张 linked Trace;重复导入不重复建任务。
|
||
- 浏览器全栈 smoke 已从任务队列进入导入页,上传第三封真实邮件,打开首张任务,选择 Account 并成功确认 Basic Information;桌面和 390px 宽度无横向溢出,fresh session 无 console warning/error。
|
||
- 后端全量测试 441 项通过,0 failure、0 error、1 skipped;真实样本 opt-in 验收 1 项通过。
|
||
- 前端 29 个测试文件共 255 项通过,TypeScript typecheck 和生产 build 通过;lint 0 error,本轮文件无新增 warning。
|
||
- 测试库已仅创建 `th_hotel_booking`:9 张表、8 个 identity sequence、30 个索引/约束索引;迁移前后其他项目 schema 对象计数不变,无跨 schema 外键;回滚型 smoke 后无残留测试行。
|
||
- 本期没有调用 PMS/Opera、发送外部邮件或修改 AgentBus 外部状态。
|
||
|
||
V0.1 的已知运行边界:
|
||
|
||
- 普通员工手工导入路径在请求内解析附件,SourceMessage 和任务保存附件元数据与安全识别证据,但不长期保存可下载的原始附件字节;如需原件归档/下载,应接入既有 AgentBus/OSS 原文链路后另做 checkpoint。
|
||
- 固定渠道确定性 Parser 无法形成事实时,当前手工导入路径生成 S10/S99 来源通知供人工处理;不会在该请求内自动调用外部 Booking Agent。既有 AgentBus → SuperAgent 路径继续独立存在,生产启用和统一 fallback 编排需后续配置与联调。
|
||
- Account/Market/Source、Rate Code 和未唯一覆盖的房型映射仍按本章第 14 节由用户确认,不以真实样本值自动猜测。
|
||
- 确认后的 PMS/Opera 执行仍明确不在 V0.1。
|
||
|
||
## 16. 2026-08-08 BR00 双区块增量追踪
|
||
|
||
| 需求项 | 后端状态 | 前端状态 | 测试状态 | 文档位置 | 当前状态 |
|
||
| --- | --- | --- | --- | --- | --- |
|
||
| 独立 Trace 补 Basic + companion Room | Done | Done | Passed | 本文 4.5、8.2、12.1 | Implemented |
|
||
| 独立 Rooming List 补 Basic + companion Room | Done | Done | Passed | 本文 4.5、8.2、12.1 | Implemented |
|
||
| 独立 Payment 补 Basic + companion Room | Done | Done | Passed | 本文 4.5、8.2、12.1 | Implemented |
|
||
| 同组生命周期 Room 去重 | Done | N/A | Passed | 本文 4.5 | Implemented |
|
||
| General/Risk、权限、酒店隔离与敏感数据边界不变 | N/A | N/A | Passed(既有回归) | 本文 4.5、10 | Verified |
|