docs: 修复跨文档冲突与外部规范口径

不动代码、配置与迁移,只收敛文档口径。

- 登记两项外部冲突:Q13 日计划缺失可选字段(SIS §3.16 注释 4 要求删除本地值,
  与现行"未携带字段保留"相反)、Q14 主/共享删除顺序与 EROR 回报义务
  (SIS §1.6.1-1.d / §4.8);航班级"缺席不删"补 SIS §3.16 注释 1 依据。
- flight-state §3.3 补主/共享关联按 FLID 值比较的规则。
- message-lifecycle:§11 水位不变量与 §5.1 空洞老化自洽;删除过期的 updatedAt
  判据,统一为 PROCESSING_STARTED_AT + 可注入 Clock;§5.1/§6 补 SIS 480 分钟
  Expiry 与 legacy 1 天保留窗,作为 Q2/Q6/Q7 的取值参照。
- architecture/design:明细表口径统一为 8 张资源明细表 + FLIGHT_ROUTE_POINT;
  Oracle 11g 断言收敛为待适配验证;配置键按 application.yml 实际名称加 msgx. 前缀。
- user-stories:Q2/Q6/Q11 补外部锚点并收窄 Q11 到重置周期 + SNDR 值域;
  新增 Q13/Q14 并挂入 US-05/06/08 前置;五个独立事实改为引用 message-lifecycle §1。
- README/legacy:文档基线改为代码基线 eea1120 + git log 指引;补"外部协议冲突以
  SIS 为准"的维护规则;修正 /all/flights 过滤措辞;术语统一为「回填意图」。

