refactor(flight-schd): 按现场 11g 约束将运营航班存储改为宽表 (ACM2-28 修订)
现场环境仅提供 Oracle 11g(无任何 JSON 能力),废除 FLTR_JSON JSONB 整文档存储: - V1.1.0 迁移重写:FLIGHT_SCHD 改为一行一航班宽表(SCHD.FLTR 标量字段列 + 1:N 明细集合序列化文本列),SCHD_GEN.FLIDS_JSON 展开为 SCHD_GEN_FLID(FDAY, FLID); 已应用过旧版迁移的环境需重建 schema 重放 - 契约层:FlightChange/Handler 在线视图改为字段集映射(与 legacy flightInfo hash 同构),仓储白名单拒绝未知字段;增量写=字段级合并(hmset 同语义), 快照=整体替换 - 事件载荷:快照投递与投影重建经 FlightFieldsJson 确定性序列化(键序稳定) - 影子对拍:FlightStoreDiffTool 改为 PG 宽表列值 vs legacy FLTR JSON 逐字段 归一化比对,新增嵌套集合比对用例 - 测试:61 用例全绿(不变量门槛 1/2/3、UTC 方言、真实 PG 方言集成、清场五场景) - 文档:decision-flight-state.md 追加 §8 修订记录(不改写定案历史),design.md 表说明同步 11g 方言移植(ON CONFLICT→MERGE、advisory lock 替代、Flyway/驱动矩阵)、 集合列升子表、类型化列提升等未尽事项另立 Plane issue 跟踪。
This commit is contained in:
@@ -11,8 +11,11 @@ import com.gzzn.omms.msgexchange.domain.MsgKind
|
||||
interface Handler {
|
||||
val kind: MsgKind
|
||||
|
||||
/** 在线状态以只读视图传入(阶段 A 点查自有 PG FLIGHT_SCHD,由调用方装配,ACM2-28 定案)。 */
|
||||
fun decide(flightView: Map<String, String>, msg: DecodedMessage): Decision
|
||||
/**
|
||||
* 在线状态以只读视图传入:FLID → 字段集(field → value,与 legacy flightInfo hash /
|
||||
* hgetAllFlightInfo 同构;阶段 A 由调用方点查自有库 FLIGHT_SCHD 宽表装配,ACM2-28 定案)。
|
||||
*/
|
||||
fun decide(flightView: Map<String, Map<String, String>>, msg: DecodedMessage): Decision
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -219,7 +219,7 @@ class MessageProcessor(
|
||||
// upsert FLIGHT_SCHD(decision.flightChanges) + insert MSG_EVENT + PROC_STATE → SUCCEEDED
|
||||
val events = buildList {
|
||||
decision.msgNotifies.forEach { add(MsgEvent(target = Targets.KAFKA_MSG, payloadJson = it.payloadJson)) }
|
||||
decision.schdPush.forEach { add(MsgEvent(target = Targets.KAFKA_SCHD, partitionKey = it.flid, payloadJson = it.fltrJson)) }
|
||||
decision.schdPush.forEach { add(MsgEvent(target = Targets.KAFKA_SCHD, partitionKey = it.flid, payloadJson = it.payloadJson)) }
|
||||
}
|
||||
|
||||
txManager.inTransaction {
|
||||
|
||||
@@ -8,6 +8,8 @@ import com.gzzn.omms.msgexchange.domain.MsgEvent
|
||||
import com.gzzn.omms.msgexchange.domain.MsgKind
|
||||
import com.gzzn.omms.msgexchange.domain.Targets
|
||||
import com.gzzn.omms.msgexchange.infra.persistence.CminmsgInboxRepository
|
||||
import com.gzzn.omms.msgexchange.infra.persistence.FlightFields
|
||||
import com.gzzn.omms.msgexchange.infra.persistence.FlightFieldsJson
|
||||
import com.gzzn.omms.msgexchange.infra.persistence.FlightSchdRepository
|
||||
import com.gzzn.omms.msgexchange.infra.persistence.MsgEventRepository
|
||||
import com.gzzn.omms.msgexchange.infra.persistence.PipelineTransactionManager
|
||||
@@ -42,7 +44,7 @@ class SnapshotFlow(
|
||||
return
|
||||
}
|
||||
val ok = staged as StageResult.Ok
|
||||
val normalized = ok.flights // (flid, payloadJson)
|
||||
val normalized = ok.flights // (flid, fields)
|
||||
val day = ok.day
|
||||
|
||||
// 内存与超大包熔断防御(ACM2-28 评论 4 项 3)
|
||||
@@ -93,9 +95,9 @@ class SnapshotFlow(
|
||||
}
|
||||
}
|
||||
|
||||
// 构造并批量写入 schd 投递事件
|
||||
val events = normalized.map { (flid, json) ->
|
||||
MsgEvent(target = Targets.KAFKA_SCHD, partitionKey = flid, payloadJson = json)
|
||||
// 构造并批量写入 schd 投递事件(载荷 = 字段集序列化,KAFKA_SCHD 线格式)
|
||||
val events = normalized.map { (flid, fields) ->
|
||||
MsgEvent(target = Targets.KAFKA_SCHD, partitionKey = flid, payloadJson = FlightFieldsJson.toJson(fields))
|
||||
}
|
||||
if (events.isNotEmpty()) {
|
||||
msgEvents.insertAll(events)
|
||||
@@ -116,7 +118,7 @@ class SnapshotFlow(
|
||||
|
||||
/** staging 结果(骨架)。 */
|
||||
sealed interface StageResult {
|
||||
data class Ok(val day: String, val flights: List<Pair<String, String>>) : StageResult
|
||||
data class Ok(val day: String, val flights: List<Pair<String, FlightFields>>) : StageResult
|
||||
data class Invalid(val reason: String) : StageResult
|
||||
|
||||
companion object {
|
||||
|
||||
Reference in New Issue
Block a user