docs: 收敛架构设计规范与用户故事实施清单 (ACM2-28)

This commit is contained in:
windyboy
2026-09-07 15:10:57 +08:00
parent bf233f7f69
commit abacd6a3f4
6 changed files with 635 additions and 694 deletions
+223 -169
View File
@@ -1,272 +1,326 @@
# msgexchange-v2 用户故事草案
# msgexchange-v2 用户故事与实施清单
> 依据 `architecture.md`、`design.md`、Plane ACM2-3/5/6/7/12/1522 与 legacy 基线整理。
> 本文描述目标能力和明确保留的兼容行为,不代表当前代码已完成。
## 1. 如何使用本文
## 1. 约定
本文是把现有脚手架补成可用系统的实施入口:**故事定义要交付什么,验收标准定义怎样证明完成,代码落点说明从哪里改起**。保留 US-01US-15、OPS-1OPS-4 编号,便于关联已有任务和测试。
- “信箱已落信”“PG 已入队”“业务处理成功”“共享信箱已回填”“下游已投递”是不同事实
- `KEEP` 表示兼容现役;`FIX` 表示修复 legacy 缺陷`DEFERRED` 表示不属于阶段 A。
- 依赖只表示前置能力,不形成循环;待决策内容不得伪装成验收标准
- 系统边界见 [architecture.md](architecture.md),模块流程见 [design.md](design.md)。本文不重复设计全文,也不以工单状态代替代码验收
- “当前基础”来自本轮代码核对,只表示有接口或部分实现,不表示故事完成。`KEEP` 是保留业务兼容,`FIX` 是明确修正旧缺陷`DEFERRED` 不进入阶段 A。
- “信箱落信、PG 入队、业务处理完成、信箱回填、下游确认”是五个独立事实,接口、日志和测试必须分开表达
- 所有内部迁移只落自有 PG;共享 MySQL 不建表、不增列、不写历史表。本文用 `DATE_PROCESSED / STATUS` 表示逻辑字段,实际列名以库方契约为准。
- 验收条目可按 `US-xx/条目号` 引用。故事较大时按下文子范围拆成小 PR,不把一个故事等同于一个提交。
## 2. 阶段 A 用户故事
**存储基线提醒**[FLIGHT_STATE 决策提案](decision-flight-state.md) 尚未定案。本文仍按阶段 A Redis 权威描述;涉及权威状态、快照和事务顺序的最终实现,先处理 Q1,不能一边实现 Redis 协议一边擅自迁为 PG 权威。
### US-01 可靠采集共享信箱报文
## 2. 建议实施顺序
**作为** 平台运维人员,**我希望** 持续采集 `CMINMSGS` 未处理报文,**以便** 上游无需改变投递方式
先补可靠性边界,再打通一条真实业务链,最后扩充报文类型。每批均可先用假适配器测试,但真实链路验收不能省略
| 批次 | 实施范围 | 本批交付证明 |
|---|---|---|
| S0:契约与基础 | 确认 Q1;整理报文/参考数据清单;补 Clock、PG 事务入口、迁移及 OPS-1 基础门禁 | 数据源归属明确;迁移可用;关键 Bean 装配测试;未就绪生产配置拒启。其他 Q 项只阻塞对应功能,不阻塞无关单测。 |
| S1:可靠收报与处理 | US-01、US-03 调度/解码/提交子范围、US-09、US-04 | 未处理信箱 → PG 入队 → 忽略终态 → 持久补偿回填;重试不越队,注入中断可恢复。 |
| S2:最小业务闭环 | US-05 的 ADFT 与一个不依赖参考数据的 FLOPUS-07 | 在 Q1/Q4 定案后,用真实存储和 Kafka 验证“建航班 → 更新 → 事件投递”,包括提交和确认丢失窗口。不是全部业务完成。 |
| S3:请求与全量计划 | US-08 的登记/出站/匹配基础 → US-06;补齐 US-08 的参考应答 | DNLD、匹配 RESP、迟到 RESP 和快照崩溃恢复通过;15 类请求逐项验收。 |
| S4:业务覆盖与接口 | US-13、US-14 → US-05 其余类型;US-02、US-12 | 增量类型、参考数据、机位映射和兼容 HTTP 均有契约样例与回归测试。接口可在前期单独开发。 |
| S5:运维恢复 | US-10、US-11,完成 OPS-1OPS-3 | 安全重放、归档后去重、故障告警、单写者保护、影子禁写均有验证证据。 |
| S6:上线验证 | OPS-4,复核所有进入切流范围的故事 | 对拍、故障演练、配置和恢复 Runbook 验收后切流;US-15 不作为门槛。 |
**依赖口径**:US-03 是基础管道,不依赖具体业务 Handler;US-09 依赖其终态提交接口,US-04 复用 US-09。US-08 的请求登记与匹配基础不依赖 US-06;US-06 消费该基础,二者共同完成 RESP 集成验收,不形成开发依赖环。US-05 只有 PSDT 子范围依赖 US-14,不应阻塞其余 Handler。
## 3. 阶段 A 用户故事
### US-01 可靠采集共享信箱
**目标**:上游继续向 `CMINMSGS` 落信,本系统持续、可恢复地采集,不要求上游改投递方式。
**验收标准**
1. 按配置周期、ID 升序有限批次采集 `DATE_PROCESSED IS NULL`;这里只采集入队,不代表业务已处理。
2. 快路径使用持久化高水位增量扫描;另以受控周期补偿重扫“未处理且 PG 无状态”的记录。水位只在本批入队确认后推进
3. 每个 ID 在 PG 至多一个 `PROC_STATE(PENDING)`;重复发现不重复入队
4. PG 不可用时不改共享信箱标记;恢复后补偿重扫能补建遗漏状态
5. 单条异常和数据库故障可观察,轮询线程不得静默退出
1. 按配置周期、ID 升序有限批次采集未处理记录;接收层只入队,不解析业务、不回填已处理标记
2. 按信箱 ID 幂等建立 PG `PENDING`;重复扫描、并发兼容入队和进程重启都不能重置已有终态
3. 快路径用持久水位,补偿路径受控重扫遗漏;本批 PG 入队全部确认后才推进水位。补偿可分页推进,不能被已入队但尚未回填的前一批永久挡住
4. PG 不可用或批次中途失败时不改信箱标记;恢复后补建遗漏,记录失败次数与扫描进度
5. 较小 ID 迟提交、ID 有空洞、兼容入口先入队较大 ID 时,必须遵守经 Q2 确认的发现与顺序协议;不能用“最终会重扫”冒充严格 FIFO
**依赖**:共享库读权限、字段与索引契约。
**实现差距**:当前 `InboxPoller` 固定 `afterId=0` 全量扫描,无持久化水位和独立补偿频控。
**当前基础与落点**`ingress/InboxPoller.kt``InboxEnqueue.kt``infra/persistence/jdbc/JdbcCminmsgInboxRepository.kt` 已有轮询和判重;固定 `afterId=0`,水位与补偿未实现。扩展 `InboxPollerTest`,补真实 PG/MySQL 中断恢复测试。
### US-02 通过兼容接口注入报文
**前置**:共享库读契约;Q2 决定严格顺序的端到端验收。
**作为** 联调人员,**我希望** 通过 `POST /cminmsgs/send` 注入 XML,**以便** 执行回放和对拍。
### US-02 兼容 HTTP 注入报文(KEEP
**目标**:联调工具通过 `POST /cminmsgs/send` 提交 XML,得到真实的信箱接收结果。
**验收标准**
1. 信箱落信后返回 `CMINMSGS_ID`,响应不得暗示 PG 已入队或业务已处理
2. 落信成功但 PG 入队失败时,由 US-01 最终补建
3. Content-Type 支持 `text/xml``application/xml``text/plain`(默认按 UTF-8 解码);空报文、超大报文(> 10MB)及畸形 XML 返回规范错误
4. 响应结构逐字兼容 legacy `ResponseDto`:成功返回 `{"is_success": true, "body": <CMINMSGS_ID>}`,失败返回 `{"is_success": false, "err_code": "<code>", "err_msg": "<detail>"}`
5. 生产默认沿用现役内网互信免密姿态(网关限定内部 IP 网段与审计);外露或跨网络时启用 Header 认证。
1. 支持 `text/xml``application/xml``text/plain`,默认 UTF-8;空报文、超过 10MB 的请求和畸形 XML 返回规范错误,不落信。XML 校验禁用 DTD、外部实体与外部资源访问
2. 信箱确认落信后返回 ID;PG 入队失败不把已落信伪装成未接收,由 US-01 补建。信箱写入未确认时不返回成功
3. 目标为兼容 `ResponseDto`;固定成功/失败样例、HTTP 状态码、响应媒体类型和错误码表后加入契约测试,见 Q3。成功只承诺信箱落信,不承诺业务处理或下游完成
4. 生产保持内网信任边界,由网关限制来源并审计;外露或跨网络必须先落实认证,不能把免密入口直接暴露
**依赖**US-01。
**目标响应体示例**(数字和错误码仅作示例,错误码表见 Q3):
### US-03 严格按序且幂等地执行处理管道
```json
{"is_success": true, "body": 12345}
{"is_success": false, "err_code": "<code>", "err_msg": "<detail>"}
```
**作为** 航班数据消费者,**我希望** 报文严格按信箱顺序处理,**以便** 重试不会造成倒序状态
**当前基础与落点**`ingress/InboxController.kt` 当前返回 200 + 纯文本 ID,尚非目标 DTO;`InboxService.kt` 在落信后直接调用入队,需处理 PG 失败。新增 HTTP 媒体类型、大小限制及跨库失败测试
**前置**US-01 补建能力;Q3。HTTP 基础格式校验不替代 US-03 的业务解码。
### US-03 严格按序、幂等地执行管道
**目标**:报文失败和重试不造成航班状态倒序,也不重复产生副作用。
**实施拆分**:调度与时钟 → 安全解码及路由 → 身份绑定 → 状态应用与 PG 提交。先用假 Handler 验证管道,不等 US-05 全部实现。
**验收标准**
1. 选择最小未完成 ID`PENDING``FAILED` 占队头退避期间后续消息不得越过
2. identity 首绑为 `SNDR|TYPE|STYP|SEQN`;冲突转 `SKIPPED` 并记录原 ID
3. `MALFORMED` 直接 DEAD`CODEC_ERROR/UNSUPPORTED/INFRA` 退避;attempts 或 HOL deadline 耗尽后转 `DEAD(EXHAUSTED)`
4. PUMP_JOB 不与消息形成统一全序,只在无队头或队头尚在退避窗口时执行;不得让已到期消息饥饿
5. Redis 先应用;`MSG_EVENT``PROC_STATE→SUCCEEDED` 在同一 PG 事务提交
6. Redis 已写、PG 未提交的窗口可幂等重放
1. 只取最小未完成 ID`PENDING / FAILED` 占队头退避未到期不得越过。作业仅在无队头或退避窗口执行,已到期消息优先,作业有界且不会造成无限饥饿
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.CREATED_AT`,不使用每次重试刷新的 `updatedAt`;所有调度判断注入 `Clock`。默认 5 次重试、10 分钟滞留限制;积压与人工重放的 deadline 边界按 Q6 验证
6. 当前 Redis 基线下,由主泵先幂等应用状态,再在同一 PG 事务提交事件与处理结果;终态回填意图通过 US-09 同事务保存。Redis 已成功而 PG 失败可安全重试,不能重复生成业务事件
7. Handler 只返回 `Decision`,副作用由管道执行;失败只在持有消息上下文的边界落账,中断向上传递,不作为普通失败吞掉。
8. 权威存储不可用或未完成恢复时停止业务处理;不能把“整个状态丢失”误判为“单航班不存在”而批量成功结束增量报文。
**依赖**US-01。
**既有基线定案**:生产幂等键默认采用 `SNDR|TYPE|STYP|SEQN``include-day-boundary=false` 禁开,防止跨日重放漏判;HOL deadline 起算时间统一固化为 `PROC_STATE.CREATED_AT`(稳定入队时间戳),消除重试刷新 `updatedAt` 导致的超时不可达缺陷。
**当前基础与落点**`processing/Pump.kt`(含 `MessageProcessor`)、`Identity.kt``codec/XmlCodec.kt``infra/retry/``JdbcPgRepositories.kt`。已有身份/重试边界测试,但 codec 为接口,主泵直取系统时间,普通 Redis 更新占位,PG 操作未共享事务;补 `CREATED_AT` 迁移及主泵级回归测试。
### US-04 忽略非业务报文(KEEP
**前置**:US-01;Q1 决定状态提交实现,Q6 决定 deadline 边界。现有 `FlightStateRepository` 空实现不是建表授权。
**作为** 运维人员,**我希望** 已确认无需处理的报文被明确忽略,**以便** 不产生 DLQ 噪声。
### US-04 明确忽略非业务报文(KEEP)
**目标**:无需处理的报文有可追踪的终结结果,不制造无效重试与死信。
**验收标准**
1. 解码 META 后、 Handler 前,大小写不敏感匹配 `TYPE-STYP` `TYPE-*`
2. 基线为 `LDM-*``REGN-*``RSTA-*``EROR-*`;统一采用 `EROR`,消除 test 的 `ERROR` 漂移
3. 命中后进入 `SKIPPED`,记录 `ignored:<rule>`,不创建业务事件
4. 按 US-09 的规则回填共享信箱,并保留审计计数。
1. 解码 META 后、身份绑定及业务 Handler 查找前,大小写不敏感匹配 `TYPE-STYP` `TYPE-*`;基线为 `LDM-* / REGN-* / RSTA-* / EROR-*`,不混用 `ERROR`
2. 命中后转 `SKIPPED`,记录 `ignored:<rule>` 和计数;不更新航班、不创建业务通知
3. 通过 US-09 保存回填意图;命中、未命中、大小写和重扫均有测试。合法忽略报文不应因 `MsgKind` 尚不能表达它而先解码失败
**依赖**US-03、US-09
**当前基础与落点**`MessageProcessor` 尚无忽略分支,`DecodedMessage/MsgKind` 主要覆盖 SCHD/FLOP;扩展解码与路由,不把忽略逻辑散落到 Handler
### US-05 应用 ADFT 与 29 类 FLOP 报文
**前置**US-03 解码/终态接口、US-09。
**作为** OMMS 业务,**我希望** 正确应用增量报文,**以便** Redis 动态符合 wire 契约。
### US-05 应用 ADFT 与 29 类 FLOPKEEP + FIX
**目标**:增量报文正确更新航班及主/共享关系,并生成符合现役语义的通知。
**验收标准**
1. `SCHD-ADFT` 29 个 FLOP 子类型有纯函数 Handler;未知类型进入 `FAILED(UNSUPPORTED)`
2. 每类覆盖输入、Redis 变化、msg、schd、处理终态五面断言
3. 航班不存在按 legacy KEEP 语义结束且不重试:`SUCCEEDED` 终态结束, US-09 回填共享信箱 `DATE_PROCESSED = now()`, `STATUS = 'SUCCESS'`,防止死循环
4. 共享航班默认不直接发通知,而是更新并通知主航班;FDEL 例外定案:删除共享航班时更新主航班 MAFL 列表并发出主航班通知;删除主航班删除其及所有子共享关联并发删除通知;目标航班不存在幂等成功退出
5. ADFT/FDEL 使用值相等比较主/共享关系作为一次原子 Redis 变更持久化(FIX
6. PSDT 依赖 US-14Handler 不直接调用 admin-api。
1. `SCHD-ADFT` 29 个 FLOP 子类型逐项列入覆盖矩阵,每项有纯函数 Handler;未知类型可恢复失败。RESP/DNLD 不计入这批 Handler,走 US-06
2. 每类固定“输入与前态 → 后态 → msg → schd终态五面样例;区分字段缺失、显式清空、重复报文和主/共享航班。清单和 golden 样例按 Q8 补齐,不以“已写 29 个类”替代验收
3. 对按 KEEP 规则需忽略的不存在航班,`SUCCEEDED` 无副作用结束,并由 US-09 回填;ADFT 建航班等行为按各类型矩阵执行。此规则只适用于权威状态健康时
4. 共享航班通常更新并通知主航班,不直接发共享通知。FDEL 删除共享航班时更新主航班 MAFL 通知;删除主航班删除主航班及其子共享关联并发删除通知;目标不存在幂等成功。
5. ADFT/FDEL 使用值相等比较主/共享关系一次原子变更,不出现主已删、子残留等半状态
6. PSDT 通过 US-14 的只读映射计算 `abdg`Handler 不直接调用 admin-api。
**依赖**US-03、US-14、SIS/XSD 与 KEEP/FIX 矩阵。
**当前基础与落点**`processing/Handler.kt``domain/Decision.kt``infra/redis/` 只有主要扩展点;按类型新增 Handler 与同包测试。先做 ADFT + 一个普通 FLOP,再做主/共享及 PSDT,最后补齐矩阵。
**前置**US-03PSDT 另依赖 US-14Q1、Q8。
### US-06 导入 RESP/DNLD 日计划快照
**作为** 航班计划使用方,**我希望** RESP 与 DNLD 共用快照流程,**以便** 主动下和请求应答获得相同终态。
**目标**主动下和请求应答使用同一套全量计划处理,迟到应答不覆盖新状态。
| 报文 | SnapshotFlow | REQ_TRACK | Kafka msg | 迟到/无匹配处理 |
|---|---|---|---|---|
| `SCHD-DNLD` | 是 | 不更新 | 成功后通知 | 不适用(广播/全量) |
| `SCHD-RESP` | 是 | 匹配开放 RQFD DONE | 成功后通知 | 严禁更快照,转 SKIPPED 并审计 |
| `SCHD-ADFT` | 否,走 US-05 | 不更新 | 按增量规则 | 增量应用 |
| 报文 | 路由 | 请求状态 | 无匹配 |
|---|---|---|---|
| `SCHD-DNLD` | SnapshotFlow | 不更新请求 | 不要求开放请求 |
| `SCHD-RESP` | 匹配守卫后进入 SnapshotFlow | 成功提交时匹配 RQFD DONE | SKIPPED、审计,禁止更新快照 |
| `SCHD-ADFT` | US-05 增量 Handler | 不更新请求 | 不适用 |
**验收标准**
1. RESP/DNLD 共用 staging 流式整包校验和 SnapshotFlow,不作为普通 FLOP 增量 Handler 重复实现
2. 主泵执行先后严格服从 I2(happens-before):主泵线程先执行 Redis Lua 完成写新代、旧代差集删除及 generation 版本 CASADFT 航班存活,FIX);Redis 执行成功后进入自有 PG 本地事务
3. 自有 PG 本地事务原子性:同一 PG 事务内原子提交 `PROC_STATE → SUCCEEDED`、匹配开放请求的 `REQ_TRACK → DONE`(记录 completed_at 与 resp_cminmsgs_id)及 `MSG_EVENT` 出站通知
4. 整包失败保留旧快照;相同报文重放(CAS 版本一致)幂等,不重复增代或差删
5. 迟到(`dttm < req.sentAt`)或无匹配/过期(`EXPIRED`RESP **严禁更新快照**,转入 `PROC_STATE → SKIPPED` 并记录审计与告警,防止历史快照时光倒流覆盖新状态(对齐 G12)
6. 覆盖首次/连续发布、DNLD→ADFT→DNLD′、RESP 匹配和崩溃窗口。
1. RESP/DNLD 共用流式解析、整包校验和规范化;校验失败不发布半包,旧快照保持可用
2. RESP 仅匹配未过期、已发送的开放 RQFD;`DTTM < SENT_AT`、已过期、已被替代或无匹配时,不写业务状态,记录跳过原因
3. 当前 Redis 基线下,Lua 原子执行新代写入、旧代差集删除和版本校验/推进;删除集只来自上一代成员,不误删集合外的 ADFT 航班
4. 随后在一个 PG 事务提交 `SUCCEEDED`、待发通知、回填意图;匹配 RESP 同事务完成请求,并保存完成时间与应答信箱 ID
5. 相同报文重放不二次增代或删数据;覆盖首次/连续快照、DNLD→ADFT→DNLD′、旧应答与 Redis 成功/PG 失败窗口。不能只靠“读取当前版本再加一”实现重放识别
**依赖**US-03、US-08、Redis gen 协议
**当前基础与落点**`processing/SnapshotFlow.kt` 的 staging 为占位,主处理只分流 DNLD,gen 走进程内过渡仓储。需补 RESP 路由、版本协议及 `REQ_TRACK` 应答关联字段和事务测试
**前置**US-03、US-08 请求登记/匹配基础;Q1、Q5。
### US-07 可靠、有序地投递 Kafka
**作为** Kafka 消费者,**我希望** 状态可见后有序投递,**以便** 通知不指向旧状态
**目标**:状态应用完成后投递通知;重试可识别、不乱序、不静默丢失
**验收标准**
1. `KAFKA:msg` EVENT_ID FIFO,确认后才标 SENT。
2. `KAFKA:schd` 按周期和上限领取;同一 FLID 仅发批内最新事件
3. 失败保持队头并退避;耗尽后 DEAD,不静默丢弃
4. 事件包含稳定去重标识,分区键和重复投递有契约测试:`KAFKA:msg``SNDR` 作为分区键;`KAFKA:schd` 严格以 `FLID` 为分区键,确保单航班有序
5. 生产环境对接 Kafka 2.8+ / 3.x+,生产者强制 `acks=all``enable.idempotence=true``max.in.flight.requests.per.connection=1`,严禁非幂等降级;投递失败退避重试,达上限转 `DEAD(DLQ)` 告警,绝不静默丢弃
1. `KAFKA:msg`目标内 `EVENT_ID` 顺序发送,确认后才标 `SENT`;队头退避时不跳过,发送有超时上限
2. `KAFKA:schd` 只通过 `flushSchd` 聚合,默认 3 秒/500 条;同一 FLID 批内最新状态,成功确认覆盖对应原事件,失败保持批次可恢复并退避,耗尽可见为 `DEAD`
3. 外部接收成功、本地确认失败或进程重启后允许重发;事件标识跨重发稳定,消费者有去重约定,不宣称端到端恰好一次
4. msg 的目标分区键为 `SNDR`。schd 的聚合粒度与分区键先按 Q4 定案,明确哪些顺序只在单分区成立;不能把多航班数组声称为“每个 FLID 都是该 Kafka record 的 key”
5. 生产强制 `acks=all``enable.idempotence=true``max.in.flight.requests.per.connection=1`;Broker 支持幂等生产协议并完成实际验证,不允许非幂等降级通过验收
6. 普通/聚合发送失败、确认丢失、批次标记中断和目标阻塞均有测试;DEAD 保留记录并告警。
**依赖**US-03、现网 Kafka Broker API 版本确认(切流前 `kafka-broker-api-versions.sh` 探测 `InitProducerId(22)`;未确认前不得标 US-07 实施完成)
**当前基础与落点**`delivery/Dispatcher.kt``SchdAggregation.kt` 已有聚合和重试测试;`DeliveryPort.sendKafka` 仅接 topic/payload,无 key 或事件标识参数,真实生产适配与强制配置校验需补齐
**前置**:US-03 事件提交;Q4、现网 Broker 验证。wire 不兼容的标识字段不能直接加到现役载荷。
### US-08 发起并跟踪 15 类 AODB 请求
**作为** 业务或运维人员,**我希望** 发起请求并跟踪生命周期,**以便** 区分登记、落信、等待、完成超时。
**目标**:区分请求登记、出站落信、等待、完成超时,不把过期应答应用到新请求
**实施拆分**:请求登记/出站补偿 → 匹配/超时 → 14 类参考应答;RQFD 快照效果由 US-06 集成验收。
**验收标准**
1. 支持 14 类 RQRD 参考请求和 1 类 RQFD-NONE 日计划请求
2. REQ_TRACK 先登记COUTMSGS 落信后关联 ID 并标 SENT,落信不等于对方已发送
3. 逐类超时与并发规则定案:同类请求并发严格为 1(新请求注册时强制同类未决请求 `EXPIRED`);`RQFD-NONE` 超时为 60s14 类 `RQRD` 超时默认为 30s
4. 响应经 US-01/US-03 入站:优先以报文回显 `SEQN``echoSeqn`)精确匹配开放请求;无回显降级为时序判定(仅接受 `DTTM >= SENT_AT` 的开放请求),并在完成时同 PG 事务标 `DONE`
5. 超时或被替代的请求 EXPIRED;迟到响应(`DTTM < SENT_AT`)或无匹配响应严禁更新业务状态/快照,转 SKIPPED 并审计。
6. **集成验收**SCHD-RESP 遵循 US-0614 类响应刷新 REF_MASTER,不与 admin-api 21 类混同
1. 覆盖 14 类 RQRD 参考请求和 1 类 RQFD-NONE;逐类名称、编码和映射见 Q8,不与 admin-api 的 21 类混算
2. 先持久化 `REGISTERED` 与出站意图COUTMSGS 确认落信后关联 ID 并标 `SENT`,不宣称对方已发送。落信成功而 PG 未确认时可恢复,不能盲目重发
3. 同类开放请求最多一个,新请求使旧请求 `EXPIRED`,并发登记不产生两个开放请求。默认 RQFD 60 秒、RQRD 30 秒,从确认落信的发送时间起算;`SENT/WAITING` 均不得成为永不超时的死分支
4. 优先按已确认的 SEQN 回显匹配;无回显降级匹配按 Q5 明确风险,只接受已发送开放请求且 `DTTM SENT_AT`。统一转换为可比较的时间,不能把报文日期数字直接与 epoch 毫秒比较
5. 迟到、无匹配或已关闭请求的应答不得更新数据,转 `SKIPPED` 并审计。参考应答成功写入 REF_MASTER 后,与请求完成、处理终态和事件在 PG 边界内保持所需原子性。
6. `POST /schd/sync` 复用请求入口,采用 24 小时制和非空/区间校验;响应明确已登记还是已落信,不承诺计划已更新
**依赖**US-01、US-03、COUTMSGS 适配器及逐类超时参数
**当前基础与落点**`reference/RequestCoordinator.kt``ReqTrackRepository` 和 JDBC 表已存在;当前真实出站未实现就标发送,回显匹配和超时未闭环。需补 COUTMSGS 适配器、编码、并发约束、应答路由与故障测试
### US-09 补偿回填共享信箱
**前置**US-01、US-03;Q5、Q8、出站信箱去重契约。请求基础不依赖 US-06。
**作为** 上游和运维人员,**我希望** PG 终态最终反映到共享信箱,**以便** 未处理积压语义准确。
### US-09 持久化补偿回填信箱
**目标**:本地处理终态最终反映到共享信箱,不因共享库故障回滚已完成业务。
**验收标准**
1. **解耦与异步执行**:主泵 PG 事务(更新 `PROC_STATE` 终态 + 插入 `MSG_EVENT`)内写入持久化回填意图;PG 事务提交后异步触发共享信箱回填,严禁内联同步阻塞等待共享库;回填失败绝不回滚 PG 终态
2. **持久化补偿**:未完成或失败的回填由后台补偿任务按指数退避重试;暴露待回填积压量与最老年龄指标,持续失败触发告警。回填 SQL 具备幂等性(`UPDATE CMINMSGS SET DATE_PROCESSED = :now, STATUS = :status ... WHERE CMINMSGS_ID = :id`
3. **各终态回填规则矩阵**(单值锁定;库方/legacy 实测前为占位,见 §7-9):
- `SUCCEEDED`**必须回填**`DATE_PROCESSED = now()`, `STATUS = 'SUCCESS'`,补齐 META 子系统列)
- `ignore SKIPPED`(规则忽略):**必须回填**`DATE_PROCESSED = now()`, `STATUS = 'SKIPPED'`),防止上游视作未处理积压持续重扫
- `duplicate SKIPPED`(身份键重复):**必须回填**`DATE_PROCESSED = now()`, `STATUS = 'DUPLICATE'`),确认去重终结。
- `DEAD`(毒丸/耗尽/MALFORMED):**必须回填**`DATE_PROCESSED = now()`, `STATUS = 'DEAD'`),避免共享信箱长期未处理告警或双跑旧系统死循环。运维人工重放基于自有 PG 驱动,不依赖信箱重置。
- 非终态(`PENDING``FAILED`):**绝对禁止回填**,保持 `DATE_PROCESSED IS NULL`
4. **影子与双跑隔离**:影子实例绝对禁止回填共享信箱;与 legacy 双跑时严格保持单系统持有标记写权。
5. 查询和日志分别展示 PG 终态与信箱回填状态。
1. PG 终态与回填意图同事务保存;所有终态路径都经过统一提交边界,不只覆盖成功路径。事务回滚时不得留下可执行回填意图
2. 提交后由后台执行回填,主泵不等待共享库;失败按持久记录退避,重启继续执行,不重新执行已完成业务
3. SUCCEEDED、规则忽略、身份重复、DEAD 均需回填处理时间;PENDING/FAILED 禁止回填。具体 STATUS 编码按 Q7 确认,内部终态不能直接当作外部字段值。
4. 重复补偿效果幂等,保留稳定的完成时间与审计;重放后的新处理结果不能被旧回填任务覆盖。非法报文缺 META 时也有明确回填方式
5. 影子模式禁写,双跑仅一个系统持有标记写权;暴露 PG 终态、回填状态、积压、最老年龄与持续失败告警
**依赖**:US-03、共享库更新权限、共享库 STATUS 值域确认(库方/legacy 对拍)
**当前基础与落点**`backfillOnSuccess` 当前仅同步写 `PROCESSED`,无持久意图。补自有 PG 意图模型/迁移、事务提交入口和独立补偿执行器;不在共享库新增补偿表
### US-10 运维重放与故障处置
**前置**:US-03 终态接口;Q7、共享库更新权限。测试覆盖四类终态、事务回滚、重复补偿和重放竞争。
**作为** 运维人员,**我希望** 查询并安全重放失败项,**以便** 修复故障而不破坏顺序。
### US-10 安全重放与故障处置
**目标**:运维能定位失败、限定恢复范围,并了解重放对当前航班状态的影响。
**验收标准**
1. 可按记录、错误类时间查询 attempts、错误及 traceId
2.`CODEC_ERROR/UNSUPPORTED/INFRA/EXHAUSTED` 可重放;请求含 MALFORMED 时静默跳过该记录,并返回逐项结果
3.放清零 attempts/nextAttemptAt,保留错误审计,仍服从 FIFO
4. DEAD、持续回填失败、队列年龄越界产生告警;操作记录操作者、原因、范围和结果
1. 按 ID、错误类时间查询次数、错误、关联事件与回填状态;重放前预览范围,记录操作者、原因和逐项结果
2.`CODEC_ERROR / UNSUPPORTED / INFRA / EXHAUSTED` 的 FAILED/DEAD 允许申请重放;MALFORMED 与其他不允许项不改状态,返回跳过原因
3. attempts/nextAttemptAt,保留身份、原始入队时间和错误审计;采用 Q6 确认的重放 deadline 策略。重新入队仍按 ID 处理,但不承诺已执行过的后续消息自动撤销
4. DEAD 之后可能已有新状态,必须预检版本与覆盖风险;不安全时拒绝直接重放,改用经批准的隔离重建或恢复流程,禁止无保护的全量 `replayAll` 生产入口
5. 操作有认证、授权、范围限制与审计;死信、持续补偿失败、队列年龄越界有告警和处理 Runbook。
**依赖**US-03、鉴权与审计
**当前基础与落点**`infra/retry/ReplayService.kt` 仅按错误类批量重排并返回数量;需补按记录选择、预检、操作审计和管理入口,扩展 `ReplayServiceTest`
### US-11 归档终态入站报文
**前置**US-03、US-09 的恢复状态;Q6、OPS-1/OPS-2 的安全与可观测基础。
**作为** 平台运维人员,**我希望** 定期归档终态报文,**以便** 控制信箱规模且不丢未完成工作。
### US-11 归档自有库终态记录
**目标**:控制自有 PG 在线表规模,不丢未完成工作、不破坏去重与恢复;不是清理共享信箱。
**验收标准**
1. 默认处理接收时间早于 **1 天**的 `SUCCEEDED/SKIPPED/DEAD`保留期可配置 17 天;不迁 PENDING/FAILED。
2. **共享库零建表与 DML 最小化定案**:严禁向共享 MySQL 写入 `CMINMSGS_HST`,共享库严格限定为信箱两表(CMINMSGS 读/回填,COUTMSGS 写入);共享 MySQL 自身历史清理交由库方自身 DBA 策略
3. **归档迁入自有 PG**:在自有 PostgreSQL 设计 `PROC_STATE_HST`(及 `MSG_EVENT_HST`)承载历史归档数据
4. 重复执行幂等并记录计数;迁移失败时 fail-closed,不删除源记录
1. 默认归档接收时间早于 1 天SUCCEEDED/SKIPPED/DEAD保留期可配置 17 天;PENDING/FAILED 禁止归档。明确接收时间字段来源,不混用 UPDATED_AT 或本地入队时间
2. 归档到自有 PG `PROC_STATE_HST`;关联 `MSG_EVENT` 的历史目标和保留规则一并设计。仍有未完成投递、回填或恢复依赖时,不移除所需记录
3. 迁移与删除在自有库事务内完成,重复执行幂等;失败保留源记录并报告计数。归档后同信箱 ID/业务身份再次到达,仍能按约定去重
4. 不写共享 MySQL `CMINMSGS_HST`,不清理外部信箱;原文可用性与重放保留期由 Q7/Q8 关联确认
**阶段**A
**当前基础与落点**`jobs/JobExecutor.kt``PumpJobRepository` 为入口;当前迁移无归档表。先确定去重记录保留与关联策略,再补迁移及归档中断测试
### US-12 查询实时航班
**前置**US-03、US-09US-07 提供事件终态规则,US-10 提供恢复保留要求。不依赖 US-15。
**作为** 授权调用方,**我希望** 查询实时航班,**以便** 获得与 Redis 权威态一致的数据。
### US-12 查询实时航班(KEEP
**目标**:调用方读取与当前权威状态一致的实时航班视图。
**验收标准**
1. KEEP `GET /all/flights`:返回 Redis 当前航班并过滤 `MAID != NULL` 的共享航班。
2. 固定响应、空结果、排序、分页/大小上限和一致性时点
3. 影子只查询影子 key;接口具备认证、限流审计。
1. 保留 `GET /all/flights`过滤 `MAID != NULL` 的共享航班;不改写业务状态
2. 固定响应样例、空结果、排序、大小限制及一致性时点。现役未分页时不能无声改为只返回第一页;分页或响应结构变更按 Q3 决定
3. 依赖异常不能伪装为空数组成功;影子只读影子状态,入口有约定的访问控制、限流审计。
**当前基础与落点**`InboxController.kt` 中仅有该接口 TODO;新增查询控制器与只读服务,复用权威读取端口,不能从空占位仓储返回成功。新增接口/状态不可用测试。
**前置**Q1、Q3;所查询的 US-05/US-06 状态发布能力。
### US-13 刷新 21 类参考主数据
**作为** 业务组件,**我希望** 从 admin-api 刷新 21 类数据到 REF_MASTER,**以便** 使用可审计的本地主数据
**目标**业务使用来自 admin-api 的本地参考数据,刷新失败仍有上次可用版本
**验收标准**
1. 采用 ACM2-5 清单;admin-api 拉取与 US-08 的 AODB 请求是两个入口
2. `(RTYPE,RKEY)` 幂等 upsert,记录 SOURCE、刷新时间和批次审计
3. 类失败不发布半批,不破坏上个可用版本;影子默认不主动刷新生产数据
1. 按 Q8 的 21 类清单配置端点、RTYPE/RKEY、字段映射;这是独立于 US-08 的数据入口,不另建“参考专用第二 PG”
2. `(RTYPE,RKEY)` 幂等写 REF_MASTER,记录 SOURCE、刷新时间和批次;单类完整校验后发布,失败不暴露半批
3. 类失败不破坏其他类或该类旧版本;同类由 AODB/admin-api 都提供时明确覆盖优先级,全量刷新时明确已删除项的处理,不能仅靠 SOURCE 日志解决冲突
4. 影子默认不主动刷新生产数据;需要参考样本时显式导入隔离副本。
### US-14 提供机位与登机桥数据
**当前基础与落点**`reference/ReferenceService.kt` 是空刷新入口,`JdbcStaticRefRepository` 有逐条 upsert;补客户端、类型清单、批次发布/事务和失败保旧测试。
**作为** PSDT 处理逻辑,**我希望** 获得机位和登机桥映射,**以便** 正确计算 `abdg`
**前置**admin-api 访问契约、Q8。可独立于消息 Handler 开发
### US-14 提供机位与登机桥映射
**目标**:PSDT 在不调用外部 HTTP 的情况下得到完整映射,正确计算 `abdg`
**验收标准**
1. 保留 ORMS_STAND ORMS_STAND_AIRBRIDGE,和新增 21 类分开统计
2. 通过适配器拉取并缓存;Handler 不直接 HTTP
3. 近机位生成登机桥,远机位或清空时 `abdg` 为空;多桥规则由 golden 固定
4. admin-api 不可用时使用最后可用版本或明确失败,不写不完整缓存。
1. 保留 `ORMS_STAND / ORMS_STAND_AIRBRIDGE` 两类,与 US-13 的 21 类分开统计;适配器拉取、完整校验后原子发布只读缓存
2. 近机位产生登机桥值,远机位或清空机位时 `abdg` 为空;一机位多桥、缺失映射与共享航班规则用 golden 固定
3. admin-api 不可用时使用最后可用版本;无可用版本或映射不完整时明确失败,不用空映射冒充正常清空,也不发布半批
4. Handler 输入包含所需只读参考视图,不允许其直接 HTTP 或写缓存。
## 3. 延后故事
**当前基础与落点**:在 `reference/``infra/` 增加映射服务/适配器,必要时扩展 Handler 输入上下文;PSDT 测试使用固定映射,无需在线 admin-api。
### US-15 历史航班清场(DEFERRED
**前置**:机位/桥数据契约及 Q8;不要求 US-13 全部完成。
**作为** 平台运维人员,**我希望** 历史写成功后移出实时态,**以便** 控制 Redis 规模且不丢历史。
## 4. 暂缓范围
1. 全系统统一固定基准时区为 `Asia/Shanghai`CST, UTC+8)。
2. 阶段归属与 ES 边界定案:`HISTORY_SWEEP` 延后为阶段 B 能力(DEFERRED),阶段 A 永续以 Redis 作为航班动态权威,完全不接入 ES;不作为阶段 A 切流门禁。
3. 五条判史规则与 ES 写入留在阶段 B 启用前完成 100% golden 对拍;逐条隔离坏数据;仅历史写成功的 FLID 可由主泵删除。
4. 与快照保持单写者串行并记录计数。
### US-15 历史航班清场(DEFERRED,阶段 B)
## 4. 上线 Epic
历史存储确认成功后,才允许主泵删除对应实时航班;逐条隔离坏数据,不能删除写历史失败的集合。五条判史规则、业务时区 `Asia/Shanghai`、历史写入与删除事件之间的恢复协议需在启用前完成 golden 对拍。
阶段 A 不依赖 ES,不接通 `HISTORY_SWEEP / PROJECTION_REBUILD` 占位能力;没有历史写入能力时默认删除零条。不要因代码已有 B 枚举就启用它。
### EPIC-OPS 安全运行、影子验证与切流
## 5. 运行与切流验收
该范围不能作为一个故事验收,拆为:
1. **OPS-1 单写者与 fail-fast**:第二写实例拒启;生产缺依赖或管道未启用时失败并说明原因。
2. **OPS-2 可观测性**:健康、队列、最老年龄、投递延迟、回填滞后、DEAD 和一致性均有指标/告警。
3. **OPS-3 影子隔离**:独立 PG、Redis 前缀、topic、服务名;禁用真实出站和回填。
4. **OPS-4 切流回滚**:影子连续稳定对拍不少于 7 天;未解释业务字段差异严格为 0;DLQ 积压为 0MSG_EVENT 最老滞留 < 5s;切流后设立 48 小时观察期,24 小时内支持按 Runbook 平滑一键回滚。
依赖按实际进入上线范围的阶段 A 故事计算,不包含 US-15。
## 5. Legacy HTTP 工具面
| 端点 | 决定 | 目标口径 |
| 编号 | 必须交付的能力 | 验证证据 |
|---|---|---|
| `POST /cminmsgs/send` | KEEP | US-02 |
| `POST /schd/sync` | KEEP,修正 | 24 小时制、非空/区间校验;只承诺 RQFD 落 COUTMSGS |
| `GET /all/flights` | KEEP | US-12 |
| `POST /kafka/topics/{name}/msgs` | 不进生产 | 若开发仍需,另建工具并限制 topic allowlist |
| `GET /flights/migrate` | 不做 | legacy 一次性 ES 迁移工具 |
| OPS-1 单写者与启动安全 | 生产缺真实适配器、误用 stub、未启用必需管道时拒启;第二活动写者不能启动,失去写权后不得继续写;中断与停机能正确退出。 | 配置拒启、双实例/失去写权及停机测试。单靠副本数配置不算运行期保护。 |
| OPS-2 可观测与安全 | 真实依赖健康、队列/队头年龄、投递/回填滞后、DEAD 和一致性异常有指标、告警与处理入口;敏感管理操作有访问控制,日志不泄漏口令或完整敏感报文。 | 故障注入触发真实告警,消息到事件可关联;日志出口断开不阻塞业务。 |
| OPS-3 影子隔离 | PG、Redis key、topic、服务注册身份隔离;输入只读水位或回放,禁生产回填、真实出站和误注册。Q1 若改存储,隔离方案同步修改。 | 配置与集成测试证明生产信箱、状态、topic 未被影子修改。 |
| OPS-4 切流与恢复 | 对拍不少于 7 天,未解释业务字段差异为 0,DLQ 积压为 0MSG_EVENT 最老滞留 < 5 秒;切流后 48 小时观察,24 小时内具备经演练的回滚能力。 | 明确负载与统计口径的对拍报告;Runbook 含停写、排空/水位、状态恢复、写权交接和失败回退,不能只回滚程序版本。 |
## 6. 详细文档 TODO
上述阈值沿用既有需求基线,需在真实环境提供证据,不代表当前已满足。Redis 权威方案还必须验证空态/全损恢复期间停止增量处理,以及备份和报文保留能支持的恢复范围;不承诺未经演练的“一键无损回滚”。
| 顺序 | Plane | 文档动作 | 完成条件 |
|---|---|---|---|
| 1 | ACM2-16 | 固定 RESP/DNLD/ADFT 路由 | US-06、design、ACM2-6 一致,迟到/无匹配禁更快照定案 |
| 2 | ACM2-17 | 拆归档与清场并标阶段 | US-11 属 AUS-15 DEFERREDHST 禁写,自有 PG 归档定案 |
| 3 | ACM2-19 | 增补信箱回填 | 提交后执行、持久化补偿、四终态回填、影子禁写定案 |
| 4 | ACM2-21 | 消除循环依赖并补管道边界 | US-03 仅依赖 US-01,业务例外归 US-05 |
| 5 | ACM2-15 | 增补 ignoreMsg | 规则、终态、回填和拼写确定 |
| 6 | ACM2-18 | 补查询、机位、21 类数据 | US-1214 与 US-08 分界明确 |
| 7 | ACM2-20 | 声明 HTTP 工具去留 | 五端点均有决定 |
| 8 | ACM2-22 | 吸收评审剩余项 | 水位、依赖、Broker、deadline 一致 |
| 9 | — | 同步 architecture/design/README | 权威口径、索引与阶段表一致 |
### HTTP 工具边界
## 7. 开放问题定案结论汇总
| 端点 | 范围 |
|---|---|
| `POST /cminmsgs/send` | US-02,保留接收兼容性。 |
| `POST /schd/sync` | US-08,保留并修正参数校验;不等同于同步完成快照。 |
| `GET /all/flights` | US-12,保留查询语义。 |
| `POST /kafka/topics/{name}/msgs` | 不进生产;开发工具若保留,另行限制 topic allowlist。 |
| `GET /flights/migrate` | 不做,属于 legacy 一次性迁移工具。 |
1. **【已定案·ACM2-17】归档存储目标**:共享库 CMINMSGS_HST 严禁写入,共享库严格限定信箱两表;归档目标确认为自有 PG `PROC_STATE_HST`
2. **【已定案·ACM2-21】SEQN 重置与时钟锚点**:生产默认保持 `include-day-boundary=false`HOL deadline 锚点固化为 `PROC_STATE.CREATED_AT`(稳定入队时间戳)。
3. **【已定案·ACM2-20/25】compat 接口契约**:支持 text/xml、application/xml 与 text/plain;逐字兼容 legacy `ResponseDto`(成功 `is_success`+`body`;失败 `is_success`+`err_code`+`err_msg`,不用 `msg`);生产保持内网信任姿态
4. **【已定案·ACM2-21】航班不存在与 FDEL**:航班不存在按 KEEP 正常结束且回填信箱;FDEL 共享航班更新主航班 MAFL 并通知,主航班删除清空关联。
5. **【已定案·ACM2-16/18】15 类请求生命周期**:同类并发严格为 1;RQFD 超时 60sRQRD 超时 30s;优先 SEQN 回显,无回显退化 DTTM 时序判定;迟到/无匹配禁更快照。
6. **【已定案·ACM2-22/23】Kafka 生产契约**:强制 `acks=all``idempotence=true`,分区键按 FLIDschd)/SNDR(msg)固化;严禁非幂等降级;现网 Broker API 版本未确认前 US-07 不得标实施完成;README 不提供生产降级 env。
7. **【已定案·ACM2-17】时区与判史边界**:统一 `Asia/Shanghai` 时区;HISTORY_SWEEP 延后至阶段 B,阶段 A 不依赖 ES,Redis 永续动态权威。
8. **【已定案·ACM2-22】对拍与回滚阈值**:影子对拍至少 7 天;业务差异 0 容忍;DLQ 积压为 0;切流后 48 小时保驾、24 小时可平滑回滚。
9. **【已定案·ACM2-26】信箱回填 STATUS 值域**`SUCCEEDED``SUCCESS`ignore `SKIPPED``SKIPPED`duplicate `SKIPPED``DUPLICATE``DEAD``DEAD`(库方/legacy 实测前为占位;若库方禁新值则仅用 legacy 已用集合)。
## 6. 编码前必须处理的决策与契约
这些是**阻塞相应实现的具体问题**,不是已完成的验收项。保留原有目标值,但不把矛盾或外部未确认内容写成事实
| 编号 | 问题与当前口径 | 解除阻塞的产物 |
|---|---|---|
| Q1 权威存储 | 当前基线是 RedisFLIGHT_STATE 提前到 PG 只是提案。影响 US-03/05/06/12、迁移和健康检查。 | 明确选择及批准记录,同步三份主文档后再固定事务、快照协议;未定案可先做无关接口和调度测试。 |
| Q2 入队顺序 | 水位+补扫无法自动保证较小 ID 迟提交不越序;当前有限批扫描也可能被未回填记录挡住。 | 库方 ID/提交顺序约束,或明确的发现完整性与暂停/恢复协议;晚提交、空洞、兼容入口与重扫联合测试。不能凭空假定 ID 连续。 |
| Q3 HTTP 契约 | 目标 ResponseDto 与现有 text/plain ID 不同;请求媒体类型目标已列出,错误码、状态码、查询格式等仍需对拍。 | 每个保留接口的真实请求/响应样例、错误表和契约测试;10MB 的字节口径、字符集及兼容变更说明一起固定。 |
| Q4 Kafka wire | schd 当前多 FLID 聚为一个数组/一条 record,与“record 按 FLID 分区”冲突;msg 的 SNDR 尚未接线。 | 下游确认发送粒度、key、去重标识放置、分区内顺序及批次确认策略;同步 Dispatcher/设计,不擅自把现役数组改成逐航班消息。 |
| Q5 请求匹配 | 目标优先 SEQN 回显,但回显是否可靠需确认;DTTM 降级存在跨代误匹配,尤其旧应答到达新请求期间。 | 15 类请求/响应样例、回显字段与时间格式;降级风险是否接受及拒绝条件。默认超时仍为 RQFD 60 秒、RQRD 30 秒。 |
| Q6 deadline 与重放 | 入队时间作为稳定锚点会把长期排队消息计入滞留;历史重放保留 CREATED_AT 后可能立即过期。 | 明确首次处理/排队过期策略与“本次恢复尝试”计时方式,保留原始时间审计;测试积压恢复和旧 DEAD 重放,不用刷新 UPDATED_AT 绕过超时。 |
| Q7 信箱外部契约 | 原目标为成功→SUCCESS、忽略→SKIPPED、重复→DUPLICATE、死信→DEAD;当前 JDBC 写 PROCESSED。新 STATUS 值尚不能假定库方支持。 | 库方认可的状态值、META/缺失字段、权限、原文保留期、出站去重与处理时间语义;若只允许 legacy 集合,显式映射内部原因,不新增外部枚举。 |
| Q8 业务覆盖清单 | “29 FLOP、14 RQRD、21 参考类、2 机位类”只是数量,不能直接当字段规范。 | 将 SIS/XSD、现役 KEEP/FIX 基线整理为逐类矩阵与脱敏样例,列明路由、字段、缺失/清空、通知、数据来源优先级、多桥规则及测试文件。资料不全的类型不标完成。 |
业务日期/日计划采用 `Asia/Shanghai`;持久化与比较使用明确的时间类型和转换规则,不靠服务器默认时区,也不直接比较不同单位的数字。
## 7. 每个实施 PR 的完成条件
1. 写明所覆盖的 `US-xx/验收条目`、未包含的子范围及相关 Q 项结论,不用“管道已接通”代替全部验收。
2. 列出涉及模块、配置、PG 迁移、外部契约和恢复影响;源码现存的旧注释或空适配器不是正确性依据。
3. 提交对应正常/失败/重复/中断测试;顺序、身份、快照和投递变更必须有不变量回归,PG 事务必须有真实数据库集成测试。
4. 用 JDK 25 执行 `./gradlew test`;受限环境将 `GRADLE_USER_HOME``TMPDIR` 指向可写目录。测试受阻时记录原因,不写“全绿”。
5. 真实适配器未完成、golden 未覆盖或契约仍有阻塞时,不把整项故事标完成;上线另需 OPS 验证和发布证据。
历史文档整改中的勾选不代表业务已实现,也不替代本清单。后续进度放在实施任务与测试证据中,本文保持需求和验收口径稳定。