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

52 lines
3.1 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.
## Context
现有 step2 依据旧套餐的类型、状态、生效时间和到期时间分类生命周期;分类后只要同一资产有多条 `active` 就阻断。奇成数据中的少量续费记录缺少生效时间且仍标为正常,无法从通用字段推断先后关系。
## Goals / Non-Goals
**Goals:**
- 用映射配置表达经运营确认的逐卡裁决。
- 在生成 SQL 前验证裁决完整性,确保不静默丢失或重复迁移套餐。
- 将覆盖后的状态写入现有审核产物,保持可追溯性。
**Non-Goals:**
- 不修改奇成老库记录。
- 不依据到期时间、创建时间或套餐时长引入全局自动裁决规则。
- 不改变未覆盖资产的现有分类和阻断逻辑。
## Decisions
### 使用 ICCID 与生命周期 ID 的显式覆盖
`mapping.yaml` 增加 `package_lifecycle_overrides`。每项包含完整 ICCID、一个 `active_life_id`、可选的 `pending_life_ids``skipped_life_ids`
生命周期 ID 是老库主键,避免到期时间存在 UTC/本地时区展示差异或同日期重复时的歧义。完整 ICCID 与 step2 的资产键一致。
未采用“最早到期记录为当前”的规则:已确认的第三张异常卡表明未来记录并不必然均应作为待生效迁移。
### 覆盖在冲突检测前重分类
先获取老库原始生命周期及既有通用分类,再按 ICCID 应用覆盖,最后执行现有映射、唯一 active 校验与 SQL 生成。覆盖只改变配置明确列出的记录状态;同卡其他通用分类为 `active``pending` 的正式套餐必须也被覆盖明确裁决,否则报配置错误并阻断该资产。
### 配置与运行时双重校验
加载时校验字段格式、同一覆盖内 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若需回退移除对应覆盖后重新生成不写老库。