Files
th-hotel-simple/docs/project/requirements/booking-email-architecture-v0.4.md
T

122 lines
9.6 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.
# Booking 邮件处理架构 v0.4
| 项目 | 内容 |
| --- | --- |
| 文档状态 | 当前有效 |
| 架构版本 | `booking-architecture-v0.4` |
| 契约版本 | `booking-contracts-v1` |
| 业务基线 | `BR00-BASELINE-1` |
| 范围终点 | 用户确认;不调用 PMS、Opera、付款或部门流转 |
## 1. 目的与替代关系
本架构把邮件获取、附件识别、固定渠道确定性解析、历史上下文、Booking Agent、校验和人工确认收敛为一条可追溯主线。它替代以附件 Parser 或旧 V4 入站模型为中心的实施方式。
早期 `architecture-v0.3`、M002 叙述和 M012 V0.1 实现记录仍可用于迁移和回归,但不能再单独作为新功能的实施依据。新增实现必须以本文和 [Booking 邮件 contracts-v1](booking-email-contracts-v1.md) 为准;发生冲突时,contracts-v1 优先。
## 2. 七层职责与边界
| 层 | 负责什么 | 输入 | 输出 | 不负责什么 |
| --- | --- | --- | --- | --- |
| 1. 信息系统接入与编排 | 接收 AgentBus 邮件或手工 EML,建立幂等、处理批次与状态查询 | AgentBus payload / `.eml` | `SourceMessageEnvelope` | 不理解业务、不直接建最终任务 |
| 2. 材料预处理 | 分离 current/quoted history,列举附件、图片、工作簿结构和候选材料,保留证据引用 | `SourceMessageEnvelope` | `MaterialPackage` | 不把历史内容重复当作本次动作 |
| 3. 确定性 Parser + Catalog | 对适用固定渠道使用版本化渠道 Profile、字段别名和底色规则提取标准事实 | `MaterialPackage` | `ParsedFactSet` | 不猜映射、不做最终业务决定 |
| 4. 当前态与邮件上下文 | 按 Group Code、订单线索或会话定向读取当前事实、有效未完成任务与计划完成态 | `ParsedFactSet` + 来源/历史线索 | `ContextPackage` | 不扫描全库、不让历史邮件重新触发动作 |
| 5. 业务识别 / Booking Agent | 合并当前材料、Parser 事实和 Context,形成候选业务决定;Parser 失败/不适用/歧义时按需兜底 | `ParsedFactSet` + `ContextPackage` | `CandidateDecision` | 不下载附件、不直接读写数据库、不建最终任务、不调用 PMS |
| 6. Validator 与人工确认准备 | 校验 schema、Catalog、证据、目标、生命周期、前置关系和确认必填项 | `CandidateDecision` | `ValidationResult`、`ConfirmationProjection` | 不绕过校验建卡、不执行外部业务动作 |
| 7. 用户确认 | 展示安全的关键参数、证据、阻断、可编辑字段和链接动作;冻结已确认参数与审计 | `ConfirmationProjection` | `CONFIRMED` 记录 | 不调用 PMS/Opera,不改变付款或部门状态 |
### 2.1 信息系统与 Agent 的职责分界
- **信息系统**拥有 SourceMessage、幂等、附件/证据存储、Catalog、确定性 Parser、Context 查询、Validator、数据库事务、确认 API 和审计。
- **AgentBus**既是邮件消息入口适配器,也是 Booking Agent 的承载平台;它不成为业务事实源。
- **Booking Agent**只消费最小化的 `ParsedFactSet + ContextPackage`,其中唯一的正文材料是 policy 脱敏、限长的 `agent_input_material` current excerpt;它不能自行扩大材料范围、下载附件、调用 PMS 或写任务表。
- Parser、Agent 和 Validator 使用同一 `catalog_version`。Catalog 是跨层的版本化业务词典,不属于某一个 Agent skill;Agent 的 reference 是 Catalog 的受控消费视图。
- `Name of Group`、`Group Name`、`Tour Code`、`Group Code` 是固定渠道对同一团号的不同列名;第 3 层统一写入 `group_code`,第 4 层也只以该统一值定向查询,不能把列名差异制造成多目标。
## 3. 统一状态机
处理运行(processing run)使用以下状态;状态是运行主线,不等同于单张业务卡的用户可见状态:
```text
RECEIVED
→ MATERIAL_READY
→ PARSER_COMPLETE | PARSER_NOT_APPLICABLE | PARSER_FAILED
→ CONTEXT_READY
→ AGENT_COMPLETE(仅在需要 Agent 时)
→ VALIDATED
→ AWAITING_CONFIRMATION
→ CONFIRMED
```
- `PARSER_FAILED`、`PARSER_NOT_APPLICABLE` 不代表整封邮件失败;它们是允许进入 Context 和按需 Agent 的受控分支。
- Validator 可以把受影响目标隔离为 Risk,但同封其他清晰目标继续到确认准备。
- 任何阶段发生可重试技术错误时记录 run attempt、错误代码和安全摘要,不伪造业务完成。
- `CONFIRMED` 是本期终点。PMS/Opera 适配器必须是后续独立状态机,不得从本状态机隐式触发。
## 4. 处理结果与隔离规则
每封邮件及每个候选目标都使用以下稳定结果类型:
| 结果 | 适用条件 | 后续行为 |
| --- | --- | --- |
| `IN_SCOPE_TASKS` | 当前邮件存在可识别的 Booking 业务目标 | 形成候选卡,经过 Validator 后进入确认 |
| `GENERAL_NOTIFICATION` | 整封 current 邮件确定没有任何支持的业务任务 | 最多一条 General 通知 |
| `RISK_NOTIFICATION` | 业务类型、目标、材料或 Parser 结果存在无法安全消解的歧义 | 每封最多一张 Risk;隔离不明确部分 |
| `IGNORED_DIRECTION` | 确定为酒店外发、内部邮件或不属于本系统处理范围 | 不创建待办任务,保留安全处理记录 |
补充规则:
- 已知业务类型但字段缺失,保留原业务类型并标记 `REVIEW_REQUIRED`,不能降格成 General 或 Risk。
- 同封邮件存在清晰任务和不清晰片段时,清晰任务继续,Risk 只承载不清晰片段。
- 重复投递、真实新邮件、revision、历史底色遗留和业务内容相同是不同判断维度;由 Validator 结合证据、消息幂等键和生命周期处理。
## 5. 固定渠道材料与 Parser 边界
### 5.1 预处理为何独立
Excel、图片和正文的原始材料体积大、结构多变且含历史内容。预处理把“能安全给 Parser/Agent 的本次材料”缩小为可定位、可审计的引用集合,因此 Agent 不必读取整张工作簿或整段会话。
- current body 和 quoted history 必须分开;quoted history 只能辅助理解、继承身份或提示重复,不可再次触发动作。
- Excel 附件保留工作簿/Sheet/行/列/底色/哈希等证据;普通任务 API 不返回整行原文。
- 图片作为 `IMAGE` 材料进入预处理。它可辅助判断 Trace、Payment/Voucher 或不在范围,但不因“有图片”自动创建业务卡。
- 无附件邮件仍经过第 1 层接入和第 4 层 Context;仅跳过 Excel 专用预处理与 Parser。
- 对 Parser fallback,信息系统可从 current subject/body 生成受控 Agent excerpt,并提取唯一明确的 Group Code 或 old→new relation 供 Context 定向查询;这不是把全文、quoted history 或附件重新交给 Agent。
### 5.2 严格底色与 Profile
- 固定渠道 Profile 必须同时满足文件信号、明确业务 Sheet 规则和表头签名;平分、未知或非法 Sheet 均停止确定性解析,进入 Risk/fallback。
- `STRICT_CURRENT_CANDIDATE` 必须在 Catalog 定义的业务范围内整行非白底。字体颜色、批注、条件格式推测和白底不计入。
- anchor 行提供身份/明细列;合法 continuation 行仅补动作/状态列。任意多行互补都不能升级为确定事实。
- 未知房量保持 `booking_type=null/UNRESOLVED`,不能按 0 推断 FIT;Trace 部门只有邮件证据唯一明确时预填,否则由用户选择 FO、HSK 或二者。
### 5.3 改团号与 Trace 生命周期
- old→new 团号只在 current body 明确标注后进入 `GROUP_CODE_REPLACEMENT`;Context 只读 old/new 两个 Group Code,old 有效且 new 不存在才允许 Update 继续。两个普通团号、历史引用或多条矛盾关系均进入复核。
- 同团同封的 standalone Trace 在信息系统内合并为一张候选卡,保留每条服务项和证据;跨封 Trace 绝不并入旧卡,Context 只以无自由文本的时间序摘要提供历史顺序。
- Trace 的最终确认至少选择 `FO` 或 `HSK`,可同时选择二者;本期确认不触发部门流转。
## 6. 数据与事实源
- 新 Booking 主线的事实源是 PostgreSQL schema `th_hotel_booking`。处理运行、版本化契约、证据引用、候选、校验和确认投影均落入该 schema。
- 旧 MySQL V4 数据仅作历史兼容读取;禁止未定义双写、跨库事务或把 MySQL 记录当作新主线事实源。
- 每次读取 Context 必须按 Group Code、订单线索或已知 SourceMessage 定向查询;无目标线索时不能扫描全库找“最像”的订单。
- 主数据(渠道白名单、sender → Account/Market/Source、Rate Code 映射)也是版本化事实。零候选、多候选和未配置均保留待用户补充,不能猜测。
## 7. 接口与并行工作边界
后续实现可以并行,但只能依赖 contracts-v1:
- Track A:`BookingMessageOrchestrator` 和入口适配器。
- Track B:Booking Agent profile、prompt、skill/reference 与离线 contract tests。
- Track C:Context/lifecycle assembler。
- Track D:PostgreSQL repository、Flyway、主数据与 processing run。
四条线不能直接依赖对方内部 Entity、Parser 私有 record 或 AgentBus payload。共享只通过 contracts-v1 的版本化数据结构、错误码和 evidence reference。
## 8. 实施前置与验收
G1 通过条件:信息系统、Agent、Context、数据库、Validator、前端和 QA 能在不引用旧 architecture-v0.3 的前提下,只基于 contracts-v1 明确输入、输出、版本字段、状态机、结果类型和失败边界后开始实现。
与现有 V0.1 的关系:V0.1 保留为受控纵向切片和回归基线;在 contracts-v1 适配完成前,不以其旧 V4 内部结构作为新模块之间的接口。