test(migration): 带数据 V1.1→最新升级链验证 + DELY Apply 拒绝 (ACM2-29 P2-4)

- FlywayMigrationTest 新增升级链用例:隔离 schema 迁至 V1.1.0、写入含
  *_TXT 的存量行、一路升级到最新——断言标量数据存活、v2 追踪列默认就位、
  display 视图/backfill_todo/明细表可用、*_TXT 列按已知损失边界消失(评审 F6:
  升级前必须导出或重放,测试固化该边界)
- L2 收尾:DELY 无协议序号属性(DLNO 非法)——SEQ_ATTR 移除 DELY,Apply 对
  DELY fail fast 拒绝(语义矩阵 §2 同步口径)
- 级联回归已在 P2-2 落地(deleteByFlids/deleteDiffByDay 明细级联断言)

验证:MSGX_PG_PORT=5433 真实 PG 全量 107 用例 0 失败 0 跳过
This commit is contained in:
windyboy
2026-09-08 15:54:50 +08:00
parent 20aafb9ab0
commit 06a1081bdd
3 changed files with 116 additions and 2 deletions
@@ -31,12 +31,12 @@ object FlightStateEngine {
"CLDT" to "CLNO",
"PSDT" to "PSNO",
"CHDT" to "CHNO",
"DELY" to "DLNO",
"ABTM" to "ASNO",
"CHOT" to "CSNO",
"ROUT" to "RTNO",
"ERUT" to "RTNO",
)
// 注意:DELY 无协议序号属性(DLNO 非法)→ 不支持 Apply;清除走空数组 Replace(空集)
/** DNLD/FLOP 字段集 → 命令(出现即 Set/Replace;未出现即 Unchanged;序号 0 条目 = 显式清除标记)。 */
fun commandsFromFields(flid: String, fields: FlightFields, snapshotReplace: Boolean): FlightFieldCommands {
@@ -96,8 +96,10 @@ object FlightStateEngine {
is CollectionCommand.Replace -> baseCollections[key] = cmd.items.toMutableList()
CollectionCommand.Clear -> baseCollections.remove(key)
is CollectionCommand.Apply -> {
val seqAttr = SEQ_ATTR[key]
?: throw IllegalArgumentException("$key does not support Apply: protocol defines no source sequence attribute")
val list = baseCollections.getOrPut(key) { mutableListOf() }.toMutableList()
val idx = list.indexOfFirst { it[SEQ_ATTR[key] ?: ""] == cmd.sourceSeq }
val idx = list.indexOfFirst { it[seqAttr] == cmd.sourceSeq }
if (idx >= 0) {
list[idx] = cmd.item
} else {