Files
break 370fd3e67f
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 10m49s
update
2026-09-03 09:28:28 +08:00

3.1 KiB
Raw Blame History

Context

现有 step2 依据旧套餐的类型、状态、生效时间和到期时间分类生命周期;分类后只要同一资产有多条 active 就阻断。奇成数据中的少量续费记录缺少生效时间且仍标为正常,无法从通用字段推断先后关系。

Goals / Non-Goals

Goals:

  • 用映射配置表达经运营确认的逐卡裁决。
  • 在生成 SQL 前验证裁决完整性,确保不静默丢失或重复迁移套餐。
  • 将覆盖后的状态写入现有审核产物,保持可追溯性。

Non-Goals:

  • 不修改奇成老库记录。
  • 不依据到期时间、创建时间或套餐时长引入全局自动裁决规则。
  • 不改变未覆盖资产的现有分类和阻断逻辑。

Decisions

使用 ICCID 与生命周期 ID 的显式覆盖

mapping.yaml 增加 package_lifecycle_overrides。每项包含完整 ICCID、一个 active_life_id、可选的 pending_life_idsskipped_life_ids

生命周期 ID 是老库主键,避免到期时间存在 UTC/本地时区展示差异或同日期重复时的歧义。完整 ICCID 与 step2 的资产键一致。

未采用“最早到期记录为当前”的规则:已确认的第三张异常卡表明未来记录并不必然均应作为待生效迁移。

覆盖在冲突检测前重分类

先获取老库原始生命周期及既有通用分类,再按 ICCID 应用覆盖,最后执行现有映射、唯一 active 校验与 SQL 生成。覆盖只改变配置明确列出的记录状态;同卡其他通用分类为 activepending 的正式套餐必须也被覆盖明确裁决,否则报配置错误并阻断该资产。

配置与运行时双重校验

加载时校验字段格式、同一覆盖内 ID 不重复且状态集合不重叠。读取老库后校验每个被引用 ID 都属于该 ICCID 的 tbl_card_life 记录、active 恰好一个、覆盖未遗漏其他原本可迁移记录。错误沿用 step2 的错误 CSV且不生成该资产套餐 SQL。

本批已确认裁决

实现时将下列裁决写入迁移配置:

ICCID active pending skipped
89860624630055027529 DD74BA52EC8242FF94815532DC19389B AB77C853EEF444E2AF20A8475F61CFA7
89860624630055035589 4ACDBC19027A4E90BF500F515093E0A3 2D247EF7877C4CE18E74EF9B139B7FCD
89860624590009246403 186B9062F3904AACB4A231041B6B5E98 EB006800000D49EB9A18024922657680

Risks / Trade-offs

  • [运营裁决填写错误] → 覆盖按老库主键校验,并在审核 CSV 输出覆盖后的每条记录状态。
  • [老库后续新增套餐记录] → 完整性校验拒绝遗漏的可迁移记录,要求重新确认配置。
  • [覆盖配置被误用于常规数据] → 不提供全局或通配符规则,覆盖仅作用于单一完整 ICCID。

Migration Plan

  1. 发布包含覆盖能力与上述三项配置的迁移脚本。
  2. 在隔离环境重新生成 step2核对三张卡各一条 active前两张各一条 pending第三张无额外套餐。
  3. 线上仅执行经审核的生成 SQL若需回退移除对应覆盖后重新生成不写老库。