Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
3.1 KiB
3.1 KiB
MODIFIED Requirements
Requirement: 同时只能有一个生效中的主套餐
系统 SHALL 确保载体(设备/卡)同一时刻只能有一个 package_type=formal 且 status=1 的套餐。
到期检测扩展:过期检测 SHALL 同时覆盖 status=1(生效中)和 status=2(已耗尽)的主套餐。当 expires_at <= now 时,无论套餐当前是生效中还是已耗尽,均视为到期,触发下一个排队套餐激活。
数据一致性保证:
- 购买时检查:查询
WHERE (iot_card_id/device_id)=? AND status=1 AND master_usage_id IS NULL - 并发控制:使用数据库事务避免并发插入多个生效中主套餐
- 激活时二次检查:激活前再次查询是否有生效中主套餐,避免并发激活
Scenario: 首次购买主套餐立即生效
- GIVEN 载体无任何主套餐记录
- WHEN 用户购买主套餐并支付成功
- THEN 系统创建 PackageUsage:
status=1,priority=1,activated_at=支付完成时间,expires_at=根据 calendar_type 计算,master_usage_id=NULL
Scenario: 购买第二个主套餐自动排队
- GIVEN 载体已有 1 个生效中的主套餐(
priority=1,status=1) - WHEN 用户购买第 2 个主套餐
- THEN 系统创建 PackageUsage:
status=0,priority=2,无activated_at和expires_at
Scenario: 生效中主套餐到期触发下一个激活
- GIVEN 卡 C1 有生效中主套餐(
status=1,expires_at=过去时间)和一个排队套餐(status=0) - WHEN 过期检测任务扫描到该套餐
- THEN 生效中套餐更新为
status=3 Expired,加油包级联失效,下一个排队套餐激活为status=1 - AND 如卡因流量耗尽停机(
stop_reason=traffic_exhausted)且已实名,触发自动复机
Scenario: 已耗尽(Depleted)主套餐到期后触发下一个激活
- GIVEN 卡 C2 有已耗尽主套餐(
status=2 Depleted,expires_at=过去时间)和一个预购排队套餐(status=0) - WHEN 过期检测任务扫描(查询条件:
status IN (1,2) AND expires_at <= now AND master_usage_id IS NULL) - THEN 耗尽套餐更新为
status=3 Expired,加油包级联失效,预购排队套餐激活为status=1 - AND 如卡因流量耗尽停机且已实名,触发自动复机
Scenario: 已耗尽套餐到期时加油包级联失效
- GIVEN 卡 C3 有耗尽主套餐(
status=2,expires_at=过去时间),以及绑定到该主套餐的 1 个加油包(status=1,尚有剩余流量) - WHEN 过期检测任务处理该主套餐
- THEN 主套餐更新为
status=3,加油包更新为status=4 Invalidated(即使尚有剩余流量) - AND 下一个排队主套餐激活
Scenario: 已耗尽套餐到期且无下一个排队套餐
- GIVEN 卡 C4 有耗尽主套餐(
status=2,expires_at=过去时间),无排队套餐 - WHEN 过期检测任务处理该主套餐
- THEN 耗尽套餐更新为
status=3,加油包级联失效,无新套餐激活 - AND 卡的业务状态更新为
IotCardStatusSuspended=4(已停用)