feat(codec): 观测未落库的 SRVT/VIPF 集合
SRVT/VIPF 只保留在 wire/domain 并计数告警,不落明细表、不参与合并: 出现事实不再被静默丢弃,为 Q13 定案提供真实流量证据([G-SRVT-VIPF])。 - wire DTO:SRVT/SERVICEDATA、VIPF/VIPDATA 与嵌套 VIPT(OPER 为元素属性) - 出现即留键:缺席与"出现但为空"不再等价;已落库 10 类集合语义不变 - 新增 msgx.pipeline.codec.srvt_seen.total / vipf_seen.total(reference.md 已登记) - 一并提交此前的 MAFL 文档改动(INV-21/INV-22、flight-state §2.3、G-MAFL 措辞)
This commit is contained in:
@@ -19,6 +19,32 @@ data class ScheduleBody(
|
||||
val records: List<ScheduleRecord>,
|
||||
)
|
||||
|
||||
/**
|
||||
* 只保留在 wire/domain、尚未映射到持久化明细的集合键(`[G-SRVT-VIPF]`)。
|
||||
*
|
||||
* 它们不参与合并、不进快照、不落库;保留的目的是不让入站事实在解码层被静默抹平,并让真实
|
||||
* 流量里的出现情况可观测——决定"缺席是否等于删除"的 `Q13` 需要真实报文才能定案。
|
||||
*/
|
||||
private val UNPERSISTED_COLLECTION_KEYS: Set<String> = setOf("SRVT", "VIPF")
|
||||
|
||||
/**
|
||||
* 一条解码载荷里各未落库集合命中的**记录数**(`[G-SRVT-VIPF]`)。
|
||||
*
|
||||
* 按记录计(一条记录带该段即算 1),不按段内元素计;只返回命中项。载荷类型不在
|
||||
* [ScheduleBody] / [FlopPayload] 之内时返回空——调用方不得据此改变处理结果。
|
||||
*/
|
||||
fun unpersistedCollectionHits(body: Any?): Map<String, Int> {
|
||||
val perRecord = when (body) {
|
||||
is ScheduleBody -> body.records.map { it.collections }
|
||||
is FlopPayload -> listOf(body.collections)
|
||||
else -> return emptyMap()
|
||||
}
|
||||
if (perRecord.isEmpty()) return emptyMap()
|
||||
return UNPERSISTED_COLLECTION_KEYS
|
||||
.mapNotNull { key -> perRecord.count { key in it }.takeIf { it > 0 }?.let { key to it } }
|
||||
.toMap()
|
||||
}
|
||||
|
||||
/**
|
||||
* Wire DTOs for SIS in docs/legacy/SIS_AODB_RMS-V0.1.md.
|
||||
* SIS permits a subsystem to ignore standard fields it does not use; those fields are
|
||||
@@ -105,6 +131,10 @@ data class FlightRecordXml(
|
||||
@param:JacksonXmlElementWrapper(useWrapping = false) @param:JacksonXmlProperty(localName = "CHOT") val chot: List<ChotXml> = emptyList(),
|
||||
@param:JacksonXmlElementWrapper(useWrapping = false) @param:JacksonXmlProperty(localName = "ROUT") val rout: List<RoutXml> = emptyList(),
|
||||
@param:JacksonXmlElementWrapper(useWrapping = false) @param:JacksonXmlProperty(localName = "ERUT") val erut: List<RoutXml> = emptyList(),
|
||||
// SRVT/VIPF 用可空表达"段是否出现":null = 未出现;出现即为列表(空元素得到一行空行)。
|
||||
// 两者都不落明细表、不参与合并,清空语义待 `Q13`(`[G-SRVT-VIPF]`)。
|
||||
@param:JacksonXmlElementWrapper(useWrapping = false) @param:JacksonXmlProperty(localName = "SRVT") val srvt: List<SrvtXml>? = null,
|
||||
@param:JacksonXmlElementWrapper(useWrapping = false) @param:JacksonXmlProperty(localName = "VIPF") val vipf: List<VipfXml>? = null,
|
||||
)
|
||||
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
@@ -198,3 +228,44 @@ data class RoutXml(
|
||||
@param:JacksonXmlProperty(localName = "SCAT") val scat: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "SCDT") val scdt: String? = null,
|
||||
)
|
||||
|
||||
/**
|
||||
* SIS `SRVT`/`SERVICEDATA`(SCHD)与 `OPT_SERVICEDATA`(FLOP):一次服务明细,可重复出现。
|
||||
*
|
||||
* 字段形态以 `docs/legacy/unisysaodbsis.xsd` 为准。`OPER` 是元素属性,SIS 正文未记载其值域;
|
||||
* `SANR`/`SARR` 只出现在 FLOP 的 `OPT_SERVICEDATA`。协议未给序号属性,故没有源序号。
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
data class SrvtXml(
|
||||
@param:JacksonXmlProperty(isAttribute = true, localName = "OPER") val oper: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "SRTC") val srtc: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "SRQT") val srqt: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "SRST") val srst: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "SRET") val sret: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "SRPR") val srpr: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "SANR") val sanr: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "SARR") val sarr: String? = null,
|
||||
)
|
||||
|
||||
/**
|
||||
* SIS `VIPF`/`VIPDATA`(SCHD)与 `OPT_VIPDATA`(FLOP):一位 VIP,可重复出现。
|
||||
*
|
||||
* `VIPT` 按 XSD 至多一个;SIS 正文"每个 VIP 重复"的说法与之冲突,形态以 XSD 为准。
|
||||
*/
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
data class VipfXml(
|
||||
@param:JacksonXmlProperty(isAttribute = true, localName = "OPER") val oper: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "VPCD") val vpcd: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "VFES") val vfes: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "VIPT") val vipt: ViptXml? = null,
|
||||
)
|
||||
|
||||
/** SIS `VIPT`/`VIPTXNDATA`:VIP 关联的服务交易明细,嵌套在 [VipfXml] 内。 */
|
||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||
data class ViptXml(
|
||||
@param:JacksonXmlProperty(isAttribute = true, localName = "OPER") val oper: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "VSCD") val vscd: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "VTQY") val vtqy: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "VTST") val vtst: String? = null,
|
||||
@param:JacksonXmlProperty(localName = "VTET") val vtet: String? = null,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user