docs(acm2-75): 精简不变量与声明边界,去掉无依据条目

审改 specification 管道/航班域/投影与 CLM:作废与需求重复或依据不足的 INV/CLM,白话重写保留条款,并同步架构、实现与引用注释。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
windyboy
2026-09-16 17:26:49 +08:00
co-authored by Cursor
parent 6fa4da60f1
commit dc1c49af6e
12 changed files with 132 additions and 177 deletions
+33 -35
View File
@@ -28,9 +28,9 @@
| `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` | SIS 消息提供的静态参考数据与资源状态(目标表) | `(RTYPE, RKEY)` 唯一;`RTYPE` 类别、合并语义与资源状态见「静态参考数据」;取数路径见 [requirements.md](requirements.md) `US-13`。 |
| `FLIGHT_SCHD` | 航班标量及单值异常字段 | `FLID` 主键;`OPERATION_DAY` 一经确定不可变;版本最近消息 ID 用于追踪。变长集合存于资源明细表与 `FLIGHT_ROUTE_POINT`,规则见「航班域」。 |
| `FLIGHT_SCHD` | 航班标量及单值异常字段 | `FLID` 主键;运营日与版本最近消息 ID 用于追踪。变长集合存于资源明细表与 `FLIGHT_ROUTE_POINT`,规则见「航班域」。 |
| `SCHD_SNAP_LOG` | 日计划处理留痕 | 只追加、可重建,不参与状态决策;保留期见 [reference.md](reference.md)。 |
字段与索引以 `src/main/resources/db/migration/` 的迁移链为准(Oracle 11g 目录为占位,未接入 Flyway)。报文原文仍从共享信箱读取,原文保留期必须满足 `C-7`;处理标记值集见 `C-5`,清除前提与保留期下界见 `C-6``C-9``C-11`
字段与索引以 `src/main/resources/db/migration/` 的迁移链为准(Oracle 11g 目录为占位,未接入 Flyway)。报文原文仍从共享信箱读取;信箱清理见 `C-1`
## 2. 消息、身份与决策
@@ -41,7 +41,7 @@
**身份绑定是独立的幂等单语句**`WHERE IDENTITY_KEY IS NULL`),不参与业务事务。它的前提是「报文不可变」(`PRE-7`):同一身份的重发不会被比对内容,若上游改发正文会被判为重复并跳过(`Q15`)。
分派与落库由 `MessageProcessor` 协调:按 `MsgKind` 把已绑定身份的队头消息交给对应事务协调器(SCHD-DNLD/RESP → `ScheduleProcessor`ADFT → `AdftProcessor`FLOP → `FlopProcessor`FDEL → `FdelProcessor``SIS:3.1``SIS:3.14` 的静态参考数据消息 → `ReferenceDataProcessor`,其余 → `SKIPPED(unsupported)`)。这些处理器在 `PIPELINE_LOCK` 事务内读取当前完整态,调用纯领域决策逻辑得到下一完整态与待发事件,提交该事务后写 Redis 投影,再在另一事务中登记处理终态与回填意图(`INV-17b``INV-23`);它们不直接触碰 Kafka。领域决策逻辑不执行 I/O。处理步骤的锁跨越 Redis 写,因此与航班历史清理的互斥覆盖整个步骤(`INV-18`)。
分派与落库由 `MessageProcessor` 协调:按 `MsgKind` 把已绑定身份的队头消息交给对应事务协调器(SCHD-DNLD/RESP → `ScheduleProcessor`ADFT → `AdftProcessor`FLOP → `FlopProcessor`FDEL → `FdelProcessor``SIS:3.1``SIS:3.14` 的静态参考数据消息 → `ReferenceDataProcessor`,其余 → `SKIPPED(unsupported)`)。这些处理器在 `PIPELINE_LOCK` 事务内读取当前完整态,调用纯领域决策逻辑得到下一完整态与待发事件,提交该事务后写 Redis 投影,再在另一事务中登记处理终态与回填意图(`INV-3``INV-23`);它们不直接触碰 Kafka。领域决策逻辑不执行 I/O。处理步骤的锁跨越 Redis 写,使与航班历史清理的协作覆盖整个步骤(`US-14` AC4)。
合法但本系统不支持的消息类型:跳过留档、按已处理写回标记(`US-03` AC2),不重试。`REGN` / `RSTA` 是静态参考数据消息,必须分派给 `US-13`,不得跳过。
@@ -81,7 +81,7 @@
### 4.3 兼容 HTTP 入口
`POST /cminmsgs/send` 把报文写入共享信箱(处理时间为空),效果与上游投递一致:由收报扫描发现、登记、处理。客户端失败重试可能再次写信箱,业务身份去重仍然必需。响应语义见 `C-28`
`POST /cminmsgs/send` 把报文写入共享信箱(处理时间为空),效果与上游投递一致:由收报扫描发现、登记、处理。客户端失败重试可能再次写信箱,业务身份去重仍然必需。响应语义见 `C-8`
### 4.4 单实例
@@ -141,11 +141,11 @@ processOne(head)
| Redis 投影写 | 否 | 是(处理步骤锁跨越本步) | 否 | 外部副作用,不在 PG 事务内;写成功是终态事务的前置(`INV-23` |
| 业务型终态(`SUCCEEDED` + 回填意图) | 是 | 是 | 否 | 同库事务(`INV-17b` |
| 非业务型终态(`MALFORMED` / `PROTOCOL` / `SKIPPED` / `EXHAUSTED`) | 否 | 否 | 否 | 单语句(终态与回填意图同一条 UPDATE) |
| 航班历史清理的物理删除 | 是 | 是(`INV-18`) | 是 | 同库事务:复查判据 + 历史写入成功后删除 |
| 航班历史清理的物理删除 | 是 | 是(落实 `US-14` AC4) | 是 | 同库事务:复查判据 + 历史写入成功后删除 |
| 回填(信箱标记 + `BACKFILL_AT`) | 否 | 否 | 否 | 跨库两次单写;幂等可重跑 |
| 人工重放(批量改回 `PENDING`) | 否 | 否 | 否 | 单语句批量;`MessageLifecycleGate` 与回填互斥 |
结论:航班变更与处理终态**不在同一事务**——两者之间夹着 Redis 投影写;同一事务只保证「航班变更 + 事件」与「终态 + 回填意图」各自原子(`INV-17b``INV-23`)。处理步骤的 `PIPELINE_LOCK` 跨越 Redis 写,使 `INV-18` 的互斥覆盖整个步骤;该锁的竞争写者是**航班历史清理**,不是别的处理器线程;没有第二写者时该锁不产生额外串行度。
结论:航班变更与处理终态**不在同一事务**——两者之间夹着 Redis 投影写;同一事务只保证「航班变更 + 事件」与「终态 + 回填意图」各自原子(`INV-3``INV-23`)。处理步骤的 `PIPELINE_LOCK` 跨越 Redis 写,使与航班历史清理的协作覆盖整个步骤(`US-14` AC4;该锁的竞争写者是**航班历史清理**,不是别的处理器线程;没有第二写者时该锁不产生额外串行度。
### 5.4 历史积压
@@ -155,7 +155,7 @@ processOne(head)
- 不加速、不分流、不走旁路:不允许并行队头,也不允许实时消息跳过积压。
- 尝试上限与退避对积压同样生效,不因积压而放宽。
- 不再处理的行置 `SKIPPED` 并记录原因,到达终态后走回填通道;不存在「整段 DELETE」的快速通道。
- 消化期间的可观测项与完成时限口径见 [reference.md](reference.md)`CLM-9`**扫描周期不是完成时限**
- 消化期间的可观测项见 [reference.md](reference.md);完成时限不作对外承诺(`CLM-9`),现场一般为即时处理
## 6. 回填
@@ -185,7 +185,7 @@ LIMIT PARAM:msgx.pipeline.backfill-batch
| 信箱行不存在 | 写入 0 行且信箱行不存在 | **立即放弃自动重试**(原因 `MISSING_ROW`)并告警。终态行存在而信箱行不存在,只可能是该行在入队后被删除(永久空洞 ID 从不入队,不会进入本扫描) |
| 暂时性故障持续超期 | 超时 / 连接失败持续到 `R` 仍未打标 | **停止自动重试**(原因 `TRANSIENT_DEADLINE`)并告警;`R` 之前只退避重试,**不按尝试次数放弃**;保留人工恢复能力 |
**放弃 ≠ 标记已确认**:放弃行不写 `BACKFILL_AT`,处理标记仍为空,「行最终都有标记」因此不能对外承诺(`CLM-4`;放弃清单能否作为清除判定依据,属未确认的清除协议(`C-8`;见 `Q7`/`Q9`)。
**放弃 ≠ 标记已确认**:放弃行不写 `BACKFILL_AT`,处理标记仍为空;放弃清单能否作为清除判定依据,属未确认的清除协议(`C-1`;见 `Q9`)。
### 6.3 `R` 的作用
@@ -201,11 +201,11 @@ LIMIT PARAM:msgx.pipeline.backfill-batch
1. 退避重试(`R` 之前不放弃);
2.`R` 仍失败则停止自动重试、告警,保留人工恢复(`reopen`)。
第三段「库方以放弃清单作为清除判定」未确认,因此「最终一定打标」当前不可承诺(`CLM-4`)。
第三段「库方以放弃清单作为清除判定」未确认`C-1`;见 `Q9`)。
两个边界要说清:`MISSING_ROW`(信箱行不存在)是**确定性结论**,立即放弃,不受 `R` 保护;`R` 只要求 `R ≤ R_keep`,原文保留期的唯一约束来源是 `C-7`
两个边界要说清:`MISSING_ROW`(信箱行不存在)是**确定性结论**,立即放弃,不受 `R` 保护;`R` 只要求 `R ≤ R_keep`,原文保留期的唯一约束来源是 `C-1`
库方的清除语义未确认(`C-6``C-8`;见 `Q7`/`Q9`):若为「打标即可清除」,`C-7`保留期下界不成立,必须与库方另定;增大 `R` 无效。
库方的清除语义未确认(`C-1`;见 `Q9`):若为「打标即可清除」,`C-1`清理前提不成立,必须与库方另定;增大 `R` 无效。
## 7. 日计划快照与请求匹配
@@ -235,7 +235,7 @@ PENDING → SENT → DONE
- 应答优先按已确认的回显字段精确匹配;降级匹配的跨代误配风险必须明确接受并审计(`C-23`)。
- 时间比较统一时区与单位,并需定义时钟偏斜容忍;容忍判据未定(`Q5`),在定义前不得把降级匹配描述为精确关联。
- 参考应答写入自有 `REF_MASTER`,日计划应答走快照流程;请求完成必须在相应数据处理成功之后,超时和迟到应答不能修改已关闭请求对应的状态。
- 出站承诺只到落信(`C-24``CLM-8`);主 / 共享删除的 EROR 回报义务`C-25`
- 出站承诺只到落信(`C-4``CLM-8`);主 / 共享删除见 `C-5`
## 8. 事件投递
@@ -245,7 +245,7 @@ PENDING → SENT → DONE
本批领取的 `EVENT_ID` 集合在**读取时刻冻结**:发送与标记只作用于这批事件,期间新提交的事件留待下一轮,不参与本批,也不被本批的「完成」带走。
`EVENT_ID` 由全局串行分配产生:事件生产者在事务内写 outbox,主泵单线程,历史清理与主泵互斥(`INV-18`),因此**分配顺序 = 提交顺序**,不存在「已提交的较大 ID 先于未提交的较小 ID 被投递」。
`EVENT_ID` 由全局串行分配产生:事件生产者在事务内写 outbox,主泵单线程,历史清理与主泵对实时航班表串行(落实 `US-14` AC4),因此**分配顺序 = 提交顺序**,不存在「已提交的较大 ID 先于未提交的较小 ID 被投递」。
发送确认后才标记 `SENT`,失败记录次数并按退避推后,达到上限转 `DEAD`(记录保留作 DLQ)。所有外部调用需要有界超时,避免阻塞投递线程。
@@ -288,7 +288,7 @@ PENDING → SENT → DONE
|---|---|---|
| 已落信、未入队 | 信箱行处理时间为空且 PG 无记录 | 重扫补建登记记录 |
| 事务执行中 | PG 无该消息终态 | 事务整体回滚,按 `PENDING` 重新处理 |
| 领域事务已提交、Redis 写失败或终态未提交 | 该消息无终态(`PENDING`),仍占队头 | 整条消息重处理:投影按当前完整态重写领域变更依赖逐类幂等(`INV-20b``G-FLOP-IDEMPOTENT`),已提交结果不回滚(`INV-16` |
| 领域事务已提交、Redis 写失败或终态未提交 | 该消息无终态(`PENDING`),仍占队头 | 整条消息重处理:投影按当前完整态重写领域再跑是否只留一次效果见 `US-03``G-FLOP-IDEMPOTENT`已提交结果不回滚(`US-03` AC3 |
| 事务已提交、标记未写 | 终态行仍持有回填意图 | 仅补写标记;业务处理结果保持不变 |
| 标记写入中途 | 标记仍为空 | 重新写入;重复写入同一值无副作用 |
| 回填时信箱行已不存在 | 写入 0 行且信箱行不存在 | 立即放弃自动重试(`MISSING_ROW`)并告警;放弃不等于标记已确认,仍需人工对账 |
@@ -298,13 +298,13 @@ PENDING → SENT → DONE
### 9.3 生命周期与清除
`JobRunner` 用独立 daemon 线程按周期触发回填扫描、航班历史清理与留痕清理;作业不参与消息 FIFO,也不使到期消息饥饿。`INV-18` 要求历史清理的删除与主泵处理互斥
`JobRunner` 用独立 daemon 线程按周期触发回填扫描、航班历史清理与留痕清理;作业不参与消息 FIFO,也不使到期消息饥饿。历史清理时跳过正在被消息处理的航班(`US-14` AC4
**通则**(对本系统所有持久对象适用)
- **时间不构成清除依据**:到期只是必要条件,**终局证据才是充分条件**(航班见 `INV-28`;共享库的清除依据属未确认的清除协议,见 `C-8``Q9`)。
- **时间不构成清除依据**:到期只是必要条件,**终局证据才是充分条件**(航班见 `US-14` AC3、`D1`;共享库的清除依据属未确认的清除协议,见 `C-1``Q9`)。
- **证据不随清除消失**:回填失败与放弃的记录在其覆盖的信箱行被清除前保持可查(`C-16`)。
- **证据缺失或结果不明时按最保守处置**:航班清理为删 0 条(`INV-28`)。
- **证据缺失或结果不明时按最保守处置**:航班清理为删 0 条(`US-14` AC3、`D1`)。
**逐对象生命周期**(保留期取值一律见 [reference.md](reference.md)
@@ -318,24 +318,24 @@ PENDING → SENT → DONE
| `PROC_STATE` 终态行 | 见下 | 无(到期直接删除) | 回填了结 | 我们 | `G-PROC-CLEANUP` |
| `REQ_TRACK` 关闭态行 | 保留期 | 无 | 无 | 我们 | `G-REQ-TRACK-RETENTION` |
**处理记录到期清理**`INV-25`
**处理记录到期清理**`US-11`
候选 = 终态 **且** 回填已了结 **且** 终局后超过保留期(基准是 `UPDATED_AT`:终态与了结都推进它,了结后不再更新)。两处不可省:
- **回填已了结** = `BACKFILL_AT` 非空(`INV-25`)。放弃行不写标记,按未了结保留,不参与删除。
- **回填已了结** = `BACKFILL_AT` 非空(`US-11`)。放弃行不写标记,按未了结保留,不参与删除。
- **写入前复查** = `DEAD` 可被人工重放改回 `PENDING`。人工重放走 `MessageLifecycleGate`、不取 `PIPELINE_LOCK`,因此该锁不构成复查依据:删除在同一事务内按候选时的 `STATE` 条件执行;影响 0 行即整体回滚、该行跳过。重放先一步改回 `PENDING` 时谓词不匹配,天然互斥。批量删除不得持 `PIPELINE_LOCK`——那会阻塞主泵 FIFO,与「作业不使到期消息饥饿」冲突。
清理范围只含「终态且已回填」;保留期内同身份去重成立(`INV-9`
清理范围只含「终态且已回填」;保留期内同身份去重见本章「消息、身份与决策」
**时间常数排序**`R` 的取值与依据见 [reference.md](reference.md) 的 `PARAM:msgx.pipeline.overdue-backfill``R_keep` 的下界见 [specification.md](specification.md) 的 `C-7`,本文件不复述。只补一条实现口径:保留期计的是**终局之后**的时间,不是入队之后——终态行未了结回填时不进入候选。
**时间常数排序**`R` 的取值与依据见 [reference.md](reference.md) 的 `PARAM:msgx.pipeline.overdue-backfill`信箱清理前提见 [specification.md](specification.md) 的 `C-1`,本文件不复述。只补一条实现口径:保留期计的是**终局之后**的时间,不是入队之后——终态行未了结回填时不进入候选。
**其余清理**
- **航班历史清理**:按 [reference.md](reference.md) 的历史判据选候选(含 `DELETED`),先成功写入历史存储再删除;语义与红线见「航班域」与 `INV-28`
- **航班历史清理**:按 [reference.md](reference.md) 的历史判据选候选(含 `DELETED`),先成功写入历史存储再删除;语义与红线见「航班域」与 `US-14``D1`
- **留痕清理**`SCHD_SNAP_LOG` 按保留期与 `(SCOPE_END, RECV_AT)` 删除,不依赖历史存储开关。
- **出站事件清理**:见「事件清理」。
共享信箱保留策略由库方管理(`C-6``C-9``C-11`。历史写入与删除事件入队之间仍需恢复方案;顺序调用不构成原子提交。
共享信箱保留与清理见 `C-1``C-2`。历史写入与删除事件入队之间仍需恢复方案;顺序调用不构成原子提交。
## 10. 容量假设与设计取舍
@@ -371,9 +371,7 @@ PENDING → SENT → DONE
### 11.2 航班身份与运营日
`FLID` 是主键。`OPERATION_DAY` 从 SCHD 记录的 `SODT` 按配置的机场时区和切日规则推导;它不是消息接收日或落库日。
运营日一经写入不可更改(`INV-12`)。遇到冲突,整包日计划按协议错误拒绝,既有状态保持不变(`INV-19`)。尚未由日计划收录的航班可以为 `NULL`;这不表示该航班没有运营日,只表示当前模型无法为它确定归属日。
`FLID` 是主键。`OPERATION_DAY` 从 SCHD 记录的 `SODT` 按配置的机场时区和切日规则推导;它不是消息接收日或落库日。尚未由日计划收录的航班可以为 `NULL`;这不表示该航班没有运营日,只表示当前模型无法为它确定归属日。运营日冲突如何处置见 `Q23``INV-4` 只管整份校验不过时本地不改)。
### 11.3 字段与集合
@@ -408,18 +406,18 @@ PENDING → SENT → DONE
- `ORDINAL` 是持久化顺序,从 1 开始;`SOURCE_SEQ` 是上游序号,允许为空或重复。
- 相同资源号不代表同一条分配,禁止按资源号去重。
- 每次持久化完整航班状态时,明细表按该 `FLID` 先删后插,以完整合并结果为准(`INV-14b`)。
- 每次持久化完整航班状态时,明细表按该 `FLID` 先删后插,以完整合并结果为准(`US-04` AC2)。
- ROUT 与 ERUT 是两类独立集合,不能因相同序号覆盖彼此。
- `CHDT` 的类字段固定为 `CCLS`/`CTYP`;当前 wire DTO 与持久化列误写成 `CHCLS`/`CHTYP`,见 `G-FLOP-UNMAPPED`
- 主/共享关系以主表的 `MAID` 为事实来源:`MAID` 是共享航班指向主航班 `FLID` 的引用(非共享航班为 `NULL`);`MAFL` 只在读取和事件投影时从子航班事实派生,不按入站标量解析或保存。
### 11.4 主/共享投影(`MAFL`
`MAFL` 是主航班的派生集合,元素为子航班的 `FLID``FLNO`;内容与变更传播分别由 `INV-21``INV-22` 保证
`MAFL` 是主航班的派生集合,元素为子航班的 `FLID``FLNO`;内容与变更传播见本章与 `US-06` AC2
- 已 FDEL 的子航班(`STATE = DELETED`)自然退出投影(内容见 `INV-21`,不需要改写主航班行。
- 已 FDEL 的子航班(`STATE = DELETED`)自然退出投影,不需要改写主航班行。
- 只有 `MAID` 为空的主航班携带 `MAFL`;共享航班只携带自身 `MAID``CSOP``CSFT`,不携带 `MAFL`,避免下游双向合并。
- 同一 `STATE_VERSION` 的投影逐字节稳定(顺序见 `INV-21`,与到达顺序及 `FLNO` 变更无关;重发与消费端比对才有意义。
- 同一写代次下投影逐字节稳定,与到达顺序及 `FLNO` 变更无关;重发与消费端比对才有意义。
- `MAID = FLID` 的自引用行不进入任何 `MAFL``MAID` 指向不存在主航班的悬挂引用不阻断该子航班自身处理,只是不产生投影。
- 子航班集合变化的传播见 `INV-22`,事件类型为 `KAFKA:msg` + `KAFKA:schd`;否则整态投影的只进不退写入会丢弃它(见「`schd` 聚合」)。共享航班自身不单独发通知。
- 派生主航班投影与产生它的状态写入必须同一事务或一致读快照;按 `MAID` 取子航班要求该列有索引(`INV-17b``INV-22`)。
@@ -432,13 +430,13 @@ PENDING → SENT → DONE
SCHD DNLD/RESP 在整包校验通过后,分批将报文携带的航班写入当前态,每批一个事务;快照里没有的航班删除:标记已删除、登记删除事件、从 Redis 投影移除(`INV-15b`)。日计划就是主动与 AODB 全量同步一次,以 AODB 下发的数据为准。
日计划里某航班没携带的字段,视为 AODB 已删除该值,本地同步清除(`C-26`)。每个成功写入的航班推进 `STATE_VERSION``INV-13`,并在同一事务登记 `KAFKA:schd``KAFKA:msg` 事件。
日计划里某航班没携带的字段,视为 AODB 已删除该值,本地同步清除(`C-26`)。每个成功写入的航班推进 `STATE_VERSION`,并在同一事务登记 `KAFKA:schd``KAFKA:msg` 事件。
消息重复处理由 `PROC_STATE` 的消息 ID 与 `IDENTITY_KEY` 控制;已成功提交的消息不得再次写入或重复登记事件。整包校验失败或运营日冲突时,整包不落地(`INV-19`)。
消息重复处理由 `PROC_STATE` 的消息 ID 与 `IDENTITY_KEY` 控制;已成功提交的消息不得再次写入或重复登记事件。整包校验失败整包不落地(`INV-4`;运营日冲突见 `Q23`
### 12.2 动态运行事件(FLOP
FLOP 只修改报文表达的字段或集合,其余状态保持不变;目标形态与合并规则见「字段与集合」。`STYP` 必须命中下表白名单,未知值按不支持类型跳过留档(`US-03` AC2),不得进入通用合并。已确认的动态更新在同一事务推进 `STATE_VERSION` 并登记 `KAFKA:msg``KAFKA:schd``INV-17b`);处理终态与回填意图在 Redis 投影写成功后的另一事务中提交(`INV-23`)。同一消息重复处理不得重复产生业务效果(`INV-20b`
FLOP 只修改报文表达的字段或集合,其余状态保持不变;目标形态与合并规则见「字段与集合」。`STYP` 必须命中下表白名单,未知值按不支持类型跳过留档(`US-03` AC2),不得进入通用合并。已确认的动态更新在同一事务推进 `STATE_VERSION` 并登记 `KAFKA:msg``KAFKA:schd``INV-17b`);处理终态与回填意图在 Redis 投影写成功后的另一事务中提交(`INV-23`)。同一消息不产生两次效果见 `US-03`;逐类规则未补齐见 `G-FLOP-IDEMPOTENT`
逐类语义以 SIS 的字段表、空标签规则与 Processing Exceptions 为准;下表每一行都必须有一条回归用例钉住「输入与前态 → 目标状态 → 终态与事件」。
@@ -470,7 +468,7 @@ FLOP 只修改报文表达的字段或集合,其余状态保持不变;目标
| `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→AODB 方向。需求已定案:这五类资源分配报文 AODB 实际会发,照常接收处理(`US-05` AC3);与 AODB 的核对确认是实施任务
`CKDT``CLDT``CHDT``GTDT``PSDT` 等 FLOP 子类型是否入站、如何合并,见 `US-05` 与本章「动态运行事件」;SIS 中的 RMS→AODB 方向说明不约束本系统(OMMS 只收不发)
**SIS 未定义但 legacy 处理的子类型**`ABTM``DELY``PADT``FTSS``STND``BDPB``REMC`。它们在 `XSD``FLOP` 段里是普通字段或集合,没有独立事件节;legacy 按 `STYP` 命中它们处理,说明真实流量可能存在 SIS 未记载的子类型。其报文形态与是否存在必须以真实报文确认(`Q8`),不得据 legacy 行为直接定案。
@@ -483,7 +481,7 @@ FLOP 只修改报文表达的字段或集合,其余状态保持不变;目标
### 12.3 删除与重建
FDEL 是业务删除入口:仅在 `ACTIVE → DELETED` 时推进版本、保留明细并与 tombstone 同事务登记;重复 FDEL 或不存在的航班按幂等成功处理。
物理删除仅由独立历史清理在历史写入成功后执行(`INV-28`)。快照里没有的航班删除(`INV-15b`);FDEL 仍是最先的删除入口。清理前需要登记一次 tombstone;已经 FDEL 的记录不重复发出。
物理删除仅由独立历史清理在历史写入成功后执行(`US-14` AC3、`D1`)。快照里没有的航班删除(`INV-7`);FDEL 仍是最先的删除入口。清理前需要登记一次 tombstone;已经 FDEL 的记录不重复发出。
ADFT 的字段缺失语义尚待上游确认。在确认前采用保守的 Set-only 规则:出现字段可更新,缺失字段不清空;不得把它当成日计划或动态全量替换。新建 ADFT 若带可解析的 `SODT`,按同一运营日规则计算 `OPERATION_DAY`;否则保留为 `NULL`