验证:文档间章节引用 0 缺失、markdown 0 断链、SIS 引用小节全部存在、
Q1–Q14 正文与 Q 表双向可解析、代码块配对正常。
This commit is contained in:
windyboy
2026-09-10 20:54:01 +08:00
parent eea11203a2
commit 50e0e7f389
7 changed files with 70 additions and 53 deletions
+14 -12
View File
@@ -6,7 +6,7 @@
- 系统边界见 [architecture.md](architecture.md),模块流程见 [design.md](design.md)。本文不重复设计全文,也不以工单状态代替代码验收。消息生命周期与信箱清除见 [message-lifecycle.md](message-lifecycle.md),航班规则见 [flight-state.md](flight-state.md)。
- “当前基础”来自本轮代码核对,只表示有接口或部分实现,不表示故事完成。`KEEP` 是保留业务兼容,`FIX` 是明确修正旧缺陷,`DEFERRED` 不进入阶段 A。
- “信箱落信、PG 入队、业务处理完成、信箱回填、目标端投递确认”是五个独立事实,接口、日志和测试必须分开表达投递确认不等于业务消费者已消费。
- 五个独立事实(落信、入队、处理完成、回填、投递确认)的定义与判定见 [message-lifecycle.md](message-lifecycle.md) §1接口、日志和测试必须分开表达投递确认不等于业务消费者已消费。
- 所有内部迁移只落自有 PG;共享 MySQL 不建表、不增列、不写历史表。本文用 `DATE_PROCESSED / STATUS` 表示逻辑字段,实际列名以库方契约为准。
- 验收条目可按 `US-xx/条目号` 引用。故事较大时按下文子范围拆成小 PR,不把一个故事等同于一个提交。
@@ -42,7 +42,7 @@
4. PG 不可用或批次中途失败时不改信箱标记;恢复后补建遗漏,记录失败次数与扫描进度。
5. 较小 ID 迟提交、ID 有空洞、兼容入口先入队较大 ID 时,必须遵守经 Q2 确认的发现与顺序协议;不能用“最终会重扫”冒充严格 FIFO。
**当前基础与落点**`ingress/InboxPoller.kt` 按 ID 区间扫描(`ID > W`,不以处理标记为谓词),水位落 `INBOX_CURSOR` 并与入队同事务推进;`JdbcCminmsgInboxRepository.readRange/maxId``ProcStateRepository.insertIfAbsent` 承担发现与幂等入队。空洞老化阈值取 `pipeline.max-commit-delay`。剩余:Q2 未书面确认前,老化阈值与严格顺序仍是假定口径;真实 MySQL 的中断恢复与迟提交联合测试待现场环境。
**当前基础与落点**`ingress/InboxPoller.kt` 按 ID 区间扫描(`ID > W`,不以处理标记为谓词),水位落 `INBOX_CURSOR` 并与入队同事务推进;`JdbcCminmsgInboxRepository.readRange/maxId``ProcStateRepository.insertIfAbsent` 承担发现与幂等入队。空洞老化阈值取 `msgx.pipeline.max-commit-delay`。剩余:Q2 未书面确认前,老化阈值与严格顺序仍是假定口径;真实 MySQL 的中断恢复与迟提交联合测试待现场环境。
**前置**:共享库读契约;Q2 决定严格顺序的端到端验收。水位与扫描谓词口径以 [message-lifecycle.md](message-lifecycle.md) §5.1 为准。
@@ -80,12 +80,12 @@
2. 安全解码 XML,至少覆盖 META、SCHD、FLOP、参考应答与忽略类路由;合法但能力未支持是 `UNSUPPORTED`,不能一律归为非法报文。保留原文以支持诊断和回放。
3. 解码后首次绑定 `SNDR|TYPE|STYP|SEQN`;冲突转 `SKIPPED` 并记录原 ID;自身重试保留绑定。生产 `include-day-boundary=false`,更改算法须另行评审上游序号规则。
4. `MALFORMED` 直接 `DEAD``CODEC_ERROR / UNSUPPORTED / INFRA` 按次数和退避处理,耗尽转 `DEAD(EXHAUSTED)`。不能无限重试未实现类型,也不能立即当非法报文丢弃。
5. HOL deadline 必须基于稳定起始时刻(必要时在 `PROC_STATE` 增加入队时间列),不能用每次重试刷新的 `updatedAt` 代替;调度判断注入 `Clock`。默认 5 次重试、10 分钟滞留限制;积压与人工重放的 deadline 边界按 Q6 验证。
5. HOL deadline 必须基于稳定起始时刻(`PROC_STATE.PROCESSING_STARTED_AT`),不能用每次重试刷新的 `updatedAt` 代替;调度判断注入 `Clock`。默认 5 次重试、10 分钟滞留限制;积压与人工重放的 deadline 边界按 Q6 验证。
6. 主泵在同一 PG 事务提交航班主表/明细、事件与处理结果;终态回填意图通过 US-09 同事务保存。任一步失败整体回滚;提交后只重试外部回填,不重复生成业务事件。
7. 领域决策逻辑只读取当前完整态与已解码报文,返回下一完整态和待发事件,不执行 I/O;Processor 作为事务协调器,将状态写入、事件、处理终态与回填意图收敛在同一事务边界内,不直接触碰 Kafka。失败只在持有消息上下文的边界落账,中断向上传递,不作为普通失败吞掉。
8. 权威存储不可用或未完成恢复时停止业务处理;不能把“整个状态丢失”误判为“单航班不存在”而批量成功结束增量报文。
**当前基础与落点**`processing/Pump.kt`(含 `MessageProcessor`)、`DynamicProcessors.kt``Identity.kt``codec/JacksonXmlCodec.kt``infra/retry/`。严格 FIFO 主泵、SCHDDNLD/RESP/ADFT/FLOP/FDEL 处理器、PG 单事务(含回填待办预登记)、身份绑定与重试已实现;调度取时由可注入 `Clock` 提供,HOL deadline 以 `PROCESSING_STARTED_AT` 为稳定起点。尚未完成:忽略规则分支(US-04),以及逐类矩阵与 golden 样例(US-05)。长期积压和人工重放如何计算 deadline 仍由 Q6 定案。
**当前基础与落点**`processing/Pump.kt`(含 `MessageProcessor`)、`DynamicProcessors.kt``Identity.kt``codec/JacksonXmlCodec.kt``infra/retry/`。严格 FIFO 主泵、SCHDDNLD/RESP/ADFT/FLOP/FDEL 处理器、PG 单事务(含回填意图预登记)、身份绑定与重试已实现;调度取时由可注入 `Clock` 提供,HOL deadline 以 `PROCESSING_STARTED_AT` 为稳定起点。尚未完成:忽略规则分支(US-04),以及逐类矩阵与 golden 样例(US-05)。长期积压和人工重放如何计算 deadline 仍由 Q6 定案。
**前置**:US-01Q1 已定单库方向,Q6 决定 deadline 边界。数据库迁移只落自有库。
@@ -118,7 +118,7 @@
**当前基础与落点**:落点已变为 `processing/DynamicProcessors.kt``FlopProcessor`/`FdelProcessor`/`AdftProcessor`)与 `domain/flight/FlightStateEngine``FlightStateRepository`。FDEL/ADFT 与通用 FLOP 处理器已接入(含 DELETED 幂等与重激活、tombstone 同事务登记);29 类逐类语义矩阵与 golden 样例仍未补全,不能因处理器存在就视为覆盖完成。
**前置**US-03PSDT 另依赖 US-14Q1、Q8。
**前置**US-03PSDT 另依赖 US-14Q1、Q8、Q14
### US-06 导入 RESP/DNLD 日计划快照
@@ -140,7 +140,7 @@
**当前基础与落点**:DNLD 与 RESP 已共同路由到 `processing/ScheduleProcessor.applyScheduleRecords`,整包校验、归属日冲突整包拒绝与单事务写入已实现;`REQ_TRACK` 表与 `ReqTrackRepository` 已建。仍需补 RESP 应答守卫(开放 RQFD 匹配、时间比对)与请求完成关联逻辑。
**前置**US-03、US-08 请求登记/匹配基础;Q1、Q5。
**前置**US-03、US-08 请求登记/匹配基础;Q1、Q5、Q13
### US-07 可靠、有序地投递 Kafka
@@ -176,7 +176,7 @@
**当前基础与落点**`ReqTrackRepository` 与 JDBC 实现、`REQ_TRACK` 表已存在;运行时协调器、`COUTMSGS` 出站适配与请求编码未实现(`XmlCodec.encodeRqrd` 仅占位),超时与应答匹配未闭环。需补协调器、出站适配、并发约束、应答路由与故障测试。
**前置**US-01、US-03;Q5、Q8、出站信箱去重契约。请求基础不依赖 US-06。
**前置**US-01、US-03Q5、Q8、Q14、出站信箱去重契约。请求基础不依赖 US-06。
### US-09 持久化补偿回填信箱
@@ -275,7 +275,7 @@
历史存储确认成功后,才允许删除对应实时航班;逐条隔离坏数据,不能删除写历史失败的集合。判史规则与保留期(`HistoryProps`)、业务时区 `Asia/Shanghai`、历史写入与删除事件之间的恢复协议需在启用前完成 golden 对拍。
阶段 A 不依赖 ES,不启用 `PROJECTION_REBUILD``HistorySweepJob` 已作为每日清理脚手架接入,但历史存储未接通(或 `history-store-enabled=false`)时删除 0 条;脚手架存在不等于清场已交付,红线见 flight-state.md §6。
阶段 A 不依赖 ES,不启用 `PROJECTION_REBUILD``HistorySweepJob` 已作为每日清理脚手架接入,但历史存储未接通(或 `msgx.history.history-store-enabled=false`)时删除 0 条;脚手架存在不等于清场已交付,红线见 flight-state.md §6。
## 5. 运行与切流验收
@@ -305,17 +305,19 @@
| 编号 | 问题与当前口径 | 解除阻塞的产物 |
|---|---|---|
| Q1 权威存储(方向已定) | 当前 PG 单库权威,主表 + 无损明细;现场供库目标为 Oracle 11g。 | 单库决策已采纳,Oracle 完整适配与部署验收仍待交付;不得退回 Redis 双写。 |
| Q2 入队顺序 | 空洞老化阈值取自"最大提交时延",但库方尚未书面承诺 ID 单调与提交时延,因此迟提交不越序仍无端到端保证。 | 库方 ID/提交顺序约束,或明确的发现完整性与暂停/恢复协议;晚提交、空洞、兼容入口与重扫联合测试。不能凭空假定 ID 连续。 |
| Q2 入队顺序 | 空洞老化阈值取自"最大提交时延",但库方尚未书面承诺 ID 单调与提交时延,因此迟提交不越序仍无端到端保证。取值可参照 SIS:报文在 CIIMS 的 `Expiry` 为 480 分钟,断连 120480 分钟按 Level 2 处理,CIIMS 在成功接收或过期前保序保存(SIS §2.4.2.3.3、§3.16、§5.2)。 | 库方 ID/提交顺序约束,或明确的发现完整性与暂停/恢复协议;晚提交、空洞、兼容入口与重扫联合测试。不能凭空假定 ID 连续。 |
| Q3 HTTP 契约 | 目标 ResponseDto 与现有 text/plain ID 不同;请求媒体类型目标已列出,错误码、状态码、查询格式等仍需对拍。 | 每个保留接口的真实请求/响应样例、错误表和契约测试;10MB 的字节口径、字符集及兼容变更说明一起固定。 |
| Q4 Kafka wire | 当前 msg/schd 均按 `FLID` 逐航班发送(schd 由 `flushSchd` 合并为每个 FLID 的最新状态),与 legacy“多 FLID 数组”形态不同;msg 是否需按 `SNDR` 分区尚未接线。 | 下游确认发送粒度、key、去重标识放置、分区内顺序及批次确认策略;未定案前不改动现役消费契约。 |
| Q5 请求匹配 | 目标优先 SEQN 回显,但回显是否可靠需确认;DTTM 降级存在跨代误匹配,尤其旧应答到达新请求期间。 | 15 类请求/响应样例、回显字段与时间格式;降级风险是否接受及拒绝条件。默认超时仍为 RQFD 60 秒、RQRD 30 秒。 |
| Q6 deadline 与重放 | 入队时间作为稳定锚点会把长期排队消息计入滞留;历史重放保留 CREATED_AT 后可能立即过期。 | 明确首次处理/排队过期策略与“本次恢复尝试”计时方式,保留原始时间审计;测试积压恢复和旧 DEAD 重放,不用刷新 UPDATED_AT 绕过超时。 |
| Q6 deadline 与重放 | 入队时间作为稳定锚点会把长期排队消息计入滞留;历史重放保留 CREATED_AT 后可能立即过期。外部参照:SIS 报文 `Expiry` 480 分钟(SIS §3.16),legacy 现役按接收超 1 天归档并删除(legacy 基线 §3.6)。 | 明确首次处理/排队过期策略与“本次恢复尝试”计时方式,保留原始时间审计;测试积压恢复和旧 DEAD 重放,不用刷新 UPDATED_AT 绕过超时。 |
| Q7 信箱外部契约 | 原目标为成功→SUCCESS、忽略→SKIPPED、重复→DUPLICATE、死信→DEAD;当前 JDBC 写 PROCESSED。新 STATUS 值尚不能假定库方支持。 | 库方认可的状态值、META/缺失字段、权限、原文保留期、出站去重与处理时间语义;若只允许 legacy 集合,显式映射内部原因,不新增外部枚举。 |
| Q8 业务覆盖清单 | “29 FLOP、14 RQRD、21 参考类、2 机位类”只是数量,不能直接当字段规范。 | 将 SIS/XSD、现役 KEEP/FIX 基线整理为逐类矩阵与脱敏样例,列明路由、字段、缺失/清空、通知、数据来源优先级、多桥规则及测试文件。资料不全的类型不标完成。 |
| Q9 信箱清除契约 | 清除由谁执行与 DDL 授权、方案 A/B 选型、现场 MySQL 版本与分区 DDL 能力(message-lifecycle.md §6)。 | 库方书面确认清除授权与方案选型。 |
| Q10 出站信箱契约 | `COUTMSGS` 消费方与顺序、`COUTMSGS_ACK_DATE_RECV / COUTMSGS_ACK_RESEND_TIMES / COUTMSGS_DATE_SENT / COUTMSGS_ERROR` 等列语义与写入方、出站清理责任与去重契约(message-lifecycle.md §7legacy 参考见 SIS 规范 COUTMSGS 机制章节)。 | 库方书面确认出站消费、清理与去重契约。 |
| Q11 上游序号重置 | 上游 `SEQN` 重置规则决定业务身份是否加入日期边界(design.md §2.2,默认关闭)。 | 上游确认重置规则;身份算法变更须另行评审。 |
| Q10 出站信箱契约 | `COUTMSGS` 消费方与顺序、`COUTMSGS_ACK_DATE_RECV / COUTMSGS_ACK_RESEND_TIMES / COUTMSGS_DATE_SENT / COUTMSGS_ERROR` 等列语义与写入方、出站清理责任与去重契约(message-lifecycle.md §7SIS §2.4.2.2.2、§2.4.2.2.4、§2.4.2.3)。 | 库方书面确认出站消费、清理与去重契约。 |
| Q11 上游序号重置 | `SEQN` 的取值范围与回绕已由 SIS §2.8.1 定义(`Number(6)`、1–999999、由发送方设置),未知的是重置周期;它决定业务身份是否加入日期边界(design.md §2.2,默认关闭)。`SNDR` 取值域也需对拍:SIS 为 AODB/RMSlegacy 实发 OSH5 等。 | 上游确认重置周期与 `SNDR` 值域;身份算法变更须另行评审。 |
| Q12 积压跳过授权 | 历史积压批次中“不再处理”的确认主体、审批留痕与跳过值集(message-lifecycle.md §5.3)。 | 业务与库方书面确认该批跳过范围;`PROC_STATE=SKIPPED` 记录原因并保留审计,不允许整段 DELETE。 |
| Q13 日计划字段缺失语义 | SIS 要求最新日计划中未发送的可选字段视为 AODB 已无该数据、子系统应删除本地已有值(SIS §3.16 注释 4RESP 同格式见 SIS §3.17),与现行"未携带字段保留"相反(flight-state.md §3.1、message-lifecycle.md §5.3)。 | 与 AODB/库方书面确认字段级删除语义;确认前不得按任一方向验收对拍差异。 |
| Q14 主/共享删除顺序与 EROR | SIS 要求删主航班前先删子共享航班,顺序不符时 RMS 向 AODB 回发 ERORSIS §1.6.1-1.d,事件定义 SIS §4.8)。现行设计为自动原子级联,未定义回报路径(flight-state.md §3.3)。 | 确认上游删除顺序约定,并选定"回发 EROR"或"幂等自动级联";出站事件类型随之纳入 US-08 范围。 |
业务日期/日计划采用 `Asia/Shanghai`;持久化与比较使用明确的时间类型和转换规则,不靠服务器默认时区,也不直接比较不同单位的数字。