Files
msgexchange-v2/docs/contracts/interface-contract.md
T
windyboy 9909dbd7e0 docs(acm2-75): 收敛 Kafka 口径并清掉航班版本号残留
- Kafka「尚需确定」去掉消费者去重与版本标识,改为消费方的字段要求
- `schd` 落定内容(`SCHD.FLTR` JSON,空字段不输出)、删除不进本主题、批次边界为定时 tick
- `Q1` 收窄为 record 粒度(`C-9` 每条一条 vs 旧系统整批一个数组)
- `Q5` 由版本标识改为 `msg` 的字段、编码与删除区分
- 删除航班版本号表述:README 事实归属的 `STATE_VERSION`、契约 `FLIGHT_SCHD` 的版本字段、验证映射 `INV-4`
- 删除 requirements 的「本版本主要新增能力」changelog 句
2026-09-18 08:47:27 +08:00

148 lines
16 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.
# 接口契约草案
本文记录 msgexchange-v2 与联调工具、运营航班显示界面、CIIMS adapter、admin-api、Elasticsearch 航班历史存储之间需要共同遵守的接口:收报、出站请求与应答、Kafka 通知、Redis 查询投影、共享信箱、参考数据与航班历史。
范围由 [requirements.md](../requirements.md) 与 [architecture.md](../architecture.md) 确定,出处随各条标注;未列出的字段不能作为字段级联调依据。
旧项目用户故事文档([legacy/](../legacy/))只供字段核对,不作为新版契约的依据。
## HTTP
| 接口 | 请求契约 | 成功响应契约 | 失败契约 | 尚需确定 |
|---|---|---|---|---|
| `POST /cminmsgs/send` | 请求体是 XML 原文;接受 `text/xml``application/xml``text/plain`,默认 UTF-8;仅限内网,网络层限制来源。 | 报文写入 `CMINMSGS` 后返回信箱编号;写入的报文与上游投递走同一条处理路径、效果一致;该响应只证明已落信,不证明业务处理或下游投递(`US-02`)。 | 空报文、超大小上限、非法 XML 不落信并返回错误;写信失败不返回编号;XML 解析禁用外部实体和外部资源访问。 | 大小上限、请求编码与 `Content-Type` 的精确处理规则、HTTP 状态码、成功/失败响应体字段及样例。 |
| `POST /schd/sync` | 触发一次 `RQFD` 日计划请求;请求字段尚未定义,登记与落信规则见「在途与作废」。 | 响应内容尚未定义;无论表示登记还是落信,都不代表 AODB 已收到。 | 错误响应尚未定义。 | 请求字段与时间格式、成功响应表示已登记还是已落信(`Q16`)、状态码、响应字段及样例。 |
| `GET /all/flights` | 无已定义的请求字段;从 Redis 投影读取当前全部动态航班,不含共享航班,与网页客户端同源(`US-12`)。 | 返回查询到的全部航班,不分页;JSON 由消息文档中的 XML 结构转换而来(`Q21`)。 | Redis 异常时返回错误,不能返回空列表伪装成功。 | 状态码和错误响应样例;外层包装是否沿用旧 `ResponseDto`。 |
旧系统线索(来源:旧项目用户故事「HTTP 接口清单」「日计划请求」):
- 三个接口共用 `ResponseDto`,字段为 `is_success``err_code``err_msg``body`
- `POST /cminmsgs/send` 的成功 `body``CMINMSGS_ID`,样例为 `{is_success: true, body: <ID>}`
- `GET /all/flights``body` 是非共享航班的 `SCHD.FLTR` 列表。
- `POST /schd/sync` 的请求体是 `{startDate, endDate}`,时间格式 `yyyy-MM-dd hh:mm` 用无 AM/PM 的 12 小时制。
- 出站报文用 `TYPE=RQFD``STYP=NONE``SNDR=OSH5`,日期范围编码为 `RQFD.STDB` / `STDE`
这些字段是否沿用、时间改用何种无歧义格式,都要核对后定稿。
新版日计划是 AODB 当前时刻的完整航班列表(`US-07`),请求是否仍带日期范围由这条全量语义判断。
## 入站报文与请求应答
AODB 经 CIIMS adapter 把 XML 报文写入 `CMINMSGS`,格式以架构指定的 [SIS 接口规范](../legacy/SIS_AODB_RMS-V0.1.md) 与 [XSD](../legacy/unisysaodbsis.xsd) 为依据。
入站报文按类型处理:`ADFT` 建立计划外航班,`FLOP` 改航班动态,`FDEL` 删航班,`SCHD-DNLD``SCHD-RESP` 同步日计划快照,参考数据写入 `REF_MASTER``US-04``US-07``US-13`);报文不合法进死信,合法但本系统不支持的类型跳过留档并按已处理写回信箱(`US-03`)。
| 环节 | 已确定的边界 | 尚需确定 |
|---|---|---|
| 出站请求 | 本系统只发 `RQRD` 参考数据请求与 `RQFD` 日计划请求,经 `COUTMSGS` 落信,交付承诺止于落信(`US-09`;架构「系统定位与范围」「主流程」)。 | 报文类型与子类型清单、发送方取值、时间与序号的构造规则。 |
| 在途与作废 | `RQRD``RQFD` 各自同时最多一条已落信、未结案的请求;同一子类型发新请求时旧请求作废,新请求登记为待发送,等该报文类型的在途请求收到应答、失败或超时后再落信;请求超过时限未等到应答标记超时(`US-09`)。 | 超时的时限取值。 |
| 应答匹配 | 应答按报文类型对应到等待中的请求;AODB 发错或迟到的应答不更新数据,记录后跳过(`US-09`);`SCHD-RESP` 只在请求未过期时生效,迟到的应答不更新数据(`US-07`)。 | 请求与应答的对应字段、过期判定的依据字段。 |
| 错误回报 | 收到 `EROR` 时定位到本系统发出的请求,标记失败并告警(`US-09`)。 | `EROR` 与请求的对应字段。 |
## Kafka
| 主题 | 已确定的消息语义 | 尚需确定 |
|---|---|---|
| `msg` | 单条航班变更通知;航班动态与删除处理完成后投递;发送失败自动重试,一直失败的记录保留可查并告警(`US-08`);同一 `FLID` 的变更保序,对外按至少一次投递。删除通知的来源有三处:`FDEL` 删除(`US-06`)、日计划快照缺席删除(`US-07`)、历史清理在物理删除前必要时登记(架构 `D1`)。 | Kafka value 的字段与类型、变更和删除的区分方式(`Q5`)、编码方式、分区规则。 |
| `schd` | 定时批量发送最新航班状态;内容是 `SCHD.FLTR` 序列化出的 JSON,空字段不输出,字段与类型见 [XSD](../legacy/unisysaodbsis.xsd) 的 `FLTR`;边界是定时任务的一次 tick,两次 tick 之间积累的变化整批发一次,没有变化就不发;删除航班不进入本主题,由 `msg` 发一条删除通知;发送失败自动重试,对外按至少一次投递(`US-08`)。 | “批量”对应的 Kafka record 粒度(`Q1`)。 |
旧系统线索(来源:旧项目用户故事「前端通知」「动态类(FLOP-*)处理」):
- `msg` 的 value 是 `MSG` 的 JSON,含 `META` 与对应业务体;日计划到达通知只有 `META`
- 只对非共享航班的变更单条下发,共享航班随主航班下发;例外是删除,共享航班被删时也单独发一条 `msg` 删除消息。
- `schd` 把窗口内航班组成 `SCHD.FLTR` 数组 JSON,队列为空时不发送。
跨航班顺序不构成契约。
测试环境与生产隔离的前提见 [specification.md](../specification.md) 的 `PRE-9``OPS-3`)。
## 存储读写边界
### 共享 MySQL:外部信箱
| 表 | 本系统的操作 | 需要对接方提供的物理契约 |
|---|---|---|
| `CMINMSGS` | 按信箱编号升序、分批读取未处理的报文,扫描与回写用同一处理时间列;兼容 HTTP 入口写入 XML 原文;处理完成后写入处理完成时刻,只填空值、不覆盖已有值;写回失败由后台任务重试,一直写不上的记录保留在案并告警(`US-01``US-02``US-10`)。 | 表 DDL、信箱编号与报文原文字段、处理时间列的列名、类型与可空性及写入样例(处理标记即该处理时间列,见 [specification.md](../specification.md) 的 `C-5`)、写入必需列、原文保留期和索引;信箱编号按到达顺序单调递增、不复用、不回退的保证(架构「必须保持的约束」)。 |
| `COUTMSGS` | 写入 `RQRD` 参考数据请求与 `RQFD` 日计划请求;CIIMS adapter 消费。交付承诺止于请求落信;写入结果不明时记录并告警,不直接重发(架构「主流程」)。 | 表 DDL、请求原文字段、写入必需列、编号生成方式、重复落信的识别规则。 |
共享 MySQL 归 CIIMS adapter 方所有;本系统不建表、不改表结构、不清除数据,也不写共享历史表。外部表的物理字段必须以对接方提供的现行 DDL 与读写样例核对,不能由本文件推造。
旧项目用户故事「数据表列清单」提供以下**旧系统实体映射列名**,不是现场 DDL、可空性或写权限的证明:
| 表 | 旧系统实体映射列名 | 旧系统写入线索 |
|---|---|---|
| `CMINMSGS` | `CMINMSGS_ID``CMINMSGS_CLOB_MSG``CMINMSGS_DATE_RECEIVED``CMINMSGS_DATE_PROCESSED``CMINMSGS_STATUS``CMINMSGS_SUBSYSTEM_DATE_SENT``CMINMSGS_SUBSYSTEM_NAME``CMINMSGS_SUBSYSTEM_SEQUENCE``CMINMSGS_SUBSYSTEM_SUBTYPE``CMINMSGS_SUBSYSTEM_TYPE` | 兼容入口写原始 XML 与接收时间,处理时间为空;旧系统的扫描与回写都落在 `CMINMSGS_DATE_PROCESSED`(旧项目用户故事「术语与数据语义」);新版必须先按 `US-02` 校验 XML。 |
| `COUTMSGS` | `COUTMSGS_ID``COUTMSGS_ACK_DATE_RECV``COUTMSGS_ACK_REQD``COUTMSGS_ACK_RESEND_TIMES``COUTMSGS_CLOB_MSG``COUTMSGS_DATE_INSERTED``COUTMSGS_DATE_SENT``COUTMSGS_ENCRYPT``COUTMSGS_ERROR``COUTMSGS_FINAL_GROUP_IND``COUTMSGS_GROUP_ID``COUTMSGS_GROUP_ORDER``COUTMSGS_NO_MESSAGES``COUTMSGS_TRUEFALS_GROUP``ROUTINGID` | 旧 `/schd/sync` 写报文 XML、插入时间与 `ROUTINGID=OSH5RQFD`;ACK/错误列的写入责任仍未确认。 |
### Redis:航班查询投影
| 存储 | 承载内容 | 边界 | 尚需确定 |
|---|---|---|---|
| Redis | 航班查询投影 | 只作查询,不是权威,也不存处理状态;只由本系统写入和移除,网页客户端与 `GET /all/flights` 读同一份,内容来自自有 PostgreSQL 的航班当前态;写投影成功、删除时移除成功,才算对应消息处理完成(架构「数据归属与一致性」;`US-05``US-06`)。 | 网页客户端读取约定(`Q6`)。 |
旧系统线索(来源:旧项目用户故事「Redis key 汇总」「术语与数据语义」「动态航班转历史」):
- 投影是 hash `flightInfo`field 为 `FLID`value 为完整 `SCHD.FLTR` 对象的带类型 JSON,不设过期;Redis 里没有名为 `schd` 的 key`schd` 只是 Kafka 主题。
- 写入路径:日计划下载(`DNLD``RESP`)整体写入当天航班,单条变更(`ADFT``FLOP`)只写对应的一条,转历史时按 `FLID` 逐条移除。整体写入不删除本次映射中缺席的航班,与 `US-07` AC5 相反,新版按 `US-07` AC5 刷新。
- 写入前生成主航班的共享航班列表 `MAFL``G-MAFL`)并拼出登机桥字段 `abdg`,两者是否为网页客户端所需仍未定(`Q6`)。
- 旧系统 Redis 另有两条机位基础数据缓存,都由本系统调用 admin-api 填充、过期 3600 秒:`orms_stand`field 为机位代码,value 为 `OrmsStand` 对象的带类型 JSON);`orms_stand_airbridge`field 为机位代码,value 为登机桥代码数组的 JSON 字符串,不是对象)。这两条是旧系统按计划机位拼 `abdg` 的数据来源,本版不交付(需求「范围与非目标」)。
### 自有 PostgreSQL:内部存储与 admin-api 只读
| 表或表组 | 边界 | 尚需确定的字段级契约 |
|---|---|---|
| `REF_MASTER` | 静态参考数据与资源状态按类别、编号保存在独立数据表,admin-api 直接只读;新消息覆盖旧记录,全量消息整体替换,增删改消息逐条处理(`US-13`);一类校验不通过只停这一类、其他类照常,校验失败类别的已有记录不变;字段为空表示「当前没有值」,不是删除(架构「必须保持的约束」)。 | 类别和编号的物理列、各类别字段及类型、主键/唯一键、空值在列中怎样保存、写入后何时可读。类别范围与消息中的识别标签见下表。 |
| `FLIGHT_SCHD`、资源明细表、`FLIGHT_ROUTE_POINT` | 航班当前态的唯一权威;`FLID` 唯一(架构「必须保持的约束」);Redis 和 Kafka 从处理结果派生,不反向覆盖这些表。 | 主键、字段与类型、资源明细表清单、外键/索引与迁移 DDL。 |
| `PROC_STATE``MSG_EVENT``REQ_TRACK``SCHD_SNAP_LOG``PIPELINE_LOCK``UNMAPPED_FIELD` | 管道处理、待发事件、请求跟踪、留痕、互斥及未映射字段由本系统维护;不对外提供直接读写接口。 | 字段、约束、索引与迁移 DDL 由内部实现设计确定;若其他系统需读取,须另立读取契约。 |
自有 PostgreSQL 的物理表结构由本系统的迁移 DDL 定稿。生产环境若改用 Oracle 11g,字段类型与迁移方案需先完成适配验证。
### 静态参考数据类别与编号来源
类别码与识别标签来自架构引用的 [SIS 接口规范](../legacy/SIS_AODB_RMS-V0.1.md);识别同一条参考记录时,用类别码加识别标签值。标签值的格式、标签在哪个范围内唯一,以及保存到 `REF_MASTER` 的方式,仍需在本系统的表结构中明确。
| 类别码 | 类别 | 消息中的识别标签 | SIS 依据 |
|---|---|---|---|
| `COUL` | 国家代码 | `COUC` | 「AODB country codes event」 |
| `ARPT` | 机场代码 | `ITCD` | 「AODB airport codes event」 |
| `AIRL` | 航空公司代码 | `ITOP` | 「AODB airline codes event」 |
| `AIRC` | 机型代码 | `ITAT` | 「AODB aircraft codes event」 |
| `REGN` | 注册号 | `RNUM` | 「AODB registration codes event」 |
| `ORGN` | 机构代码 | `OGID` | 「AODB organization codes event」 |
| `FLTL` | 航班类型代码 | `FTYP` | 「AODB flight type codes event」 |
| `TLST` | 航站楼代码 | `TCOD` | 「AODB terminal codes event」 |
| `GLST` | 登机门代码 | `GCOD` | 「AODB gate codes event」 |
| `SLST` | 机位代码 | `SCOD` | 「AODB stand codes event」 |
| `CLST` | 值机柜台代码 | `CCOD` | 「AODB check in counter codes event」 |
| `BLST` | 行李转盘代码 | `BCOD` | 「AODB carousel codes event」 |
| `CHLT` | 行李滑槽代码 | `CCOD` | 「AODB chute codes event」 |
资源状态是第十四类消息,类别码为 `RSTA`SIS 接口规范「AODB resource status event」),识别一条资源状态时须同时使用资源类型 `RTYP` 和资源编号 `RSID``CLST``CHLT` 都使用 `CCOD` 标签,因此不能脱离类别码识别记录。
## Elasticsearch 航班历史写入
| 契约项 | 已确定的边界 | 尚需确定 |
|---|---|---|
| 写入对象 | 满足 `US-14` 已结束判据的航班从自有业务数据库写入 Elasticsearch 历史库,作为历史查询副本。 | 历史索引名称、文档 ID、写入字段及类型、嵌套资源结构、字段缺失与删除状态的表达方式、索引保留期与容量上限(架构「数据归属与一致性」列为未定)。 |
| 成功确认 | 只有该航班的历史写入成功,才允许从实时数据物理删除;删除前按 `D1` 必要时登记待发删除事件。 | Elasticsearch 写入响应中何种结果算成功、成功是否要求可查询、批量响应如何逐项确认。 |
| 写入粒度 | 单个航班写入失败不影响其他航班。 | 使用逐条请求还是批量请求、批量大小、部分成功时的确认与继续处理规则。 |
| 失败与重试 | 写入失败的航班保持在实时数据中,下次运行再试;已写入的航班不重复写入;正在被消息处理的航班跳过,下轮再处理。 | 超时或响应不明时的对账方式、可重试错误分类、重试间隔、文档 ID 和覆盖策略如何保证幂等。 |
旧系统线索:逐航班按 `SODT + FLID` 查询旧索引 `flight_hts`,存在则更新、不存在则新增;写入内容是 `SCHD.FLTR` 序列化后的 JSON,单条写入失败跳过该航班(旧项目用户故事「动态航班转历史」)。
## 待决事项
由本系统与需求方确定的事项见 [specification.md](../specification.md)「本系统与需求方待决」。
## 定稿所需证据
1. 核对三个 HTTP 接口的旧系统线索,取得成功和失败响应样例、实际状态码及 `/schd/sync` 的无歧义时间格式。
2. 运营航班显示界面的 `msg``schd` 消费样例和字段要求,特别是变更、删除、重复投递的处理方式。
3. CIIMS adapter 方提供的 `CMINMSGS``COUTMSGS` 现行 DDL、读写样例和写权限说明,核对旧系统实体映射列名,并确认信箱编号单调递增、不复用、不回退。
4. 13 类参考数据与资源状态的编号规则,以及自有 PostgreSQL 的迁移 DDL。
5. 网页客户端读取 Redis 投影的约定,含它需要哪些字段(`Q6`)。
6. AODB 应答与 `EROR` 样例,含请求与应答的对应字段、超时判定依据。
7. Elasticsearch 历史索引映射、文档样例、逐条或批量写入响应、索引保留期与容量上限,以及写入结果不明时的对账规则。
只有上述证据核对完成后,待定字段才能转为字段级契约;任何新增字段、默认值或错误码都需写明其来源与对接方。