Files
msgexchange-v2/docs/user-stories.md
T

327 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# msgexchange-v2 用户故事与实施清单
## 1. 如何使用本文
本文是把现有脚手架补成可用系统的实施入口:**故事定义要交付什么,验收标准定义怎样证明完成,代码落点说明从哪里改起**。保留 US-01US-15、OPS-1OPS-4 编号,便于关联已有任务和测试。
- 系统边界见 [architecture.md](architecture.md),模块流程见 [design.md](design.md)。本文不重复设计全文,也不以工单状态代替代码验收。
- “当前基础”来自本轮代码核对,只表示有接口或部分实现,不表示故事完成。`KEEP` 是保留业务兼容,`FIX` 是明确修正旧缺陷,`DEFERRED` 不进入阶段 A。
- “信箱落信、PG 入队、业务处理完成、信箱回填、下游确认”是五个独立事实,接口、日志和测试必须分开表达。
- 所有内部迁移只落自有 PG;共享 MySQL 不建表、不增列、不写历史表。本文用 `DATE_PROCESSED / STATUS` 表示逻辑字段,实际列名以库方契约为准。
- 验收条目可按 `US-xx/条目号` 引用。故事较大时按下文子范围拆成小 PR,不把一个故事等同于一个提交。
**存储基线提醒**[FLIGHT_STATE 决策提案](decision-flight-state.md) 尚未定案。本文仍按阶段 A Redis 权威描述;涉及权威状态、快照和事务顺序的最终实现,先处理 Q1,不能一边实现 Redis 协议一边擅自迁为 PG 权威。
## 2. 建议实施顺序
先补可靠性边界,再打通一条真实业务链,最后扩充报文类型。每批均可先用假适配器测试,但真实链路验收不能省略。
| 批次 | 实施范围 | 本批交付证明 |
|---|---|---|
| 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 升序、有限批次采集未处理记录;接收层只入队,不解析业务、不回填已处理标记。
2. 按信箱 ID 幂等建立 PG `PENDING`;重复扫描、并发兼容入队和进程重启都不能重置已有终态。
3. 快路径用持久水位,补偿路径受控重扫遗漏;本批 PG 入队全部确认后才推进水位。补偿可分页推进,不能被已入队但尚未回填的前一批永久挡住。
4. PG 不可用或批次中途失败时不改信箱标记;恢复后补建遗漏,记录失败次数与扫描进度。
5. 较小 ID 迟提交、ID 有空洞、兼容入口先入队较大 ID 时,必须遵守经 Q2 确认的发现与顺序协议;不能用“最终会重扫”冒充严格 FIFO。
**当前基础与落点**`ingress/InboxPoller.kt``InboxEnqueue.kt``infra/persistence/jdbc/JdbcCminmsgInboxRepository.kt` 已有轮询和判重;固定 `afterId=0`,水位与补偿未实现。扩展 `InboxPollerTest`,补真实 PG/MySQL 中断恢复测试。
**前置**:共享库读契约;Q2 决定严格顺序的端到端验收。
### US-02 兼容 HTTP 注入报文(KEEP
**目标**:联调工具通过 `POST /cminmsgs/send` 提交 XML,得到真实的信箱接收结果。
**验收标准**
1. 支持 `text/xml``application/xml``text/plain`,默认 UTF-8;空报文、超过 10MB 的请求和畸形 XML 返回规范错误,不落信。XML 校验禁用 DTD、外部实体与外部资源访问。
2. 信箱确认落信后返回 ID;PG 入队失败不把已落信伪装成未接收,由 US-01 补建。信箱写入未确认时不返回成功。
3. 目标为兼容 `ResponseDto`;固定成功/失败样例、HTTP 状态码、响应媒体类型和错误码表后加入契约测试,见 Q3。成功只承诺信箱落信,不承诺业务处理或下游完成。
4. 生产保持内网信任边界,由网关限制来源并审计;外露或跨网络必须先落实认证,不能把免密入口直接暴露。
**目标响应体示例**(数字和错误码仅作示例,错误码表见 Q3):
```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. 安全解码 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. 权威存储不可用或未完成恢复时停止业务处理;不能把“整个状态丢失”误判为“单航班不存在”而批量成功结束增量报文。
**当前基础与落点**`processing/Pump.kt`(含 `MessageProcessor`)、`Identity.kt``codec/XmlCodec.kt``infra/retry/``JdbcPgRepositories.kt`。已有身份/重试边界测试,但 codec 为接口,主泵直取系统时间,普通 Redis 更新占位,PG 操作未共享事务;补 `CREATED_AT` 迁移及主泵级回归测试。
**前置**:US-01;Q1 决定状态提交实现,Q6 决定 deadline 边界。现有 `FlightStateRepository` 空实现不是建表授权。
### US-04 明确忽略非业务报文(KEEP)
**目标**:无需处理的报文有可追踪的终结结果,不制造无效重试与死信。
**验收标准**
1. 解码 META 后、身份绑定及业务 Handler 查找前,大小写不敏感匹配 `TYPE-STYP``TYPE-*`;基线为 `LDM-* / REGN-* / RSTA-* / EROR-*`,不混用 `ERROR`
2. 命中后转 `SKIPPED`,记录 `ignored:<rule>` 和计数;不更新航班、不创建业务通知。
3. 通过 US-09 保存回填意图;命中、未命中、大小写和重扫均有测试。合法忽略报文不应因 `MsgKind` 尚不能表达它而先解码失败。
**当前基础与落点**`MessageProcessor` 尚无忽略分支,`DecodedMessage/MsgKind` 主要覆盖 SCHD/FLOP;扩展解码与路由,不把忽略逻辑散落到 Handler。
**前置**US-03 解码/终态接口、US-09。
### US-05 应用 ADFT 与 29 类 FLOPKEEP + FIX
**目标**:增量报文正确更新航班及主/共享关系,并生成符合现役语义的通知。
**验收标准**
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。
**当前基础与落点**`processing/Handler.kt``domain/Decision.kt``infra/redis/` 只有主要扩展点;按类型新增 Handler 与同包测试。先做 ADFT + 一个普通 FLOP,再做主/共享及 PSDT,最后补齐矩阵。
**前置**US-03PSDT 另依赖 US-14Q1、Q8。
### US-06 导入 RESP/DNLD 日计划快照
**目标**:主动下发和请求应答使用同一套全量计划处理,迟到应答不覆盖新状态。
| 报文 | 路由 | 请求状态 | 无匹配时 |
|---|---|---|---|
| `SCHD-DNLD` | SnapshotFlow | 不更新请求 | 不要求开放请求 |
| `SCHD-RESP` | 匹配守卫后进入 SnapshotFlow | 成功提交时匹配 RQFD → DONE | SKIPPED、审计,禁止更新快照 |
| `SCHD-ADFT` | US-05 增量 Handler | 不更新请求 | 不适用 |
**验收标准**
1. RESP/DNLD 共用流式解析、整包校验和规范化;校验失败不发布半包,旧快照保持可用。
2. RESP 仅匹配未过期、已发送的开放 RQFD;`DTTM < SENT_AT`、已过期、已被替代或无匹配时,不写业务状态,记录跳过原因。
3. 当前 Redis 基线下,Lua 原子执行新代写入、旧代差集删除和版本校验/推进;删除集只来自上一代成员,不误删集合外的 ADFT 航班。
4. 随后在一个 PG 事务提交 `SUCCEEDED`、待发通知、回填意图;匹配 RESP 同事务完成请求,并保存完成时间与应答信箱 ID。
5. 相同报文重放不二次增代或删数据;覆盖首次/连续快照、DNLD→ADFT→DNLD′、旧应答与 Redis 成功/PG 失败窗口。不能只靠“读取当前版本再加一”实现重放识别。
**当前基础与落点**`processing/SnapshotFlow.kt` 的 staging 为占位,主处理只分流 DNLD,gen 走进程内过渡仓储。需补 RESP 路由、版本协议及 `REQ_TRACK` 应答关联字段和事务测试。
**前置**US-03、US-08 请求登记/匹配基础;Q1、Q5。
### US-07 可靠、有序地投递 Kafka
**目标**:状态应用完成后投递通知;重试可识别、不乱序、不静默丢失。
**验收标准**
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 保留记录并告警。
**当前基础与落点**`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;逐类名称、编码和映射见 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 小时制和非空/区间校验;响应明确已登记还是已落信,不承诺计划已更新。
**当前基础与落点**`reference/RequestCoordinator.kt``ReqTrackRepository` 和 JDBC 表已存在;当前真实出站未实现就标发送,回显匹配和超时未闭环。需补 COUTMSGS 适配器、编码、并发约束、应答路由与故障测试。
**前置**US-01、US-03;Q5、Q8、出站信箱去重契约。请求基础不依赖 US-06。
### US-09 持久化补偿回填信箱
**目标**:本地处理终态最终反映到共享信箱,不因共享库故障回滚已完成业务。
**验收标准**
1. PG 终态与回填意图同事务保存;所有终态路径都经过统一提交边界,不只覆盖成功路径。事务回滚时不得留下可执行回填意图。
2. 提交后由后台执行回填,主泵不等待共享库;失败按持久记录退避,重启继续执行,不重新执行已完成业务。
3. SUCCEEDED、规则忽略、身份重复、DEAD 均需回填处理时间;PENDING/FAILED 禁止回填。具体 STATUS 编码按 Q7 确认,内部终态不能直接当作外部字段值。
4. 重复补偿效果幂等,保留稳定的完成时间与审计;重放后的新处理结果不能被旧回填任务覆盖。非法报文缺 META 时也有明确回填方式。
5. 影子模式禁写,双跑仅一个系统持有标记写权;暴露 PG 终态、回填状态、积压、最老年龄与持续失败告警。
**当前基础与落点**`backfillOnSuccess` 当前仅同步写 `PROCESSED`,无持久意图。补自有 PG 意图模型/迁移、事务提交入口和独立补偿执行器;不在共享库新增补偿表。
**前置**:US-03 终态接口;Q7、共享库更新权限。测试覆盖四类终态、事务回滚、重复补偿和重放竞争。
### US-10 安全重放与故障处置
**目标**:运维能定位失败、限定恢复范围,并了解重放对当前航班状态的影响。
**验收标准**
1. 按 ID、错误类、时间查询次数、错误、关联事件与回填状态;重放前预览范围,记录操作者、原因和逐项结果。
2.`CODEC_ERROR / UNSUPPORTED / INFRA / EXHAUSTED` 的 FAILED/DEAD 允许申请重放;MALFORMED 与其他不允许项不改状态,返回跳过原因。
3. 重置 attempts/nextAttemptAt,保留身份、原始入队时间和错误审计;采用 Q6 确认的重放 deadline 策略。重新入队仍按 ID 处理,但不承诺已执行过的后续消息自动撤销。
4. DEAD 之后可能已有新状态,必须预检版本与覆盖风险;不安全时拒绝直接重放,改用经批准的隔离重建或恢复流程,禁止无保护的全量 `replayAll` 生产入口。
5. 操作有认证、授权、范围限制与审计;死信、持续补偿失败、队列年龄越界有告警和处理 Runbook。
**当前基础与落点**`infra/retry/ReplayService.kt` 仅按错误类批量重排并返回数量;需补按记录选择、预检、操作审计和管理入口,扩展 `ReplayServiceTest`
**前置**US-03、US-09 的恢复状态;Q6、OPS-1/OPS-2 的安全与可观测基础。
### US-11 归档自有库终态记录
**目标**:控制自有 PG 在线表规模,不丢未完成工作、不破坏去重与恢复;不是清理共享信箱。
**验收标准**
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 关联确认。
**当前基础与落点**`jobs/JobExecutor.kt``PumpJobRepository` 为入口;当前迁移无归档表。先确定去重记录保留与关联策略,再补迁移及归档中断测试。
**前置**US-03、US-09US-07 提供事件终态规则,US-10 提供恢复保留要求。不依赖 US-15。
### US-12 查询实时航班(KEEP
**目标**:调用方读取与当前权威状态一致的实时航班视图。
**验收标准**
1. 保留 `GET /all/flights`,过滤 `MAID != NULL` 的共享航班;不改写业务状态。
2. 固定响应样例、空结果、排序、大小限制及一致性时点。现役未分页时不能无声改为只返回第一页;分页或响应结构变更按 Q3 决定。
3. 依赖异常不能伪装为空数组成功;影子只读影子状态,入口有约定的访问控制、限流与审计。
**当前基础与落点**`InboxController.kt` 中仅有该接口 TODO;新增查询控制器与只读服务,复用权威读取端口,不能从空占位仓储返回成功。新增接口/状态不可用测试。
**前置**Q1、Q3;所查询的 US-05/US-06 状态发布能力。
### US-13 刷新 21 类参考主数据
**目标**:业务使用来自 admin-api 的本地参考数据,刷新失败仍有上次可用版本。
**验收标准**
1. 按 Q8 的 21 类清单配置端点、RTYPE/RKEY、字段映射;这是独立于 US-08 的数据入口,不另建“参考专用第二 PG”。
2.`(RTYPE,RKEY)` 幂等写 REF_MASTER,记录 SOURCE、刷新时间和批次;单类完整校验后发布,失败不暴露半批。
3. 一类失败不破坏其他类或该类旧版本;同类由 AODB/admin-api 都提供时明确覆盖优先级,全量刷新时明确已删除项的处理,不能仅靠 SOURCE 日志解决冲突。
4. 影子默认不主动刷新生产数据;需要参考样本时显式导入隔离副本。
**当前基础与落点**`reference/ReferenceService.kt` 是空刷新入口,`JdbcStaticRefRepository` 有逐条 upsert;补客户端、类型清单、批次发布/事务和失败保旧测试。
**前置**admin-api 访问契约、Q8。可独立于消息 Handler 开发。
### US-14 提供机位与登机桥映射
**目标**:PSDT 在不调用外部 HTTP 的情况下得到完整映射,正确计算 `abdg`
**验收标准**
1. 保留 `ORMS_STAND / ORMS_STAND_AIRBRIDGE` 两类,与 US-13 的 21 类分开统计;适配器拉取、完整校验后原子发布只读缓存。
2. 近机位产生登机桥值,远机位或清空机位时 `abdg` 为空;一机位多桥、缺失映射与共享航班规则用 golden 固定。
3. admin-api 不可用时使用最后可用版本;无可用版本或映射不完整时明确失败,不用空映射冒充正常清空,也不发布半批。
4. Handler 输入包含所需只读参考视图,不允许其直接 HTTP 或写缓存。
**当前基础与落点**:在 `reference/``infra/` 增加映射服务/适配器,必要时扩展 Handler 输入上下文;PSDT 测试使用固定映射,无需在线 admin-api。
**前置**:机位/桥数据契约及 Q8;不要求 US-13 全部完成。
## 4. 暂缓范围
### US-15 历史航班清场(DEFERRED,阶段 B)
历史存储确认成功后,才允许主泵删除对应实时航班;逐条隔离坏数据,不能删除写历史失败的集合。五条判史规则、业务时区 `Asia/Shanghai`、历史写入与删除事件之间的恢复协议需在启用前完成 golden 对拍。
阶段 A 不依赖 ES,不接通 `HISTORY_SWEEP / PROJECTION_REBUILD` 占位能力;没有历史写入能力时默认删除零条。不要因代码已有 B 枚举就启用它。
## 5. 运行与切流验收
| 编号 | 必须交付的能力 | 验证证据 |
|---|---|---|
| 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 含停写、排空/水位、状态恢复、写权交接和失败回退,不能只回滚程序版本。 |
上述阈值沿用既有需求基线,需在真实环境提供证据,不代表当前已满足。Redis 权威方案还必须验证空态/全损恢复期间停止增量处理,以及备份和报文保留能支持的恢复范围;不承诺未经演练的“一键无损回滚”。
### HTTP 工具边界
| 端点 | 范围 |
|---|---|
| `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 一次性迁移工具。 |
## 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 验证和发布证据。
历史文档整改中的勾选不代表业务已实现,也不替代本清单。后续进度放在实施任务与测试证据中,本文保持需求和验收口径稳定。