docs(acm2-74): 补齐 FLOP 逐类语义、静态参考数据与数据结构

自洽与精简:

- specification 补第四种状态词 [我们自证]、验证映射补 INV-14 两行、去 CLM-7/CLM-9 的进度语、补编号空缺说明
- architecture/requirements/implementation 去除逐字复述(领域决策三写句、时间常数排序、C-25/C-26、INV-12/21/22)与参数值重复
- README 与新文档对齐:收报谓词改 ID>W、删不存在的 reference/ 包与 lua/、删 msgx.phase 与 MSGX_REDIS_URI、设计权威口径改 docs/、进度段改指 Plane

内容补齐:

- 新增 implementation.md「动态运行事件(FLOP)」:按 SIS 3.19–3.43 的 25 类逐类映射与空标签语义(含 CNCL 空标签为撤销等),补 RMS→AODB 方向拒绝、ROUT 只保留 4 条、VIPP 忽略等约束;厘清 legacy 29 类与 SIS 25 类的差集
- 新增 implementation.md「静态参考数据」章:13 类参考数据与资源状态的 RTYPE/RKEY、list 与增量合并语义、删除只由 DEL 表达、SLST/REMT/RSTA 机位与登机桥映射
- §11.3 数据结构改为标量分组表与集合明细表(元素键、条数上限、SIS 锚点)
- specification 新增 G-FLOP-DIRECTION / G-FLOP-UNMAPPED / G-REF-DATA;Q8 收窄为真实报文分布与 admin-api 清单
This commit is contained in:
windyboy
2026-09-14 07:34:17 +08:00
parent cedd859bdf
commit 5b7938ac4b
6 changed files with 206 additions and 98 deletions
+144 -23
View File
@@ -1,9 +1,10 @@
# 实现设计
本文件是实现设计的唯一出处,分章:
本文件是实现设计的唯一出处,分章:
- **处理管道**章:记录模型、状态机、收报与水位、主泵与事务边界、回填、快照与请求、投递、失败恢复与维护作业;
- **航班域**章:航班当前态的权威模型、合并与写入语义、删除与重建
- **航班域**章:航班当前态的权威模型、合并与写入语义、删除与重建
- **静态参考数据**章:主数据类别与编码、`REF_MASTER` 结构与合并语义、资源状态与机位/登机桥映射。
正文描述**目标设计**,不标注交付状态:可声明性见 [specification.md](specification.md)「声明边界」与「当前已知偏差」,进度在 Plane(ACM2)。契约与不变量只引稳定 ID;参数取值只引 `PARAM:<完整键>`(见 [reference.md](reference.md))。
@@ -27,7 +28,7 @@
| `PROC_STATE` | 入站消息的处理状态、身份、尝试次数、错误原因与回填事实 | `MSG_ID = CMINMSGS_ID` 主键防重复入队;`IDENTITY_KEY` 唯一约束防业务重复;按最小未完成 `MSG_ID` 取队头;`BACKFILL_NEXT_AT` 非空 = 还欠一次回填,`BACKFILL_AT` 非空 = 标记已确认,`BACKFILL_ABANDONED_AT/REASON` 非空 = 已停止自动重试(**不等于**标记已确认);`RECEIVED_AT` 复制自信箱接收时间、**可能为 NULL**、仅用于对账与展示;`ENQUEUED_AT` 是本地入队时间、非空、是超期判据的唯一依据;归档后的去重影子行置 `STATE='ARCHIVED'`、只保留 `IDENTITY_KEY``MSG_ID`,不占队头、不触发回填、不参与积压聚合(`G-PROC-HST`)。 |
| `MSG_EVENT` | 等待投递的事件(outbox) | `EVENT_ID``KAFKA:msg` 是稳定事件身份并决定投递顺序;对 `KAFKA:schd` 是每次接受 upsert 时替换的写代次。`TARGET` 区分 `KAFKA:msg` / `KAFKA:schd``PARTITION_KEY` 当前取 `FLID``Q4` 定案前为假定,见 `C-29`);`EVENT_TYPE` 区分 UPSERT 与 TOMBSTONE。`KAFKA:schd``FLID` 单行 upsert,只保留最新 `STATE_VERSION``SENT_AT` 在投递确认的同一条 UPDATE 内写入,是保留期判定的唯一基准。 |
| `REQ_TRACK` | 上游请求及应答关联 | 状态 `PENDING / SENT / DONE / EXPIRED`;保存请求类型、覆盖运营日、发送方、出站信箱 ID 与发送/完成时间;**「同类只允许一个开放请求」的唯一键 = `(请求类型, 覆盖运营日, 发送方)`,且仅对开放状态生效**。 |
| `REF_MASTER` | 静态参考数据(目标表) | `(RTYPE, RKEY)` 唯一;客户端与刷新流程见 [requirements.md](requirements.md) `US-13`/`US-14`。 |
| `REF_MASTER` | 静态参考数据与资源状态(目标表) | `(RTYPE, RKEY)` 唯一;`RTYPE` 类别、合并语义与资源状态见「静态参考数据」;取数路径见 [requirements.md](requirements.md) `US-13`/`US-14`。 |
| `FLIGHT_SCHD` | 航班标量及单值异常字段 | `FLID` 主键;`OPERATION_DAY` 一经确定不可变;版本与最近消息 ID 用于追踪。变长集合存于资源明细表与 `FLIGHT_ROUTE_POINT`,规则见「航班域」。 |
| `INBOX_CURSOR` | 消费水位 `W`、空洞计时 `holeSince`、播种事实 `SEEDED_AT` | 单行游标;`W` 只随新 ID 成功入队推进,遇空洞即停;`HOLE_SINCE` 持久化空洞观测时刻,进程重启不丢计时。`SEEDED_AT IS NULL` **不等于**从未消费(已有库新增列后同样为 NULL)。 |
| `SCHD_SNAP_LOG` | 日计划处理留痕 | 只追加、可重建,不参与状态决策;保留期见 [reference.md](reference.md)。 |
@@ -344,16 +345,11 @@ PENDING → SENT → DONE
归档范围只含终态;归档后仍须保留业务去重能力(`INV-9`)——去重记忆期长于工作状态在线期,实现取「主表保留去重影子行」:主行置 `STATE='ARCHIVED'`、只留 `IDENTITY_KEY``MSG_ID``IDENTITY_KEY` 唯一约束留在主表不动。队头推进、`backlog()` 与回填扫描的谓词显式排除 `ARCHIVED`,不靠状态包含列表隐式过滤。
**时间常数排序**(取值见 [specification.md](specification.md)「契约数值」)
1. `R ≤ R_keep``C-7`)。
2. 去重记忆期 ≥ `R_keep`;否则「归档后重复」不成立(`INV-9`)。
3. 回填放弃清单可见期 ≥ `R_keep`;否则库方清除缺 `C-8` 依据(`C-16`)。
4. 归档阈值计的是**终局之后**的时间,不是入队之后:终态行未了结回填时不进入候选。
**时间常数排序**`R ≤ R_keep`、去重记忆期 ≥ `R_keep`、放弃清单可见期 ≥ `R_keep` 三个下界关系的定义与理由见 [specification.md](specification.md)「契约数值」,本文件不复述。只补一条实现口径:归档阈值计的是**终局之后**的时间,不是入队之后——终态行未了结回填时不进入候选。
**其余清理**
- **航班历史清理**:按 [reference.md](reference.md) 的历史判据选候选(含 `DELETED`),先成功归档再删除;未经 FDEL 的生命周期清除需先补发删除事件。语义与红线见「航班域」。
- **航班历史清理**:按 [reference.md](reference.md) 的历史判据选候选(含 `DELETED`),先成功归档再删除;语义与红线见「航班域」`D1`
- **留痕清理**`SCHD_SNAP_LOG` 按保留期与 `(SCOPE_END, RECV_AT)` 删除,不依赖历史存储开关。
- **出站事件清理**:见「事件清理」。
@@ -380,8 +376,6 @@ PENDING → SENT → DONE
- 单活动主泵按信箱 FIFO 推进。事务内 `PIPELINE_LOCK` 只串行化本地状态提交,不替代选主或消息认领。
- 状态写入、outbox 事件、处理终态和回填意图在同一 PostgreSQL 事务中提交(`INV-17`);回填与 Kafka 投递在提交后独立重试。
现场目标库为 Oracle 11g;Oracle 适配必须通过方言与集成验证后才能作为可切换的运行时选项。
### 11.1 权威模型
| 对象 | 职责 |
@@ -398,32 +392,60 @@ PENDING → SENT → DONE
`FLID` 是主键。`OPERATION_DAY` 从 SCHD 记录的 `SODT` 按配置的机场时区和切日规则推导;它不是消息接收日或落库日。
一旦已写入非空 `OPERATION_DAY`,同一 `FLID` 不得改到另一个运营日(`INV-12`)。遇到冲突,整包日计划按协议错误拒绝,既有状态保持不变(`INV-19`)。尚未由日计划收录的航班可以为 `NULL`;这不表示该航班没有运营日,只表示当前模型无法为它确定归属日。
运营日一经写入不可更改`INV-12`)。遇到冲突,整包日计划按协议错误拒绝,既有状态保持不变(`INV-19`)。尚未由日计划收录的航班可以为 `NULL`;这不表示该航班没有运营日,只表示当前模型无法为它确定归属日。
### 11.3 字段与集合
标量与异常对象前缀字段存于主表。协议中的 `SRVT``VIPF` 是无界集合,目标形态必须按集合完整保存到专用明细表示;专用明细、合并与投递见 `G-SRVT-VIPF``MAFL` 不是 SIS/XML 入站字段,而是由共享航班的 `MAID``FLID``FLNO` 生成的主航班派生投影(`G-MAFL`
航班当前态分三层:主表标量、集合明细、路线点。**键名一律取 SIS 标签名**(不改写、不合并同义标签),集合元素内的键取属性名或子标签名。字段的业务语义、值域与长度以 [SIS 接口规范](legacy/SIS_AODB_RMS-V0.1.md) 与 [XSD](legacy/unisysaodbsis.xsd) 为准;本节只定义目标形态与合并语义
**标量**(存于 `FLIGHT_SCHD` 主行,出现即覆盖;空串为显式清空)
| 组 | 标签 |
|---|---|
| 身份与计划 | `ALCD``ALSC``FLNO``MVIN``SODT``FLTY``FLIN``ACFT``RENO` |
| 班次与运营 | `TAOP``TAFL``TAID``TRML``CSOP``CSFT``MAID` |
| 时间 | `ESTT``ACTT``BOTM``LACL``FINT``APPT``EGSR``EGST``PADT``NAAT``NEAT``PEDT``FTSS` |
| 资源与状态 | `STND``PHAG``FHAG``MHAG``CNCL``REMC``MAXP``VIPP``VIPR``LBNO``LBWT``PAXC``EXSC``EXSR` |
**集合**(存于明细表;报文带了该集合就按完整合并结果整体替换,元素顺序取报文顺序;未出现则保留本地值)
| 集合 | 元素键(属性在前) | 条数上限 | 定义处 |
|---|---|---|---|
| `GTDT` | `GTNO``GATE``PGOT``PGCT``GOTM``GCTM``GTYP` | 99 | `SIS:3.34` |
| `CKDT` | `CKNO``CHKC``CCLS``PCOT``PCCT``COTM``CCTM``CTYP` | 99 | `SIS:3.24` |
| `CLDT` | `CLNO``BELT``BCLS``PCOT``PCCT``FBAG``LBAG``BTYP` | 99 | `SIS:3.25` |
| `CHDT` | `CHNO``CHUT``CCLS``PCBT``PCET``CBTM``CETM``CTYP` | 99 | `SIS:3.26` |
| `PSDT` | `PSNO``PSST``STST``STET` | 9 | `SIS:3.38` |
| `CHOT` | `CSNO``CHTM``CHID``CHST` | 99 | `SIS:3.22` |
| `DELY` | `CODE``STRT``DURA`、文本 | — | `XSD` `FLOP` 段 |
| `ABTM` | `ASNO``ABDG``ABOP``AOTM` | 99 | `XSD` `FLOP` 段 |
| `ROUT` / `ERUT` | `RTNO``APCD``SCAT``SCDT` | 6 / 7`ROUT` 只取 4 | `SIS:3.40` |
| `SRVT` | `OPER``SRTC``SRQT``SRST``SRET``SRPR``SANR``SARR` | 无界 | `G-SRVT-VIPF` |
| `VIPF` | `OPER``VPCD``VFES``VIPT/OPER``VIPT/VSCD``VIPT/VTQY``VIPT/VTST``VIPT/VTET` | 无界 | `G-SRVT-VIPF` |
`SRVT``VIPF` 只保留出现事实与原始内容,不参与合并与投递。`MAFL` 不是 SIS/XML 入站字段,而是由共享航班的 `MAID``FLID``FLNO` 生成的主航班派生投影(`G-MAFL`)。
- `ORDINAL` 是持久化顺序,从 1 开始;`SOURCE_SEQ` 是上游序号,允许为空或重复。
- 相同资源号不代表同一条分配,禁止按资源号去重。
- 每次持久化完整航班状态时,明细表按该 `FLID` 先删后插,以完整合并结果为准(`INV-14`)。
- ROUT 与 ERUT 是两类独立集合,不能因相同序号覆盖彼此。
- `CHDT` 的类字段在 SIS 正文写作 `CCLS`/`CTYP`、在 `XSD` 写作 `CHCLS`/`CHTYP`**以 `XSD` 为准**。
- 主/共享关系以主表的 `MAID` 为事实来源:`MAID` 是共享航班指向主航班 `FLID` 的引用(非共享航班为 `NULL`);`MAFL` 只在读取和事件投影时从子航班事实派生,不按入站标量解析或保存。
### 11.4 主/共享投影(`MAFL`
`MAFL` 是主航班的派生集合,元素为子航班的 `FLID``FLNO`;内容与变更传播分别由 `INV-21``INV-22` 保证。
- 子航班集合 = `STATE = ACTIVE``MAID = 主航班 FLID``FLIGHT_SCHD` 行;已 FDEL 的子航班(`STATE = DELETED`)自然退出投影,不需要改写主航班行。
- 已 FDEL 的子航班(`STATE = DELETED`)自然退出投影(内容见 `INV-21`,不需要改写主航班行。
- 只有 `MAID` 为空的主航班携带 `MAFL`;共享航班只携带自身 `MAID``CSOP``CSFT`,不携带 `MAFL`,避免下游双向合并。
- 投影按 `FLID` 升序,与到达顺序及 `FLNO` 变更无关:同一 `STATE_VERSION` 的投影逐字节稳定,重发与消费端比对才有意义。
- 同一 `STATE_VERSION` 的投影逐字节稳定(顺序见 `INV-21`),与到达顺序及 `FLNO` 变更无关;重发与消费端比对才有意义。
- `MAID = FLID` 的自引用行不进入任何 `MAFL``MAID` 指向不存在主航班的悬挂引用不阻断该子航班自身处理,只是不产生投影。
- 子航班集合变化(新增、删除、`MAID` 迁移)必须让涉及的主航班在同一事务内推进 `STATE_VERSION` 并登记主航班事件(`KAFKA:msg` + `KAFKA:schd`;否则整态投影的只进不退写入会丢弃它(见「`schd` 聚合」)。共享航班自身不单独发通知。
- 子航班集合变化的传播见 `INV-22`,事件类型为 `KAFKA:msg` + `KAFKA:schd`;否则整态投影的只进不退写入会丢弃它(见「`schd` 聚合」)。共享航班自身不单独发通知。
- 派生主航班投影与产生它的状态写入必须同一事务或一致读快照;按 `MAID` 取子航班要求该列有索引(`INV-17`)。
## 12. 航班域:合并、删除与生命周期
领域决策逻辑(如 `FlightStateEngine` 及各类 Handler 规则)保持纯粹:它根据当前完整态和已解码报文,返回下一完整态与待发事件,不执行数据库或 Kafka I/O。处理器是事务协调器,负责在统一事务边界内调用决策逻辑并持久化结果(`US-03``INV-17`)。
本章的领域规则只描述「合并成什么态」;决策纯度、事务边界与落库职责见「消息、身份与决策」与 `INV-17``US-03`)。
### 12.1 SCHD 日计划
@@ -431,15 +453,51 @@ SCHD DNLD/RESP 在整包校验通过后,逐条将报文携带的航班写入
日计划在重叠字段上可以覆盖当前动态值;未携带的字段按合并规则保留,显式清空才清除。每个成功写入的航班推进 `STATE_VERSION``INV-13`),并在同一事务登记 `KAFKA:schd``KAFKA:msg` 事件。
**字段缺失语义与外部规范冲突**SIS 规定最新日计划中未发送的可选字段表示 AODB 已无该数据、子系统应删除本地已有值(`SIS:3.16-note-4`RESP 与 DNLD 同格式,见 `SIS:3.17`),并要求以 AODB 最新数据覆盖本地(`SIS:1.6.2`。这与上面的「未携带字段保留」相反。确认前两条并存,`Q13` 跟踪,不得据本节推定已与上游对齐。
**字段缺失语义与外部规范冲突**:SIS 要求以 AODB 最新数据覆盖本地(`SIS:1.6.2`),且未发送的可选字段表示应删除本地`C-26``Q13`与上面的「未携带字段保留」相反。确认前两条并存,不得据本节推定已与上游对齐。
消息重放由 `PROC_STATE` 的消息 ID 与 `IDENTITY_KEY` 控制;已成功提交的消息不得再次写入或重复登记事件。整包校验失败或运营日冲突时,整包不落地(`INV-19`)。
### 12.2 动态运行事件
### 12.2 动态运行事件FLOP
FLOP 事件只修改表达的字段或资源集合,其余航班状态保持不变。每个动态子类型的语义都必须有明确 Handler 规则和回归测试,不能只因已被路由就推定其业务语义完整(`INV-20`)。
FLOP 只修改报文表达的字段或集合,其余状态保持不变;目标形态与合并规则见「字段与集合」。逐类语义**不靠处理器分支表达,而靠 SIS 的逐类字段表与空标签规则**:下表每一行都必须有一条回归用例钉住「输入 → 目标字段/集合 → 空标签结果」,不能只因报文已被路由就推定语义完整(`INV-20`)。
动态事件保留既有 `OPERATION_DAY`,也不基于接收时间重新推导它。未知或已删除航班的具体处理遵从对应 Handler 的幂等规则。
| SIS | STYP | 目标 | 空标签 / 缺失语义 |
|---|---|---|---|
| `SIS:3.19` | `ACFT` | `ACFT` 标量 | 字段为 M,未写明空语义 |
| `SIS:3.20` | `ACTT` | `ACTT` 标量 | 空 = 清除已有实际时间 |
| `SIS:3.21` | `BOTM` | `BOTM` 标量 | 空 = 清除登机时间 |
| `SIS:3.22` | `CHOT` | `CHOT` 集合 | 集合按完整结果替换;元素内 `CHTM` 空 = 删除该轮挡时间 |
| `SIS:3.23` | `FLTY` | `FLTY` 标量 | 字段为 M,未写明空语义 |
| `SIS:3.24` | `CKDT` | `CKDT` 集合 | 空 `<CKDT CKNO="0">` = 现无柜台分配;**AODB 方向报文必须拒绝** |
| `SIS:3.25` | `CLDT` | `CLDT` 集合 | 空 `<CLDT CLNO="0">` = 现无转盘分配;**AODB 方向报文必须拒绝** |
| `SIS:3.26` | `CHDT` | `CHDT` 集合 | 空 `<CHDT CHNO="0">` = 现无滑槽分配;**AODB 方向报文必须拒绝** |
| `SIS:3.27` | `CNCL` | `CNCL` 标量 | 空 = **撤销**上一次取消(不是清空时间) |
| `SIS:3.28` | `ESTT` | `ESTT` 标量 | 空 = 删除预计时间 |
| `SIS:3.29` | `FDEL` | 走删除路径(「删除与重建」) | 恒为空标签 |
| `SIS:3.30` | `FDIV` | `FDIV``DDES`/`DDIR`),当前未映射(`G-FLOP-UNMAPPED` | 空 `DDES=""` = 清除转场标志 |
| `SIS:3.31` | `FINT` | `FINT` 标量 | 空 = 删除最终时间 |
| `SIS:3.32` | `FLIN` | `FLIN` 标量 | 字段为 M,未写明空语义 |
| `SIS:3.33` | `FRET` | `FRET``REID`),当前未映射(`G-FLOP-UNMAPPED` | 空 = 清除返航标志 |
| `SIS:3.34` | `GTDT` | `GTDT` 集合 | 空 `<GTDT GTNO="0">` = 现无登机门分配;`GOTM`/`GCTM` 缺失 = 未分配开放/关闭时间;**AODB 方向报文必须拒绝** |
| `SIS:3.35` | `LACL` | `LACL` 标量 | 空 = 清除最后通知时间 |
| `SIS:3.36` | `MAXP` | `MAXP` 标量 | 空 = 删除最大载客数 |
| `SIS:3.37` | `HNAG` | `FHAG`/`PHAG`/`MHAG` 标量 | `FHAG` 空 = 删除该代理;`MHAG` 可缺席 |
| `SIS:3.38` | `PSDT` | `PSDT` 集合 | 空 `<PSDT PSNO="0">` = 现无机位分配;**AODB 方向报文必须拒绝** |
| `SIS:3.39` | `RENO` | `RENO` 标量 | 空 = 清除注册号 |
| `SIS:3.40` | `ROUT` | `ROUT` 集合 | `SCAT`/`SCDT` 分别对起点/终点缺席;只保留 4 条(离港取前 4、到港取后 4)且忽略 `SCAT`/`SCDT` |
| `SIS:3.41` | `TAOP` | `TAOP`/`TAFL`/`TAID` 标量 | 任一为空 = 该到达航班的经停连接断开 |
| `SIS:3.42` | `TRML` | `TRML` 标量 | 空 = 删除航站楼 |
| `SIS:3.43` | `VIPP` | `VIPP`/`VIPR` 标量 | 空 = 删除;SIS 另要求 RMS 忽略 `VIPP`(忽略事件还是忽略字段,SIS 未写明,按 `Q8` 对拍确认) |
**方向约束**`SIS:3.24``SIS:3.25``SIS:3.26``SIS:3.34``SIS:3.38` 五节明确「RMS will reject this message if received from AODB」——柜台、转盘、滑槽、登机门、计划机位是 RMS→AODB 的分配事件。本系统只从日计划快照接受这五个集合,收到对应 FLOP 报文必须拒绝(当前实现的偏差见 `G-FLOP-DIRECTION`)。
**SIS 未定义但 legacy 处理的子类型**`ABTM``DELY``PADT``FTSS``STND``BDPB``REMC`。它们在 `XSD``FLOP` 段里是普通字段或集合,没有独立事件节;legacy 按 `STYP` 命中它们处理,说明真实流量可能存在 SIS 未记载的子类型。其报文形态与是否存在必须以真实报文确认(`Q8`),不得据 legacy 行为直接定案。
**SIS 定义但 legacy 无处理器**`CHDT``FINT``MAXP`
**未映射字段**`XSD` `FLOP` 段中尚未解码的字段见 `G-FLOP-UNMAPPED`;其中 `FRET``FDIV``BDPB` 在 legacy 有对应处理,逐项必须在 `Q8` 对拍时定案(补齐映射或明确声明忽略),不得静默丢弃。
动态事件保留既有 `OPERATION_DAY`,也不基于接收时间重新推导它。航班不存在或已删除时按幂等成功处理——动态事件不创建航班(创建只发生在日计划与异常航班)。
### 12.3 删除与重建
@@ -451,7 +509,7 @@ ADFT 的字段缺失语义尚待上游确认。在确认前采用保守的 Set-o
主/共享航班级联:删除共享航班时重算主航班 `MAFL`(见「主/共享投影」)并向主航班通知;删除主航班时级联删除其子共享关联并发出删除通知;主/共享关系必须一次原子变更,不出现主已删、子残留的半状态。共享航班增量通常只更新并通知主航班,不直接发共享通知。这些语义同样约束 FDEL 之外的生命周期清理。主/共享关联的增删按 `FLID` 做值比较,不使用引用比较。
SIS 规定删除主航班时必须先删子共享航班、再删主航班,顺序不符时 RMS 应向 AODB 回发 EROR`SIS:1.6.1-1.d`,事件定义见 `SIS:4.8`)。本章的原子级联不发该回报,两者取舍见 `C-25`
本章的原子级联不回发 EROR,与 SIS 的删除顺序要求相反;取舍见 `C-25``Q14`
### 12.4 Kafka 与读取
@@ -464,3 +522,66 @@ SIS 规定删除主航班时必须先删子共享航班、再删主航班,顺
### 12.5 生命周期
运营日过去不等于航班结束。历史清理须同时满足配置保留期与终态证据或足够静默期,先成功写入历史存储,后物理删除当前态;历史存储失败时必须删除零行(`D1``G-FLIGHT-HIST-RETENTION`)。
## 13. 静态参考数据
本章定义航班基础数据(参考主数据)的目标形态与合并语义。字段的值域、长度与业务含义以 [SIS 接口规范](legacy/SIS_AODB_RMS-V0.1.md) 对应节为准,本章只定义类别、结构与落库口径;取数路径与刷新责任见 [requirements.md](requirements.md) `US-13`/`US-14`
### 13.1 来源
| 来源 | 权威节 | 形态 |
|---|---|---|
| AODB 参考数据事件 | `SIS:3.1``SIS:3.13` | `META.TYPE` 即类别码;`STYP``DNLD` / `RESP` / `ADD` / `UPD` / `DEL` |
| AODB 资源状态事件 | `SIS:3.14` | `TYPE=RSTA``STYP` 只有 `DNLD` / `RESP` |
| AODB 应答参考数据请求 | `SIS:3.15` | 复用上表格式,仅 `STYP=RESP`;**没有请求 ID 或关联字段**,配对只靠子类型 |
| admin-api 本地主数据 | 见 `US-13` | 21 类,清单与字段映射待 `Q8` 确认 |
同一类别可能由两条来源同时提供,覆盖优先级见 `US-13`
### 13.2 类别
| `RTYPE` | 含义 | 唯一键 `RKEY` | 权威节 |
|---|---|---|---|
| `COUL` | 国家代码 | `COUC` | `SIS:3.1` |
| `ARPT` | 机场代码 | `ITCD` | `SIS:3.2` |
| `AIRL` | 航空公司代码 | `ITOP` | `SIS:3.3` |
| `AIRC` | 机型代码 | `ITAT` | `SIS:3.4` |
| `REGN` | 注册号 | `RNUM` | `SIS:3.5` |
| `ORGN` | 机构代码 | `OGID` | `SIS:3.6` |
| `FLTL` | 航班类型代码 | `FTYP` | `SIS:3.7` |
| `TLST` | 航站楼代码 | `TCOD` | `SIS:3.8` |
| `GLST` | 登机门代码 | `GCOD` | `SIS:3.9` |
| `SLST` | 机位代码 | `SCOD` | `SIS:3.10` |
| `CLST` | 值机柜台代码 | `CCOD` | `SIS:3.11` |
| `BLST` | 行李转盘代码 | `BCOD` | `SIS:3.12` |
| `CHLT` | 行李滑槽代码 | `CCOD` | `SIS:3.13` |
| `RSTA` | 资源状态 | `RSID`(另存资源类型 `RTYP` | `SIS:3.14` |
`CLST``CHLT` 复用同名标签 `CCOD``CNMC``CTML``CCAT`,语义不同,只能靠 `RTYPE` 区分。
### 13.3 结构与合并语义
`REF_MASTER` 一行一个 `(RTYPE, RKEY)`,字段名取 SIS 对应节的标签名,另存 `SOURCE``AODB` / `ADMINAPI`)、刷新批次与刷新时间。
- **list 模式 = 全量**:SIS 原文为一个 XML 含该类全部记录。整批校验通过后按类整体发布,失败不暴露半批(`US-13`)。
- **incremental 模式 = 单条全字段**:报文只含被改动的一条,但该条含全部字段;按 `(RTYPE, RKEY)` 整体覆盖该行。
- **删除只由 `STYP=DEL` 表达**:参考数据**没有字段级删除语义**——可选字段的空标签表示「数据不可用」,不是删除。这与航班动态的空标签语义相反,两者不得套用同一套合并规则。
- `SRVT``VIPF` 与参考数据无关;参考数据不参与航班状态推进,也不进入 `MSG_EVENT`
SIS 声明的上游忽略与截断口径(`SIS:3.2`/`SIS:3.4`/`SIS:3.5`/`SIS:3.6`/`SIS:3.7`/`SIS:3.8`/`SIS:3.10`/`SIS:3.11`/`SIS:3.12`):机场代码忽略 `ANAM`/`ACTY`/`ICCD`/`BDIS`/`ATYP`/`HAUL`;机型忽略 `DESC`/`CHAP`/`MFWT`/`MTWT`/`MHTM`/`MABR`;注册号忽略 `OWID`/`MFWT`/`MTWT`;机构忽略 `ONAM`,且 `OCAT` 只保留旅客/维护/地服代理;航班类型忽略 `FDES`/`FCML`/`CTYP`;航站楼忽略 `TNAM`/`TCAT`/`TPAX`;机位忽略 `STNM`/`MABS`/`FEPU` 并把 `STGP` 截断到 8 字符;值机柜台忽略 `CTNM`/`CCAT`;转盘忽略 `BTNM`/`BCAT`;国家代码只保留第一个 `REGC`。这些字段在未确认本地用途前不进入参考数据模型,需要时由 `US-13` 增补并说明用途。
### 13.4 资源状态
资源状态是「带时间窗的可用性事实」,按 `RTYPE=RSTA` 存入 `REF_MASTER``RTYP` 限定资源类型(`BELT` / `CNTR` / `GATE` / `STND`),`STAT` 取值 `E`(可用)/ `D`(不可用)。
- 资源**默认为可用**;只有禁用需要下发。
- 禁用可带起止时间;**结束时间到达后自动恢复可用,不再补发启用消息**。
- 结束时间缺失表示**一直禁用,直到该资源收到新的状态事件**。
- 重新启用只带起始时间,不带结束时间。
### 13.5 机位与登机桥映射
- 机位主数据即 `SLST``RKEY=SCOD`),机位性质由 `REMT` 表达:`N` = 近机位(默认)、`Y` = 远机位、`A` = 停机区;所属航站楼是 `STML`。机位可用性由 `RSTA``RTYP=STND`)表达。
- **机位→登机桥关系没有 SIS 来源**,只有 admin-api 提供;`US-14` 的映射因此依赖 admin-api 可用性,不可用时用最后可用版本。
- 协议内的登机桥编码是 `ABTM` 元素中的 `ABDG``SIS:3.16``XSD` `OPT_BRIDGEDATA`),**不是航班主表标量**;legacy 另有一个由 admin-api 派生的航班级 `abdg`。目标形态必须在两者间二选一并写进「字段与集合」,确认前不得把派生值当成协议字段。
- `PSDT` 的「空集合」与「未携带」含义不同:前者清空本地机位、后者保留原值(`INV-14`;空集合写法见「动态运行事件」)。