This commit is contained in:
45
openspec/changes/fix-realname-activation-logic/proposal.md
Normal file
45
openspec/changes/fix-realname-activation-logic/proposal.md
Normal file
@@ -0,0 +1,45 @@
|
||||
## Why
|
||||
|
||||
当前系统存在两个关联缺陷,且缺陷 A 的影响远不止套餐激活本身:
|
||||
|
||||
**缺陷 A**:代理商**先给设备/卡实名,再购买 `expiry_base=from_activation` 的套餐**,系统未检查当前实名状态,无条件将套餐标记为 `pending_realname_activation=true`(待生效,status=0)。这不仅导致套餐永久无法激活,还**连带阻断了购买后的自动复机链路**:`tryResumeAfterPayment` 在检查到 `activatedCount=0` 时直接跳过,即使卡此前因无套餐而停机,购买成功后也不会自动开机。
|
||||
|
||||
**缺陷 B**:卡首次实名(0→1)时,实名轮询处理器只触发卡级套餐激活,不处理该卡所属设备的设备级套餐,导致设备级套餐在"购买后某张卡实名"场景下永不激活,同样无法触发设备下绑定卡的复机。
|
||||
|
||||
修复后的规则:**`from_activation` 套餐在购买时检查实名状态,已实名则直接激活(同时保障复机链路正常触发);卡首次实名时同时触发其所属设备的设备级套餐激活与复机**。
|
||||
|
||||
## What Changes
|
||||
|
||||
- **购买时实名状态检查**:在 `activateMainPackage` 中,当判断 `expiry_base != "from_purchase"` 时,额外检查载体当前实名状态:
|
||||
- `iot_card`:查询该卡的 `real_name_status`
|
||||
- `device`:通过 `tb_device_sim_binding` 查询是否存在任意已实名的绑定卡
|
||||
- 已实名 → 直接激活(`status=Active`),`tryResumeAfterPayment` 检查到 `activatedCount>0` 后正常触发复机链路
|
||||
- 未实名 → 保持原有逻辑等待实名触发
|
||||
- **实名轮询触发设备级激活与复机**:在 `PollingRealnameHandler` 的卡首次实名(0→1)路径中,额外查询该卡所属设备,若设备存在则同时提交 `carrier_type=device` 的 `TaskTypePackageFirstActivation` 任务;任务执行后 `ActivateByRealname` 内部会调用 `ResumeCardIfStopped("device", deviceID)` 触发设备下符合条件卡的复机
|
||||
- `NewPollingRealnameHandler` 构造函数新增 `*postgres.DeviceSimBindingStore` 参数
|
||||
|
||||
**复机行为说明**:自动复机仅针对由轮询系统引起的停机(`stop_reason` 为 `no_package`、`traffic_exhausted`、`not_realname`),手动停机(`manual`)不受影响,设备下每张卡独立判断实名状态后再决定是否复机。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
无新能力,均为现有逻辑的修正。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `package-realname-activation`:补充"购买时载体已实名则直接激活"的决策分支,以及"设备下卡实名时触发设备级套餐激活"的联动规则
|
||||
- `polling-task-handlers`:`PollingRealnameHandler` 新增 `DeviceSimBindingStore` 依赖,新增 `triggerDeviceRealnameActivation` 函数
|
||||
|
||||
## Impact
|
||||
|
||||
**涉及文件**:
|
||||
- `internal/service/order/service.go`(`activateMainPackage` 函数,~1782-1807 行)
|
||||
- `internal/task/polling_realname_handler.go`(结构体、构造函数、新增函数)
|
||||
- `pkg/queue/handler.go`(`registerPollingHandlers` 中的构造调用)
|
||||
|
||||
**数据库**:无 schema 变更,无迁移
|
||||
|
||||
**API**:无接口变更,对外透明
|
||||
|
||||
**当前问题设备的直接影响**:设备 `862639076038233` 的套餐(`tb_package_usage.id=1`)需要手动修复(修改 `pending_realname_activation=false`、激活套餐),代码修复仅防止新订单再次陷入同样问题。手动修复套餐后,还需手动触发设备复机(或等待轮询系统下次评估),因为历史停机事件不会被追溯重放。
|
||||
Reference in New Issue
Block a user