docs(acm2-75): 按需求与架构收口契约和规范
补齐接口契约的入站、Redis 与出站边界,规范对齐已定语义并作废过期条款;Kafka 生产端约束编号改为 D2。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+202
-183
@@ -1,238 +1,257 @@
|
||||
# 规范:术语、契约、前提、不变量与声明边界
|
||||
|
||||
本文定义 msgexchange-v2 的术语、外部契约、前提、不变量与声明边界。
|
||||
|
||||
内容取自 [requirements.md](requirements.md)、[architecture.md](architecture.md) 与 [contracts/interface-contract.md](contracts/interface-contract.md);机制与数据模型见 [implementation.md](implementation.md),参数与指标见 [reference.md](reference.md)。
|
||||
|
||||
`C-x`、`PRE-x`、`INV-x`、`CLM-x`、`Qn`、`G-NAME` 只在本文件定义;ID 语法见 [README.md](README.md)。
|
||||
|
||||
契约条目的写法:整条口径还需对方确认的,末尾标 `(待确认 Qn)`;正文已定、只有个别字段未定的,另起一行以「待确认:」列出并指向 `Qn`。未标注的,是本系统自己遵守或已由需求与架构定下。作废条款集中放在各节末尾,保留原文与作废标记。
|
||||
|
||||
## 1. 术语
|
||||
|
||||
| 术语 | 含义 |
|
||||
|---|---|
|
||||
| 上游 | 报文的写入方。现在是 CIIMS adapter,它把 AODB 下发的报文写进信箱。 |
|
||||
| 信箱 | CIIMS adapter 的 MySQL 里用于消息交换的表——入站 `CMINMSGS`、出站 `COUTMSGS`;报文由 adapter 写入,网关读取。 |
|
||||
| 库方 | CIIMS adapter 方。信箱表在它的 MySQL 里,表结构变更与数据清除由它执行,机制未定;本系统只读消息、写回处理标记,不改表结构、不清数据。 |
|
||||
| 处理标记 | 信箱行上表示「已处理」的字段,需求文档说的「处理时间」就是它。本系统只把空标记写成已处理值,不回撤、不覆盖。 |
|
||||
| 落信 | 报文进入信箱,成为其中一行。写入的是 adapter 或兼容 HTTP 入口。 |
|
||||
| 入队 | 本系统在自有 PG 给这条报文建立一条处理记录,开始处理。 |
|
||||
| 已回填 | 本系统已把处理标记写回该信箱行。 |
|
||||
| 处理完成 | 消息处理完了:业务数据已写入自有 PG,该写的 Redis 投影也已写成功。 |
|
||||
| 投递确认 | 发出去的消息对方已接收,本系统的投递记录也记成已发送;这不代表对方的业务已经消费。 |
|
||||
| Redis 投影 | 本系统写进 Redis、供查询用的航班数据;完整数据在本系统的 PostgreSQL 数据库里。 |
|
||||
| 自有 PG | 本系统自己的业务数据库 PostgreSQL,处理结果都存在这里;与信箱之间没有跨库事务。生产环境用 PostgreSQL 还是 Oracle 11g,还没定。 |
|
||||
| admin-api | 下游查询系统;直接读本系统写入的静态参考数据表,不向本系统提供数据。 |
|
||||
|
||||
条款后面的状态标记有四种:`[待确认 Qn]`=还没拿到对方确认;`[已确认 YYYY-MM-DD]`=对方已确认并记录在此;`[我们单方承诺]`=不等对方、自己已生效的对外承诺;`[我们自证]`=本系统自身的部署事实,无需确认。
|
||||
| 上游 | 产生报文的 AODB;报文由 CIIMS adapter 写入信箱。 |
|
||||
| 信箱 | 共享 MySQL 的 `CMINMSGS`(入站)与 `COUTMSGS`(出站);归库方所有,本系统只读写消息、回写处理标记。 |
|
||||
| 库方 | 信箱所在的共享 MySQL 管理方,即 CIIMS adapter 方。 |
|
||||
| 处理标记 | 信箱行上表示已处理的值。读取条件是「处理时间为空」;处理完成时写入完成时刻。本系统只填空值,不回撤、不覆盖。 |
|
||||
| 落信 | 报文写入信箱成为一行;入站由 CIIMS adapter 或兼容入口写入,出站由本系统写入 `COUTMSGS`;入站报文写进信箱后可能尚未登记。 |
|
||||
| 登记 | 本系统在自有 PG 为这条报文建立处理记录,排队等待处理。 |
|
||||
| 处理完成 | 业务数据已写入自有 PG,该写的 Redis 投影也已写成功。 |
|
||||
| 回填 | 把处理标记写回信箱行。 |
|
||||
| 投递 | 读待发事件发 Kafka。 |
|
||||
| Redis 投影 | 供页面与 `GET /all/flights` 查询的航班数据;只由本系统写入和移除,不作权威。 |
|
||||
| 自有 PG | 本系统唯一的业务数据库;航班当前态、管道记录与静态参考数据都在这里。 |
|
||||
| 权威 | 航班当前态以自有 PG 为准;信箱、Redis、Kafka 与展示视图都不是。 |
|
||||
| 出站请求 | 经 `COUTMSGS` 发向 AODB 的 `RQRD` 参考数据请求与 `RQFD` 日计划请求;交付承诺止于落信。 |
|
||||
| 运营航班显示界面 | Kafka 主题 `msg` 与 `schd` 的消费方,即需求所称网页客户端:变更通知走 Kafka(`US-08`),航班查询与 `GET /all/flights` 同源读 Redis 投影(`INV-24`)。 |
|
||||
| 航班历史 | 已结束航班写入 Elasticsearch 后的副本;写成功后才从实时数据删除。 |
|
||||
| 静态参考数据 | 13 类基础数据与资源状态,写自有 PG 的独立数据表,admin-api 直接只读。 |
|
||||
|
||||
## 2. 契约
|
||||
|
||||
读者:库方(共享 MySQL 管理方)接口人、上游(CIIMS / AODB / SIS)接口人、本系统开发与运维。
|
||||
|
||||
### 2.1 共享信箱(库方)
|
||||
|
||||
**ID 与可见性**
|
||||
- **C-3** 信箱编号不复位、不复用、不回退,含表轮换、备份恢复与自增归零。不丢消息依赖这条(`PRE-2`、`PRE-3`)。`(待确认 Q2)`
|
||||
- **C-4** 报文行不可变:同一业务身份(`SNDR`、`TYPE`、`STYP`、`SEQN`)的重发是同一内容。`(待确认 Q15)`
|
||||
- **C-5** 处理标记的允许值由库方认可,本系统只在该值集内写入;死信、跳过与回填失败的原因记在自有 PG,不在信箱新增取值。
|
||||
待确认:允许值的具体取值(`Q7`)。
|
||||
- **C-6** 原文的保留期与清除时机由库方定;本系统不承诺清除时间,只要求不早于 `C-7` 的下界。`(待确认 Q7、Q9)`
|
||||
- **C-7** 原文保留期下界:回填重试期间原文必须还在(`US-10` AC2)。`(待确认 Q7、Q9)`
|
||||
- **C-8** 清除由库方执行;本系统不执行 DDL、不清数据、不写共享历史表(`C-14`)。清除是否需要标记以外的证据,另行确认。`(待确认 Q9)`
|
||||
- **C-9** 清除的方案与 DDL 授权由库方定,本系统不参与选型。`(待确认 Q9)`
|
||||
- **C-10** 信箱时间列由写入方写入,其时钟基准须可解释(`PRE-4`)。
|
||||
待确认:时区与允许偏斜(`Q7`)。
|
||||
- **C-12** 原文被提前清除时,本系统不补造原文,也不把这类消息当成功:尚未处理的消息按处理失败回滚、保持未完成,错误记在对应处理记录上(`US-03` AC3/AC5)。`(本系统单方承诺)`
|
||||
- **C-14** 本系统不建表、不改表结构、不迁移 schema、不清数据,也不写共享历史表。
|
||||
- **C-15** 处理标记只在空值上写入处理完成时刻,写完不回撤、不覆盖已有值。`(本系统单方承诺)`
|
||||
- **C-16** 回填失败的行保留记录并告警,记录在对应信箱行被清除前保持可查。`(本系统单方承诺)`
|
||||
- **C-30** 信箱读取口径:按配置周期读取「处理时间为空」的行,按编号升序、每批有上限;单活动实例运行,不引入并行消费者。
|
||||
|
||||
### 2.2 上游(AODB / SIS)
|
||||
|
||||
- **C-20** 业务身份由 `SNDR`、`TYPE`、`STYP`、`SEQN` 组成,语义由上游定义,取值范围与回绕以 [SIS 接口规范](legacy/SIS_AODB_RMS-V0.1.md) 为准;`SEQN` 的重置周期未知,它决定身份是否加入日期边界。`(待确认 Q11)`
|
||||
- **C-21** `FLID` 在保留期内不复用;复用会让「只进不退」的合并把新航班的事件压掉。`(待确认 Q16)`
|
||||
- **C-23** 应答到达时按报文类型对应到等待中的请求;AODB 发错或迟到的应答不更新数据,记录后跳过(`US-09` AC2)。`SCHD-RESP` 只在请求未过期时生效,迟到的应答不更新数据(`US-07`)。
|
||||
待确认:用哪些字段对应、超时如何判定(`Q5`)。
|
||||
- **C-24** 出站信箱 `COUTMSGS`:消费方是 CIIMS adapter。`RQRD` 与 `RQFD` 各自同时最多一条已落信、未结案的请求;同一子类型发新请求时旧请求作废,新请求登记为待发送,等同一报文类型的在途请求收到应答、失败或超时后再落信;请求超过时限未等到应答标记超时(`US-09` AC1)。收到 `EROR` 时定位到本系统发出的请求,标记失败并告警(`US-09` AC3)。重试只针对仍有效且确认未落信的请求;写入结果不明时记录并告警,不直接重发;交付承诺只到落信(架构「主流程」)。
|
||||
待确认:ACK 与错误列的语义及写入责任、出站行的清除与保留期、重复落信的识别规则(`Q10`)。
|
||||
- **C-25** 删除主航班时级联删除其共享航班,原子提交、不删一半;本系统不向 AODB 回发 `EROR`(`US-06` AC2)。
|
||||
- **C-26** 日计划快照里没有携带的字段视为 AODB 已删除该值,本地同步清除(`US-07` AC3)。
|
||||
|
||||
### 2.3 HTTP 入口
|
||||
|
||||
- **C-28** `POST /cminmsgs/send` 的响应只表示接收结果:成功返回信箱编号,失败不返回编号;媒体类型支持 `text/xml`、`application/xml`、`text/plain`,默认 UTF-8;空报文、超过大小上限与非法 XML 不落信;解析禁用外部实体与外部资源访问;仅限内网,来源由网络层限制。
|
||||
待确认:请求体上限取值与失败响应样例(`Q3`)。
|
||||
- **C-33** `POST /schd/sync` 触发一次 `RQFD` 日计划请求;成功响应无论表示已登记还是已落信,都不代表 AODB 已收到,交付承诺止于落信(`C-24`)。
|
||||
待确认:成功响应表示已登记还是已落信(`Q17`)。
|
||||
|
||||
### 2.4 下游(admin-api 与运营航班显示界面)
|
||||
|
||||
- **C-29** 对外投递按至少一次设计,不承诺端到端恰好一次:应用重启与待发事件重发都可能让同一条消息多发一次。主题 `msg` 上同一 `FLID` 的变更保序,跨 `FLID` 不承诺顺序;`schd` 不在本条保序范围内。
|
||||
待确认:Kafka key 与分区规则(`Q4`)。
|
||||
- **C-31** admin-api 直接读取本系统写入的静态参考数据表;本系统不调用 admin-api,也不从它拉取、补全或合并数据。
|
||||
- **C-32** Redis 航班投影的读取口径:网页客户端与 `GET /all/flights` 读同一份投影,返回当前全部动态航班(不含共享航班)、不分页;投影只由本系统写入和移除,不是权威、也不存处理状态;Redis 异常时报错,不返回空列表(`INV-24`)。
|
||||
待确认:投影 key/value 结构与网页客户端读取约定(`Q20`)。
|
||||
|
||||
### 2.5 已作废条款
|
||||
|
||||
- **C-1** ID 单调:信箱 ID 按提交顺序分配,已发布水位之下不再出现更小的新 ID。`[待确认 Q2]` **[作废 by C-30]**
|
||||
- **C-2** ID 分配 → 事务可见时延上界由库方**直接给出**。该值决定空洞老化阈值;**不可由 SIS 报文 `Expiry` 推导**(`Expiry` 是报文保留与传输恢复口径,与「ID 分配后多久对读事务可见」不是同一个量)。`[待确认 Q2]` **[作废 by C-30]**(2026-09-14:扫描改为处理标记谓词,按轮自愈,可见时延不再决定任何阈值。)
|
||||
- **C-3** ID 空间不复位、不复用、不回退:含表轮换、备份恢复、`AUTO_INCREMENT` 归零。采用整表轮换方案时,新表种子必须 ≥ `max(ID)+1`,保证 ID 不断链;本系统的水位 `W` 是不可逆单游标,ID 回退会导致其后所有行永久不可见。`[待确认 Q2]`
|
||||
- **C-4** 报文行不可变:同一业务身份(`SNDR|TYPE|STYP|SEQN`)的重发必为同一内容。若上游会以同一身份改发正文,需要另定识别规则(`Q15`)。`[待确认 Q15]`
|
||||
|
||||
**保留与清除(标记、保留期、清除前提)**
|
||||
|
||||
- **C-5** 处理标记值集与写权限:本系统只写入库方认可的 legacy 值集内的「已处理」值(默认值见 [reference.md](reference.md) `PARAM:mailbox.processed-value`),只写空标记、不回撤、不覆盖;内部原因(死信、重复、放弃)记录在自有 PG,**不在信箱新增枚举**。`[待确认 Q7]`
|
||||
- **C-6** 清除语义必须是「标记 + 保留期」:打标本身不触发清除,触发条件是「到达保留期 `R_keep`」且「边界内全部行已打标」。若库方语义是「打标即可清除」,则清除前置条件不成立,且**增大 `R` 无法补救**,必须与库方另定保留期。`[待确认 Q7][待确认 Q9]`
|
||||
- **C-7** 保留期下界(本文件是唯一定义处):
|
||||
`R_keep ≥ max(审计期限, 回填重试上限)`。
|
||||
报文在 CIIMS 的 `Expiry`(480 分钟量级,`SIS:3.16`)可作为原文保留期的参照,但它是报文有效期,不等于本处所需的保留期。`[待确认 Q7][待确认 Q9]`
|
||||
- **C-8** 清除前置条件(本文件是唯一定义处):执行清除时,边界内**每行必须已有终局**——即「已持有处理标记」**或**「已登记在本系统的回填放弃清单中且经人工对账确认」。放弃行不写标记,未达终态的行顺延至处理完成后清除;本系统不执行 DDL,也不写共享历史表。`[待确认 Q7][待确认 Q9]`
|
||||
- **C-9** 清除执行方与方案:清除由库方执行或书面授权执行。方案 A(按 `DATE_RECEIVED` 日分区 + `TRUNCATE/DROP PARTITION`)为首选;方案 B(`CREATE TABLE ... LIKE` + 保留窗复制 + `RENAME TABLE` + 对账 + `CMINMSGS_HST` 归档 + `DROP`)为备选。现场 MySQL 版本与分区 DDL 能力待确认。`[待确认 Q9]`
|
||||
- **C-10** 时间语义:时间比较与换算统一采用机场时区 `Asia/Shanghai` 及明确类型转换;`DATE_RECEIVED` 由上游/库方写入,其时钟基准需可解释(见 `PRE-4`)。`[待确认 Q7]`
|
||||
|
||||
**原文保留**
|
||||
|
||||
- **C-11** legacy 现役按接收超 1 天归档并删除 `CMINMSGS`;若沿用该窗口,则与 `C-7` 冲突,须以 `C-7` 为准。`[待确认 Q9]`
|
||||
- **C-12** 若原文被提前清除(违反保留契约),本系统的死信处置不变,按契约违例走运维追责;该情形不改变 `C-8` 的清除前提。`[我们单方承诺]`
|
||||
|
||||
**我们向库方的承诺**
|
||||
|
||||
- **C-2** ID 分配 → 事务可见时延上界由库方**直接给出**。该值决定空洞老化阈值;**不可由 SIS 报文 `Expiry` 推导**(`Expiry` 是报文保留与传输恢复口径,与「ID 分配后多久对读事务可见」不是同一个量)。**[作废 by C-30]**
|
||||
- **C-11** 原文保留期是否沿用旧系统的 1 天窗口待确认;无论取何值都必须满足 `C-7` 的下界。`(待确认 Q9)` **[作废 by C-6]**
|
||||
- **C-13** 只读约定区间的信箱行(`ID > W`),单活动实例运行,不引入并行消费者。`[我们单方承诺]` **[作废 by C-30]**
|
||||
- **C-14** 不建表、不改表结构、不迁移 schema、不写共享历史表;兼容 HTTP 入口按既有契约写入入站信箱。`[我们单方承诺]`
|
||||
- **C-15** 处理标记只写 `C-5` 认可的值,不回撤、不覆盖已有非空标记。`[我们单方承诺]`
|
||||
- **C-16** 回填放弃清单在对应信箱边界被清除前必须保持可查:`C-8` 以本清单作为清除授权证据之一,该证据不得随处理记录的清除而消失。`[我们单方承诺][待确认 Q7][待确认 Q9]`
|
||||
- **C-30** 信箱读取口径:本系统按配置周期扫描信箱,谓词为「处理标记为空」,按编号升序读取、每批有上限;单活动实例运行,不引入并行消费者。编号即到达顺序:已读过的编号之后不应再出现更小的新编号(较小编号迟提交只会被发现得晚,不会丢;ID 空间不复位、不复用见 `C-3`)。`[我们单方承诺]`(顺序依据 `[待确认 Q2]`)
|
||||
- **C-22** 报文不可变,见 `C-4`。`(待确认 Q15)` **[作废 by C-4]**
|
||||
|
||||
### 2.2 上游(SIS / AODB)
|
||||
|
||||
- **C-20** 业务身份四元组 `SNDR|TYPE|STYP|SEQN` 的语义由上游定义;`SEQN` 的取值范围与回绕见 `SIS:2.8.1`。**重置周期未知**,它决定业务身份是否加入日期边界(默认不加)。`SNDR` 取值域也需对拍(SIS 为 AODB/RMS,legacy 实发 OSH5 等)。`[待确认 Q11]`
|
||||
- **C-21** `FLID` 在保留期内不复用。若复用,事件版本(`STATE_VERSION`)必须按 incarnation 作用域,否则「保留最新版本」的合并规则会把新航班的事件压掉,旧 tombstone 也可能删掉在用航班。`[待确认 Q16]`
|
||||
- **C-22** 报文不可变(同 `C-4`)。`[待确认 Q15]`
|
||||
- **C-23** 请求/应答回显契约:目标优先按已确认的回显字段精确匹配;回显未确认时的降级匹配(同类开放请求且报文 `DTTM ≥ sentAt`)存在跨代误配风险,必须明确接受并审计,不得宣称精确关联。比较前统一时区与时间单位。`[待确认 Q5]`
|
||||
- **C-24** 出站信箱 `COUTMSGS`:消费方为 CIIMS adapter。未确认项:消费顺序、`COUTMSGS_ACK_DATE_RECV` / `COUTMSGS_ACK_RESEND_TIMES` / `COUTMSGS_DATE_SENT` / `COUTMSGS_ERROR` 各列语义与写入责任、出站行清除责任与保留期、落信成功但本地未置 `SENT` 时的重复写入风险及下游去重契约。本系统对出站的交付承诺只到**落信**为止。`[待确认 Q10]`
|
||||
- **C-25** 删除主航班时级联删除其共享航班,原子提交、不允许删一半;不向 AODB 回发 EROR。`[我们单方承诺]`(2026-09-14 定案,依据 `US-06` AC2;SIS 原要求见 `SIS:1.6.1-1.d`、`SIS:4.8`。)
|
||||
- **C-26** 日计划快照中未携带的可选字段视为 AODB 已删除该值,本地同步清除。`[我们单方承诺]`(2026-09-14 定案,依据 `US-07` AC3;SIS 语义见 `SIS:3.16-note-4`、`SIS:3.17`。)
|
||||
- **C-28** 兼容 HTTP 入口的响应只表示**接收结果**,不表示业务处理成功:成功返回信箱编号,失败不返回编号;目标为现役 `ResponseDto`。请求媒体类型支持 `text/xml`、`application/xml`、`text/plain`,默认 UTF-8;请求体上限取值(暂定 10MB)与失败响应样例仍需与现役逐项对拍。仅限内网使用,来源由网络层限制。`[待确认 Q3]`
|
||||
- **C-29** 对外投递按**至少一次**设计,不承诺端到端恰好一次;Kafka 消息的 key 为 `FLID`,同一 `FLID` 内保序,跨 `FLID` 不承诺顺序。`[待确认 Q4]`
|
||||
|
||||
### 2.3 下游(admin-api)
|
||||
|
||||
- **C-31** admin-api 直接读取本系统写入的静态参考数据表;本系统不调用 admin-api,也不从 admin-api 拉取、补全或合并任何数据。`[我们单方承诺]`
|
||||
|
||||
## 3. 前提(外部提供)
|
||||
## 3. 前提
|
||||
|
||||
前提失效时不变量必须整体重估。
|
||||
|
||||
| 编号 | 前提 | 若不成立的影响 | 状态 |
|
||||
|---|---|---|---|
|
||||
| PRE-1 | 信箱消费权排他:同一时刻只有一个系统有权处理、打标、判定可清除(迁移期由切流规程保证单一权威写者) | 采集谓词、身份去重、清除前提全部失效 | `[待确认]`(切流由运维规程保证,上线前另立) |
|
||||
| PRE-2 | 信箱 ID 分配顺序即到达顺序:见 `C-30` | 「编号即到达顺序」的顺序声称失去依据 | `[待确认 Q2]` |
|
||||
| PRE-3 | ID 空间不复位、不复用、不回退:见 `C-3` | 处理记录按信箱编号唯一的前提被破坏,同编号可能重复登记 | `[待确认 Q2]` |
|
||||
| PRE-4 | 报文的 `DATE_RECEIVED` 时钟基准可解释(偏斜在有界范围内) | 跨系统时间比较(`RECEIVED_AT` 与本地 `NOW`)会提前或推迟判定 | `[待确认 Q7]` |
|
||||
| PRE-5 | 单活动实例运行(信箱读取不加锁) | 并行读会让「已处理」判定互相踩踏 | `[我们自证]`(部署约束,见 architecture.md) |
|
||||
| PRE-6 | 信箱与自有 PG 之间没有跨库事务 | 回填、清除都不能声称原子 | `[我们自证]`(架构事实) |
|
||||
| PRE-7 | 报文不可变:同一业务身份的重发必为同一内容:见 `C-4` | 上游改发会被判为重复并静默跳过 | `[待确认 Q15]` |
|
||||
| PRE-8 | `FLID` 在保留期内不复用:见 `C-21` | 「保留最新版本」的合并规则可能压掉新航班事件,旧 tombstone 可能删掉在用航班 | `[待确认 Q16]` |
|
||||
| PRE-1 | 信箱消费权排他:同一时刻只有一个系统有权处理、打标与判定可清除 | 采集谓词、身份去重与清除前提全部失效 | 由切流规程保证,上线前另立 |
|
||||
| PRE-2 | 信箱编号的分配顺序即到达顺序 | 「编号即到达顺序」的顺序声称失去依据 | 待确认 `Q2` |
|
||||
| PRE-3 | 信箱编号空间不复位、不复用、不回退 | 同一编号可能重复登记 | 待确认 `Q2` |
|
||||
| PRE-4 | 信箱时间列的时钟基准可解释,偏斜有界 | 与本地时间的比较会提前或推迟判定 | 待确认 `Q7` |
|
||||
| PRE-5 | 单活动实例运行,信箱读取不加锁 | 并行读会让「已处理」判定互相踩踏 | 部署约束 |
|
||||
| PRE-6 | 信箱与自有 PG 之间没有跨库事务 | 回填与清除都不能声称原子 | 架构事实 |
|
||||
| PRE-7 | 报文不可变:同一业务身份的重发是同一内容 | 上游改发正文会被判为重复并静默跳过 | 待确认 `Q15` |
|
||||
| PRE-8 | `FLID` 在保留期内不复用(见 `C-21`) | 「只进不退」的合并可能压掉新航班事件,旧的删除标记可能删掉在用航班 | 待确认 `Q16` |
|
||||
|
||||
运行约束:测试环境的实例使用独立的数据库、Redis 与 Kafka 主题,不连接生产信箱(`OPS-3`)。
|
||||
|
||||
## 4. 不变量
|
||||
|
||||
### 4.1 管道
|
||||
|
||||
- **INV-1** 五个独立事实互不替代:落信 / 入队 / 处理完成 / 已回填 / 投递确认各有独立证据,前一个不蕴含后一个。
|
||||
- **INV-2** 水位与入队同事务:不允许出现「水位已推进、消息未入队」的持久化状态;水位只增不减,遇空洞即停,只有判定为永久空洞才放行,且放行只跳过空洞本身、不越过任何已存在的行。**[作废 by INV-2b]**
|
||||
- **INV-2b** 扫描谓词与幂等登记:每轮按编号升序读取「处理标记为空」的信箱行,每批有上限;同一编号只登记一次(`INV-9`);重复扫描与重启恢复不重复登记、不重复处理、不丢行;终态但未回填的行会被重复读到,按已有记录幂等跳过。
|
||||
- **INV-3** 队头唯一:任一时刻只有一个可执行队头(最小未完成 `MSG_ID`,`PENDING` 与 `FAILED` 都占位);`FAILED` 未退避到期时后续消息不得越过。
|
||||
- **INV-4** 只领取已发现的行:主泵只领 `MSG_ID ≤ W`;水位之外的行只可能来自兼容入口,必须等水位追平后按序处理。**[作废 by INV-2b]**(水位取消,兼容入口写入的行即普通行。)
|
||||
- **INV-5** 发现与处理互不阻塞:收报只看 `ID > W`,不以处理标记为谓词;终态而未回填的行不阻断后续消息的发现。**[作废 by INV-2b]**
|
||||
- **INV-6** 处理终态不可逆:已提交的 `SUCCEEDED` 不因回填或投递失败回改。
|
||||
- **INV-1** 五个事实互不替代:落信、登记、处理完成、回填、投递各有独立证据,前一个不蕴含后一个。
|
||||
- **INV-2b** 扫描谓词与幂等登记:每轮按编号升序读取「处理时间为空」的信箱行,每批有上限;同一编号只登记一次;重复扫描与重启恢复不重复登记、不重复处理、不丢行。
|
||||
- **INV-3** 队头唯一:任一时刻只有一个可执行的队头(编号最小的未完成消息),队头未完成时后面的消息不得越过。
|
||||
- **INV-6** 处理终态不可逆:已提交的成功不因回填或投递失败回改。
|
||||
- **INV-7** 处理标记单调:任何路径只把空标记写成已处理值,不回撤、不覆盖。
|
||||
- **INV-8** 回填只针对终态(`PENDING` / `FAILED` 永不写标记);「还欠一次回填」的事实与终态由**同一条语句**落库,不存在第二处落账。
|
||||
- **INV-9** 一信一行、一身份一记录:`PROC_STATE` 按 `MSG_ID` 唯一;同一业务身份至多绑定一条有效处理记录。
|
||||
- **INV-8** 回填只针对已有终态的消息;「还欠一次回填」与终态由同一条语句落库,不存在第二处落账。
|
||||
- **INV-9** 一信一行、一身份一记录:处理记录按信箱编号唯一,同一业务身份至多绑定一条有效记录。
|
||||
- **INV-10** 对外投递至少一次;端到端恰好一次不在交付范围。
|
||||
- **INV-16** 回填与 Kafka 投递失败可重试,不回滚已提交的本地业务结果;出站请求写入结果不明时记录告警、不直接重发(`C-24`)。
|
||||
- **INV-17b** 状态变更与待发事件在同一事务提交;处理终态与回填意图在另一事务提交,且晚于 Redis 投影写成功。日计划的分批与静态参考数据的单事务见架构「主流程」。
|
||||
- **INV-19** 整包校验失败或运营日冲突时整包不落地,既有状态与版本不变。
|
||||
- **INV-20b** 处理器幂等:同一消息在失败重处理与重复发现下都只产生一次业务效果。身份唯一只防「重复记录」,不防「重新执行」;逐类幂等规则补齐前本条不可声明(`CLM-3`)。
|
||||
|
||||
### 4.2 航班域
|
||||
|
||||
- **INV-11** 自有 PG 的航班当前态是唯一权威;信箱、Kafka、展示视图都不是权威。**[作废 by INV-11b]**
|
||||
- **INV-11b** 自有 PG 的航班当前态是唯一权威;信箱、Redis 投影、Kafka、展示视图都不是权威。
|
||||
- **INV-12** `FLID` 唯一;已写入非空的 `OPERATION_DAY` 不可改变。
|
||||
- **INV-13** 每个航班每次成功状态写入单调推进 `STATE_VERSION`;重复消息不重复推进。
|
||||
- **INV-12** `FLID` 唯一;已写入非空的运营日不可改。
|
||||
- **INV-13** 每次成功写入版本号加一;重复消息不重复加,版本不回退。
|
||||
- **INV-14b** 增量报文未携带的字段不被隐式清空。日计划快照不适用本条(`INV-15b`)。
|
||||
- **INV-15b** 日计划快照以 AODB 下发为准:快照里没有的航班删除——标记已删除、登记删除事件、从 Redis 投影移除;未携带的字段同步清除(`US-07` AC2/AC3)。
|
||||
- **INV-18** 航班表的写者是主泵处理器与航班历史清理,两者必须互斥,不得出现清理删除与处理器更新同一个 `FLID` 的竞态。
|
||||
- **INV-21** 主航班与其共享航班不出现只删一半的状态:删除共享航班时联动更新其主航班,删除主航班级联删除其共享航班(`US-06` AC2)。
|
||||
- **INV-22** 主航班与共享航班的删除在同一 PG 事务内提交。被删除的航班从 Redis 投影移除;删除共享航班时,主航班的投影随更新结果刷新。移除与刷新都成功后才算这次处理完成(`INV-17b`、`INV-23`)。
|
||||
|
||||
### 4.3 投影、投递、历史与参考数据
|
||||
|
||||
- **INV-23** Redis 投影写成功才算处理完成:写失败的消息不置终态、不写回填标记,保持未完成、下轮重新处理;自有 PG 已提交的业务结果不回滚。
|
||||
- **INV-24** Redis 航班投影只由本系统写入和移除;`GET /all/flights` 与网页客户端读同一份,返回当前全部动态航班(不含共享航班),不分页;Redis 异常时报错,不返回空列表伪装成功。
|
||||
- **INV-25** 处理记录清理:只删「已有终态且已回填」并超过保留期的记录,未完成的不删,保留期可配置;未映射字段的记录不随处理记录到期清理(`US-05` AC3)。
|
||||
- **INV-26** 静态参考数据按类别与编号保存,新消息覆盖旧记录;全量消息整体替换,增删改消息逐条处理;字段为空表示「当前没有值」,不是删除。
|
||||
- **INV-27** 一类参考数据校验不通过就只停这一类,其他类照常;该类的已有记录不变。
|
||||
- **INV-28** 航班只在历史写入确认成功后才从实时数据删除,删除前按 `D1` 必要时登记待发删除事件,历史存储未接通时一条也不删;写失败的下轮重来,已写入的不重复写入,单个航班失败不影响其他航班。与消息处理的互斥见 `INV-18`。
|
||||
|
||||
### 4.4 已作废条款
|
||||
|
||||
- **INV-2** 水位与入队同事务:不允许出现「水位已推进、消息未入队」的持久化状态;水位只增不减,遇空洞即停,只有判定为永久空洞才放行,且放行只跳过空洞本身、不越过任何已存在的行。**[作废 by INV-2b]**
|
||||
- **INV-4** 只领取已发现的行:主泵只领 `MSG_ID ≤ W`;水位之外的行只可能来自兼容入口,必须等水位追平后按序处理。**[作废 by INV-2b]**(水位取消,兼容入口写入的行即普通行。)
|
||||
- **INV-5** 发现与处理互不阻塞:收报只看 `ID > W`,不以处理标记为谓词;终态而未回填的行不阻断后续消息的发现。**[作废 by INV-2b]**
|
||||
- **INV-11** 自有 PG 的航班当前态是唯一权威;信箱、Kafka、展示视图都不是权威。**[作废 by INV-11b]**
|
||||
- **INV-14** 报文未携带的字段不被隐式清空;集合按完整合并结果写入,保留输入顺序与源序号。**[作废 by INV-14b]**
|
||||
- **INV-14b** 增量报文(FLOP/ADFT)未携带的字段不被隐式清空;集合按完整合并结果写入,保留输入顺序与源序号。日计划快照不适用本条(`INV-15b`)。
|
||||
- **INV-15** 缺席于某个日计划不构成删除理由;删除只由 FDEL 或受控历史清理触发。**[作废 by INV-15b]**
|
||||
- **INV-15b** 日计划快照以 AODB 下发为准:快照里没有的航班删除——标记已删除、登记删除事件、从 Redis 投影移除;快照里未携带的字段视为 AODB 已删除该值,本地同步清除(`US-07` AC2/AC3)。
|
||||
- **INV-16** 外部副作用(回填、Kafka 投递、出站信箱)失败可重试,但不回滚已提交的本地业务结果。
|
||||
- **INV-17** 状态变更、待发事件、处理终态与回填意图在同一 PG 事务内原子提交。**[作废 by INV-17b]**
|
||||
- **INV-17b** 状态变更与待发事件在同一 PG 事务内提交;处理终态与回填意图在同一 PG 事务内提交,且该事务在 Redis 投影写成功之后(`INV-23`)。日计划例外:分批写入,每批一个事务(状态变更 + 待发事件),终态与回填意图在整包完成后同一事务提交;失败不标记已处理,下轮整包重新处理(`US-07` AC4)。静态参考数据不产生待发事件与投影写,落库、终态与回填意图在同一事务提交。
|
||||
- **INV-18** 航班表的写者集合是「主泵处理器」与「历史清理」;两者必须互斥(同一 `PIPELINE_LOCK`,或清理在同一事务内复查判据后再删除),不得出现清理删除与处理器更新同一 `FLID` 的竞态。
|
||||
- **INV-19** 整包校验失败或运营日冲突时整包不落地,既有状态与版本保持不变。
|
||||
- **INV-20** 处理器幂等:同一消息重复执行只产生一次业务效果。身份唯一只防「重复记录」,不防「重新执行」;SIS 25 类与经 `Q8` 定案启用的 legacy 子类型完成逐类幂等矩阵前,本条**不可声明**(`G-FLOP-IDEMPOTENT`)。**[作废 by INV-20b]**
|
||||
- **INV-20b** 处理器幂等:同一消息重复执行(失败重处理、重复发现)只产生一次业务效果。身份唯一只防「重复记录」,不防「重新执行」;逐类幂等矩阵(SIS 25 类与现场延续的 7 类)补全前,本条**不可声明**(`G-FLOP-IDEMPOTENT`)。
|
||||
- **INV-21** `MAFL` 是派生投影:内容恒等于「`STATE = ACTIVE` 且 `MAID = 主航班 FLID`」的子航班集合(元素 `FLID` + `FLNO`,按 `FLID` 升序),不落库、不从入站解析;自引用与悬挂引用不入投影。
|
||||
- **INV-22** 子航班集合变化必须使涉及的主航班在同一事务内推进 `STATE_VERSION` 并登记主航班事件;投影只进不退,版本不推进即被下游丢弃。
|
||||
- **INV-23** Redis 投影写成功才算处理完成:写失败的消息不置终态、不写回填标记,保持未完成,下轮重新处理;自有 PG 已提交的业务结果不因此回滚(`US-05` AC4、`US-06` AC1)。
|
||||
- **INV-24** Redis 航班投影只由本系统写入与移除;`GET /all/flights` 与网页客户端同源读 Redis;Redis 异常时报错,不返回空列表伪装成功(`US-12` AC1/AC2)。
|
||||
- **INV-25** 处理记录清理:只删「终态且已回填」且超过保留期的记录;未完成的不删。保留期可配置(`US-11`)。
|
||||
- **INV-26** 静态参考数据按(类别, 编号)保存,新消息覆盖旧记录;全量消息整体替换,增删改消息逐条处理;消息里字段为空表示「当前没有值」,不是删除(`US-13` AC1/AC3/AC4)。
|
||||
- **INV-27** 一类参考数据校验不通过就不更新这一类,其他类照常处理;该类已有数据不动(`US-13` AC2)。
|
||||
- **INV-28** 航班先写历史存储、确认成功后才从实时数据删除;写入失败下次重来,已写入的不重复写入;单个航班失败不影响其他航班;正在被消息处理的航班跳过、下轮再处理(`US-14` AC3/AC4;写者互斥见 `INV-18`)。
|
||||
|
||||
## 5. 声明边界
|
||||
|
||||
| 编号 | 主张 | 依赖 | 当前可否声明 | 挂起原因 |
|
||||
| 编号 | 承诺 | 依赖 | 现在能否作出 | 限制或原因 |
|
||||
|---|---|---|---|---|
|
||||
| CLM-3 | 失败重处理与重复发现不产生重复业务副作用 | INV-20b、`G-FLOP-IDEMPOTENT` | **不可** | 逐类幂等矩阵未补全 |
|
||||
| CLM-4 | 回填不会被短暂故障放弃:最终打标,或进入可对账的放弃清单 | INV-8、`C-5`、`C-8` | **可声明(有条件)** | 条件:`R` 之前不放弃;`MISSING_ROW` 立即放弃并告警;放弃行须经人工对账才可用于清除判定(`C-8`) |
|
||||
| CLM-6 | 单实例内严格 FIFO | PRE-5、INV-3 | **可**(限于单活动实例) | — |
|
||||
| CLM-7 | 事件投递在同一 `FLID` 内保序 | INV-10、投递设计 | **可**(跨 `FLID` 不承诺) | 实现当前按目标级全序投递,收敛到按 `FLID` 属投递改造 |
|
||||
| CLM-8 | 出站交付承诺只到「落信」 | `C-24`、`Q10` | **可**(仅落信语义) | 消费方已定(CIIMS adapter);ACK 列语义未确认 |
|
||||
| CLM-9 | 处理标记延迟由调度周期决定 | — | **不可** | 扫描周期不等于完成时限;批次积压、单行超时与清理作业都会延长实际延迟 |
|
||||
| CLM-10 | 容量量级假设(单实例、入站日消息量千级到万级、单报文 ≤ 10⁴ 字节) | — | **不可** | 未实测,无生产负载数据;解除条件:取得现役信箱日量、峰值与单报文上限后重估 |
|
||||
| CLM-3 | 失败重处理与重复发现不产生重复业务副作用 | `INV-20b` | 不能 | 逐类幂等规则未补齐(`G-FLOP-IDEMPOTENT`) |
|
||||
| CLM-4 | 信箱行最终都被写上处理标记 | `INV-7`、`C-15`、`C-16` | 不能 | 一直写不上的行留案并告警(`US-10` AC2) |
|
||||
| CLM-6 | 单实例内严格 FIFO | `PRE-5`、`INV-3` | 能 | 仅限单活动实例 |
|
||||
| CLM-7 | 主题 `msg` 上同一 `FLID` 内保序 | `INV-10`、`C-29`、`D2` | 能 | 须满足 `D2` 的三项生产端约束;跨 `FLID` 不承诺;不覆盖 `schd` |
|
||||
| CLM-8 | 出站交付承诺只到落信 | `C-24` | 能 | 只覆盖落信;ACK 与错误列语义未确认(`Q10`) |
|
||||
| CLM-9 | 处理标记的写入时刻不等于处理完成的时限 | — | 不能 | 扫描周期不构成完成时限;批次积压与单行重试都会延长实际延迟 |
|
||||
| CLM-10 | 容量与吞吐量级 | — | 不能 | 无实测数据,取得信箱日量、峰值与单报文上限后重估 |
|
||||
|
||||
## 6. 验证映射
|
||||
## 6. 待确认事项台账
|
||||
|
||||
每条不变量至少一条证据。测试名以仓库现状为准;新增测试按本表补位。本表只记录**验收口径与证据位置**,覆盖进展只在 Plane(ACM2)。
|
||||
### 6.1 待对方确认
|
||||
|
||||
| 不变量 / 声明边界 | 场景 | 证据 / 测试 |
|
||||
| 编号 | 事项 | 当前假定 | 影响 |
|
||||
|---|---|---|---|
|
||||
| Q2 | 信箱编号的分配顺序、单调与不复用 | 见 `C-3`、`PRE-2`、`PRE-3` | 「编号即到达顺序」目前无法确认 |
|
||||
| Q3 | 兼容入口的请求体上限与失败响应样例 | 响应语义与解析限制已定(`C-28`) | 兼容入口无法验收 |
|
||||
| Q4 | Kafka 载荷与去重标识 | 两个主题名、`msg` 单条变更、`schd` 定时批量已定(`US-08`;接口契约「Kafka」);`msg` 的 `FLID` 保序见 `C-29`。`schd` 每条 record 装什么、批次边界未定 | key、分区规则、`schd` 粒度及去重标识仍须确定 |
|
||||
| Q5 | 请求与应答的对应字段、超时判定 | 见 `C-23` | 请求跟踪无法闭环 |
|
||||
| Q7 | 处理标记的允许值、原文保留期、处理时间列、信箱时钟基准与时区 | 只填空值,不回撤不覆盖(`C-15`);回填重试期间原文须在(`C-7`) | 允许值、保留期取值与时钟基准未定 |
|
||||
| Q8 | 现场会发但 SIS 未定义的子类型(靠桥、延误等)的报文形态与逐类终态 | 按现有处理逻辑延续(`US-05` AC1) | 逐类终态与幂等规则未定(`G-FLOP-SEMANTICS`) |
|
||||
| Q9 | 清除方案与保留期 | 清除由库方执行(`C-8`);旧系统按接收超过 1 天归档并删除入站行,是否沿用待确认。见 `C-6`~`C-9` | 清除边界与保留期未定 |
|
||||
| Q10 | 出站 ACK 与错误列语义、出站行清理与重复落信识别 | 交付承诺止于落信(`C-24`) | 出站行清理与去重责任未定 |
|
||||
| Q11 | 上游 `SEQN` 的重置周期与身份是否加日期边界 | 暂不加日期边界 | 身份算法不能定稿 |
|
||||
| Q15 | 上游是否会以同一业务身份改发正文 | 假定不可变(`PRE-7`) | 身份去重语义未定 |
|
||||
| Q16 | `FLID` 的重用语义 | 假定保留期内不复用(`C-21`) | 事件合并与删除标记未定 |
|
||||
| Q20 | Redis 投影的 key/value 结构、序列化方式与网页客户端读取约定 | 旧系统线索为 hash `flightInfo`、field 取 `FLID`(见接口契约「Redis:航班查询投影」) | 消费方读取契约无法定稿 |
|
||||
|
||||
答复就地更新结论,并按 [README.md](README.md)「维护清单」落到对应条款。
|
||||
|
||||
### 6.2 已确认
|
||||
|
||||
| 编号 | 事项 | 结论 |
|
||||
|---|---|---|
|
||||
| INV-1 | 五事实互不替代:入队不引用标记、回填不引用投递、投递不引用回填 | 需接口级断言 |
|
||||
| INV-2b | 谓词扫描与批次上限 | 只读「处理标记为空」的行、每批有上限;`InboxPollerTest`(随 `G-SCAN-PREDICATE` 改造重写) |
|
||||
| INV-2b | 重复扫描、重启恢复 | 不重复登记、不重复处理、不丢记录 |
|
||||
| INV-3 | 较小 ID 迟提交 | 迟发现的较小编号仍按编号序登记处理,不丢、不重复 |
|
||||
| INV-3 | 队头失败、退避及作业竞争 | 消息不越队;到期后恢复;作业不使消息无限饥饿 |
|
||||
| INV-6 | 投递失败后终态不变 | 需用例 |
|
||||
| INV-7 | 回填四种结果 | 写入成功 / 早已标记(不覆盖、记成功)/ 信箱行不存在(立即放弃并告警,不得视为已标记)/ 暂时故障持续到 `R` 仍未打标(停止自动重试,可人工恢复) |
|
||||
| INV-7 | `RECEIVED_AT` 为 NULL | 超期分支仍成立且不导致标记提前写入——判据是本地 `ENQUEUED_AT`,与库方时钟及 NULL 无关 |
|
||||
| INV-8 | PG 提交失败、回填失败 | 事件、终态与回填意图一起回滚;已提交结果只补写标记,不重放业务;中间态永不补写 |
|
||||
| INV-8 | 非业务型终态 | 不触碰航班表 / `MSG_EVENT`,只写 `PROC_STATE`,且终态与回填意图同语句生效 |
|
||||
| INV-9 | 同身份多条记录、失败后重试、清理后重复 | 只产生一次有效业务处理,不把自身重试判为重复 |
|
||||
| INV-10 | 投递确认丢失、批次失败、次数耗尽 | 允许可识别的重发、保持目标顺序、整批退避并保留死信 |
|
||||
| INV-11b | 权威唯一 | 需断言信箱、Redis 投影、展示视图不成为写入或对账来源 |
|
||||
| INV-12 / INV-13 | PG 事务失败、快照重复或迟到 | 整体回滚重试、不重复推进版本、不回退状态、不误删增量航班 |
|
||||
| INV-12 | 运营日冲突 | 整包 `DEAD(PROTOCOL)`,既有状态与版本不变 |
|
||||
| INV-14b | 增量未携带字段保留、显式清空才清除;集合按完整合并结果写入 | `FlightStateEngineTest`「flop merge retains absent scalars and collections」;`FdelAndAdftProcessorTest`「ADFT merge does not clear absent scalars」 |
|
||||
| INV-14b | FLOP 逐类空标签语义(清除、撤销、集合清空)与「未携带不清空」的区分 | 逐类用例见 [implementation.md](implementation.md)「动态运行事件」;`G-FLOP-UNMAPPED`、`G-FLOP-SEMANTICS` |
|
||||
| INV-15b | 快照缺席航班删除、未携带字段清除;增量不适用快照语义 | 新增用例(`G-SCHD-SNAPSHOT`) |
|
||||
| INV-16 | 外部副作用失败后本地结果不变 | 需用例 |
|
||||
| INV-17b | 状态与事件同事务;终态与回填意图同事务且晚于 Redis 写成功;日计划分批 | 需真实 PG 用例 |
|
||||
| INV-18 | 清理与处理并发 | `HistorySweepJobTest`(归档后被主泵更新的航班不删除、不发 tombstone)+ `HistorySweepPurgePgTest`(删除阶段失败时 tombstone 与删除整体回滚) |
|
||||
| INV-19 | 整包协议拒绝(声明数不符、运营日冲突) | `DEAD(PROTOCOL)`,整包不落地、整体回滚、既有状态不变 |
|
||||
| INV-21 | `MAFL` 投影与 `ACTIVE` 子航班集合一致(子航班删除后退出、自引用与悬挂引用不入、顺序确定) | `G-MAFL`:投影未实现 |
|
||||
| INV-22 | 子航班新增、删除、`MAID` 迁移时主航班版本与事件 | `G-MAFL`:主/共享级联未实现 |
|
||||
| INV-20b / CLM-3 | 同一消息失败重处理、重复发现 | 阻塞于逐类幂等矩阵(`G-FLOP-IDEMPOTENT`) |
|
||||
| INV-23 | Redis 写失败 | 消息保持未完成、不提前写标记;重处理收敛 |
|
||||
| INV-24 | 同源读取与异常 | Redis 异常时报错、不返回空列表 |
|
||||
| INV-25 | 清理谓词 | 只删「终态且已回填」超保留期的记录 |
|
||||
| INV-26 / INV-27 | 参考数据覆盖 / 全量替换 / 空标签 / 逐类门控 | 需用例(`G-REF-DATA`) |
|
||||
| INV-28 | 历史先行 | 历史未确认成功删除 0 条;已写入不重复写入 |
|
||||
| — | 请求超时、无匹配 RESP、时间单位不一致 | 不误用迟到应答、不提前完成请求 |
|
||||
| — | stub 误配置、重复实例、停机中断 | 生产拒绝不安全启动,工作线程能正确退出 |
|
||||
| Q13 | 日计划未携带字段的删除语义 | 见 `C-26` |
|
||||
| Q14 | 主/共享删除顺序与 EROR 回报义务 | 见 `C-25` |
|
||||
|
||||
上表首列是**引用**(`INV-x` 的定义见本文件「不变量」);同一行可覆盖多个 `INV`,例如 `INV-20b / CLM-3`。
|
||||
### 6.3 本系统与需求方待决
|
||||
|
||||
声明边界的证据指针:`CLM-4` 断言放弃行不写标记、不被当作已打标;`CLM-9` 由作业心跳与回填年龄指标提供观测(指标名见 [reference.md](reference.md)「指标与健康」),实际延迟仍需现场数据。
|
||||
以下事项不出自对接方,由本系统与需求方决定:
|
||||
|
||||
| 编号 | 事项 | 当前假定 | 影响 |
|
||||
|---|---|---|---|
|
||||
| Q1 | 生产库选型 | 自有 PG 是唯一权威;生产环境用 PostgreSQL 还是 Oracle 11g 不能从三份依据确定,Oracle 适配验证通过前不作支持承诺 | 生产部署验收 |
|
||||
| Q17 | `POST /schd/sync` 的成功响应表示已登记还是已落信 | 架构只约定交付承诺止于落信(`C-24`),两种含义都相容 | 响应契约无法定稿(`C-33`) |
|
||||
| Q18 | 人工发起 `RQRD` 的方式 | `US-09` 要求人工发起,HTTP 接口清单没有对应入口 | 参考数据请求无法人工触发 |
|
||||
| Q19 | `msg` 的版本与去重标识是否直接采用航班当前态的版本号 | 可用依据是 `FLIGHT_SCHD` 的版本规则(`INV-13`) | 消费方去重规则未定(与 `Q4` 衔接) |
|
||||
|
||||
## 7. 当前已知偏差
|
||||
|
||||
本表是**偏差标记的唯一出处**:其他文档只在相应位置写 `G-NAME`,不解释、不记进度。偏差只写事实与受影响稳定 ID,不写负责人、日期、进度或 Plane 状态;闭合时在同一变更中删除本行与全仓 `G-NAME` 引用,关闭证据留在 Plane。
|
||||
本表是偏差标记的唯一出处,其他文档只写 `G-NAME`。闭合时删除本行与全仓引用。
|
||||
|
||||
| 偏差 | 含义 | 影响 |
|
||||
| 偏差 | 缺什么,会怎样 | 影响 |
|
||||
|---|---|---|
|
||||
| `G-RESP-GUARD` | `RESP` 应答守卫未实现,当前与 `DNLD` 无差别进入快照写入 | 请求匹配闭环;`C-23` |
|
||||
| `G-REQ-TRACK` | `REQ_TRACK` 无运行时协调器:出站适配、请求编码、超时与应答匹配未实现 | `US-09`;`C-24` |
|
||||
| `G-FLOP-IDEMPOTENT` | SIS 25 类与现场延续的 7 类(靠桥、延误、计划机位等)尚无完整逐类幂等矩阵 | `INV-20b`、`CLM-3` |
|
||||
| `G-MAFL` | 主航班 `MAFL` 派生投影及主/共享原子级联未实现(规则见 `INV-21`/`INV-22`);`MAFL` 不是 SIS/XML 入站字段 | 航班完整态;删除与重建 |
|
||||
| `G-SRVT-VIPF` | SIS/XML 的 `SRVT`、`VIPF` 无界集合尚未映射到持久化明细;wire/domain 只保留出现事实与原始内容,不参与合并与投递(清空语义见 `Q13`) | 航班完整态;无损字段保存 |
|
||||
| `G-COMPAT-HTTP` | compat 入口尚未按 `US-02` 口径实现:请求体上限取值与失败响应样例未对拍(媒体类型集与成功/失败响应语义已定案) | `C-28`;`US-02` |
|
||||
| `G-REQ-OPEN-UNIQUE` | `REQ_TRACK` 尚无约束开放态 `(REQ_TYPE, OPERATION_DAY, SENDER)` 唯一性的部分索引 | `US-09`;`G-REQ-TRACK` |
|
||||
| `G-REQ-TRACK-RETENTION` | `REQ_TRACK` 关闭态行(`DONE`/`EXPIRED`)的保留期与清除作业未定义 | 自有 PG 无界增长;`US-09` |
|
||||
| `G-FLIGHT-HIST-RETENTION` | 航班历史存储(外部)的保留期与容量上限未定义 | `INV-28`;实时数据物理清除后历史存储是唯一副本 |
|
||||
| `G-FLOP-UNMAPPED` | [XSD](legacy/unisysaodbsis.xsd)「FLOP 元素」的 `FFID`、`UNCL`、`CKOP`、`GTOP`、`CKCL`、`BDOP`、`LCTM`、`BDCL`、`FRET`、`FDIV`、`FLAB`、`RUNW`、`PXNO`、`FLBG`、`CKPB`、`BDPB` 未解码;`CHDT.CCLS/CTYP` 被错误写成 `CHCLS/CHTYP`,均会静默丢失。其中 `FRET`、`FDIV`、`BDPB` 在 legacy 有对应处理 | `US-05`;无损字段保存 |
|
||||
| `G-FLOP-SEMANTICS` | FLOP 未按 SIS 25 类建立 `STYP` 白名单;`ROUT` 未按方向截取至 4 条且仍保存 `SCAT`/`SCDT`;BOTM/LACL 未同步设置或重置运行状态;除 FDEL 外,已删除航班仍会被合并、增版并发事件 | `US-05`、`INV-14b`、`INV-20b` |
|
||||
| `G-REF-DATA` | SIS 静态参考数据处理(`SIS:3.1`~`SIS:3.14`)未实现;当前按「合法但不支持」跳过并回填(`US-03` AC2),独立参考数据表与 admin-api 直读未落地 | `US-13`、`US-03` |
|
||||
| `G-SCAN-PREDICATE` | 收报仍按持久水位 ID 区间扫描(含空洞老化与切流播种),未达「处理标记为空」谓词口径 | `US-01`;`INV-2b` |
|
||||
| `G-REDIS-PROJECTION` | 无任何 Redis 投影写/移除路径:航班动态写入、删除移除、快照刷新、查询读取均未实现 | `US-05`、`US-06`、`US-07`、`US-12` |
|
||||
| `G-SCHD-SNAPSHOT` | 日计划快照未达 `US-07` 口径:缺席航班不删除、未携带字段不清除、整包单事务(需求要求分批、每批一个事务) | `INV-15b`、`INV-17b` |
|
||||
| `G-PROC-CLEANUP` | 处理记录到期清理作业未实现(归档链随 `US-11` 口径废弃) | `US-11`;`INV-25` |
|
||||
| `G-RESP-GUARD` | `SCHD-RESP` 没有过期判断,晚到的应答也会更新本地数据 | `US-07`;`C-23` |
|
||||
| `G-REQ-TRACK` | 出站请求没有跟踪:登记、编码、超时与应答匹配都没有实现 | `US-09`;`C-24` |
|
||||
| `G-REQ-OPEN-UNIQUE` | 同一报文类型同时最多一条已落信、未结案请求的限制没有实现;待发送登记不算占用该名额 | `US-09` |
|
||||
| `G-REQ-TRACK-RETENTION` | `REQ_TRACK` 已结案记录的保留期取值未定,到期清理作业没有可依据的窗口 | `US-09` |
|
||||
| `G-FLIGHT-HIST-RETENTION` | 历史存储的保留期与容量上限未定 | `INV-28`;实时数据删除后历史是唯一副本 |
|
||||
| `G-FLOP-IDEMPOTENT` | 逐类幂等规则未补齐 | `INV-20b`;`CLM-3` |
|
||||
| `G-FLOP-SEMANTICS` | `STYP` 没有白名单,`ROUT` 未限制 4 条,运行状态落点与已删除航班的处理与 `US-05` 不符 | `US-05`;`INV-14b` |
|
||||
| `G-FLOP-UNMAPPED` | [XSD](legacy/unisysaodbsis.xsd)「FLOP 元素」里有些字段没有解码或映射错了,会被静默丢掉 | `US-05` |
|
||||
| `G-MAFL` | 主航班的共享航班列表与主/共享原子级联未实现 | `INV-21`;`INV-22` |
|
||||
| `G-SRVT-VIPF` | `SRVT`、`VIPF` 两个集合没有落到持久化明细 | `US-05` |
|
||||
| `G-SCAN-PREDICATE` | 收报仍按水位扫描,不是按「处理时间为空」读取 | `US-01`;`INV-2b` |
|
||||
| `G-REDIS-PROJECTION` | Redis 投影没有写入与移除路径 | `US-05`、`US-06`、`US-07`、`US-12` |
|
||||
| `G-SCHD-SNAPSHOT` | 日计划快照不删除缺席航班、不清除未携带字段,也没有分批 | `INV-15b`;`INV-17b` |
|
||||
| `G-PROC-CLEANUP` | 处理记录的到期清理作业未实现 | `US-11`;`INV-25` |
|
||||
| `G-REF-DATA` | 静态参考数据没有处理,当前按「合法但不支持」跳过并回填;参考数据表与 admin-api 直读未落地 | `US-13`;`US-03` |
|
||||
|
||||
## 8. 待确认事项台账
|
||||
## 8. 验证映射
|
||||
|
||||
| 编号 | 事项 | 当前假定 | 阻塞 | 状态 |
|
||||
|---|---|---|---|---|
|
||||
| Q1 | 权威存储(内部方向)与生产库选型 | 自有 PG 单库权威 + 无损明细;生产环境用 PostgreSQL 还是 Oracle 11g 未定,Oracle 适配验证通过前不构成支持承诺 | 生产部署验收 | 已定案(内部),生产库待定 |
|
||||
| Q2 | 信箱 ID 分配顺序即到达顺序;ID 空间不复位、不复用 | — | 到达顺序声称(`US-01` AC3) | 未确认 |
|
||||
| Q3 | HTTP 契约:请求体上限取值、失败响应样例 | 上限暂定 10MB(`C-28`) | 兼容入口验收 | 未确认 |
|
||||
| Q4 | Kafka 载荷与去重标识 | 主题/粒度/保序已按 `US-08` 定案:`msg` 发单条变更、`schd` 定时批量发最新状态、key=`FLID` | 投递契约 | 未确认 |
|
||||
| Q5 | 请求匹配:回显字段可靠性与降级匹配 | `RQFD` 60 秒 / `RQRD` 30 秒超时 | 请求跟踪闭环 | 未确认 |
|
||||
| Q7 | 处理标记值集与写权限、原文保留期、处理时间语义 | 写入 `PROCESSED` | 回填值集、保留期下界 | 未确认 |
|
||||
| Q8 | 逐类覆盖:SIS 未定义但现场会发的 7 类(靠桥、延误、计划机位等)的报文形态、除 FDEL 外目标航班不存在/已删除时的逐类终态、BOTM/LACL 运行状态的落点 | 航班动态的字段与空标签规则以 `SIS:3.19`~`SIS:3.43` 为准(`US-05` AC1 定案);静态参考数据以 `SIS:3.1`~`SIS:3.14` 为准(`US-13`);legacy 7 类按现有处理逻辑延续(`US-05` AC1 定案) | 逐类幂等矩阵与 golden(`G-FLOP-SEMANTICS`、`G-FLOP-IDEMPOTENT`、`G-REF-DATA`) | 未确认(不阻塞 `US-13` 验收) |
|
||||
| Q9 | 清除执行方与 DDL 授权、方案 A/B 选型、分区能力 | 首选方案 A | `R_keep` 与清除边界 | 未确认 |
|
||||
| Q10 | 出站 ACK 列语义、出站行清理与去重契约 | — | 出站信箱 | 未确认 |
|
||||
| Q11 | 上游 `SEQN` 重置周期与业务身份的日期边界 | 不含日期边界 | 身份算法 | 未确认 |
|
||||
| Q13 | 日计划缺失可选字段的删除语义 | 结论(2026-09-14):未携带字段视为 AODB 已删除该值,本地同步清除(`C-26`) | — | 已定案 |
|
||||
| Q14 | 主/共享删除顺序与 EROR 回报义务 | 结论(2026-09-14):幂等原子级联、不回发 EROR(`C-25`) | — | 已定案 |
|
||||
| Q15 | 上游是否会以同一业务身份改发正文(决定是否需要区分「重复」与「改发」) | 假定期望不可变(`C-4`) | 身份去重语义 | 未确认 |
|
||||
| Q16 | `FLID` 重用语义(决定版本是否按 incarnation 作用域) | 假定不复用(`C-21`) | 事件合并与 tombstone | 未确认 |
|
||||
|
||||
Q 的答复只在本表就地更新(补「结论」与日期),并触发 [README.md](README.md)「维护清单」的落地 4 步;不另开文件。
|
||||
| 不变量 | 需求验收 | 要观察的结果 |
|
||||
|---|---|---|
|
||||
| INV-2b | `US-01` AC1/AC2/AC4 | 扫描重来与重启后登记数不变,行不丢 |
|
||||
| INV-3 | `US-03` AC1 | 队头未完成时,后面的消息不被处理 |
|
||||
| INV-6、INV-16 | `US-03` AC3 | 失败回滚后消息仍在未完成;已提交结果不被副作用回滚 |
|
||||
| INV-7、INV-8 | `US-10` AC1/AC2 | 标记只写一次;重启后继续,写不上的有记录与告警 |
|
||||
| INV-9 | `US-01` AC2 | 同一编号重复出现时,处理记录数不增加 |
|
||||
| INV-10 | `US-08` AC2 | 失败重试后仍能投出;`msg` 上同一 `FLID` 的顺序不颠倒(`C-29`、`CLM-7`) |
|
||||
| INV-11b | 架构「系统定位与范围」 | 航班当前态的权威写入只在自有 PG |
|
||||
| INV-12、INV-13 | 架构「必须保持的约束」 | 运营日写入后不变;重复消息不推进版本 |
|
||||
| INV-14b | `US-04` AC2、`US-05` AC2 | 未携带的字段保持原值 |
|
||||
| INV-15b | `US-07` AC2/AC3 | 缺席的航班在 PG 标为已删除并从 Redis 投影移除;未携带的字段被清空 |
|
||||
| INV-17b | `US-05` AC4、`US-06` AC1 | 投影写失败时,没有终态与回填意图落库 |
|
||||
| INV-18 | `US-14` AC4 | 历史清理跳过正在被消息处理的航班 |
|
||||
| INV-19 | `US-07` AC1 | 校验失败后本地数据与版本不变 |
|
||||
| INV-20b、CLM-3 | `US-01` AC2、`US-03` AC3 | 重复执行不增加业务效果 |
|
||||
| INV-21、INV-22 | `US-06` AC2 | 主/共享删除联动后没有半删状态 |
|
||||
| INV-23 | `US-05` AC4、`US-06` AC1 | 投影写失败的消息下轮仍被处理 |
|
||||
| INV-24 | `US-12` AC1/AC2 | 返回全部非共享航班,且与 Redis 一致;Redis 故障时返回错误 |
|
||||
| INV-25 | `US-11` AC1/AC2 | 未完成的记录不被删除 |
|
||||
| INV-26、INV-27 | `US-13` AC1~AC4 | 失败类别的已有记录不变 |
|
||||
| INV-28 | `US-14` AC3/AC4 | 历史写入失败的航班仍在实时数据中 |
|
||||
| CLM-4(留案告警) | `US-10` AC2 | 一直写不上的行有记录与告警 |
|
||||
| CLM-9(不承诺完成时限) | `OPS-2` | 积压与延迟有指标与告警 |
|
||||
| CLM-10(容量假设) | `OPS-2` | 上线前用现场量级重估 |
|
||||
|
||||
## 9. 契约数值
|
||||
|
||||
| 量 | 定义处 | 约束 |
|
||||
|---|---|---|
|
||||
| `R_keep` | `C-7` | `R_keep ≥ max(审计期限, 回填重试上限)`;原文保留期下界(重放不在交付范围) |
|
||||
| `R` | [reference.md](reference.md) `PARAM:msgx.pipeline.overdue-backfill` | `R ≤ R_keep`;只决定强补写与放弃期限 |
|
||||
| 去重记忆期 | `INV-9` | = 处理记录保留期(`US-11`);期内同身份去重成立,期满后同身份消息按新消息处理 |
|
||||
| 回填放弃清单可见期 | `C-16` | ≥ `R_keep`;否则库方清除缺 `C-8` 依据 |
|
||||
| 量 | 定义处 |
|
||||
|---|---|
|
||||
| 原文保留期下界 | `C-7` |
|
||||
| 处理记录保留期 | `INV-25` |
|
||||
|
||||
Reference in New Issue
Block a user