Files
junhong_cmp_fiber/openspec/specs/package-traffic-alert/spec.md
break d5bcda94fe feat(套餐真流量预警): AUG26-004 真流量预警规则、达量扫描通知与导出
新增 000228 迁移:规则表 tb_package_traffic_alert_rule(每套餐商品至多一条,无软删除,package_id
非部分唯一约束)、达量预警快照表 tb_package_traffic_alert(以主套餐使用记录 + 阈值快照为唯一键,
触发时冻结用量、额度、比例、阈值、到期时间、归属与资产快照),并为 tb_package_usage 新增扫描
范围部分索引 idx_package_usage_alert_scope;down 在预警表存在数据时阻断回滚。

新增规则维护接口 GET/POST/PUT /api/admin/package-traffic-alert-rules(仅超级管理员与平台账号):
创建校验套餐存在且真流量额度大于零,阈值为 1%~100% 的两位小数;修改只影响后续扫描,不回填也
不改写既有预警快照;全部写操作记录操作者、前后值与时间。

新增每日 06:00(Asia/Shanghai)扫描任务 package:traffic:alert:scan,与套餐临期扫描共用 data_cleanup
队列:按资产汇总当前有效套餐的真流量,分子取使用记录真已用量、分母取使用记录真总量快照,命中
主套餐规则阈值时在同一事务创建预警与可靠通知事件;重复执行以唯一冲突视为已处理,不重复投递,
不建停机锁、不调用运营商。

新增预警列表、详情与异步导出 GET /api/admin/package-traffic-alerts、GET /api/admin/package-traffic-alerts/:id、
POST /api/admin/package-traffic-alerts/export,列表与详情一律读冻结快照;新增通知类型
package.traffic.alert 与受控目标 package_traffic_alert_detail,目标解析仅对超级管理员与平台账号
返回可跳转,越权与不存在统一按资源不可见处理。

同步 OpenAPI(cmd/gendocs、cmd/api/docs.go、pkg/openapi/handlers.go)、审计动作与资源注册、上下文
健康检查证据;归档变更并同步 package-traffic-alert 主 Spec。
2026-09-16 17:05:55 +08:00

95 lines
7.0 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.
# package-traffic-alert Specification
## Purpose
按套餐真实流量和当前有效套餐事实生成一次性达量预警,向资产所属店铺当时有效业务员投递可追溯通知,而不将通道级停复机控制或虚流量混入套餐预警。
## Requirements
### Requirement: 真流量预警规则
系统 SHALL 为每个套餐商品维护至多一条当前真流量预警规则,阈值为 1% 至 100% 的小数百分比。规则启用、修改或降低阈值只影响后续扫描;既有预警 MUST 保留触发时的套餐、阈值、流量和资产快照。规则停用后停止创建新预警;重新启用或降低阈值后,下次扫描发现已有有效套餐达量时必须补建符合条件的预警。
#### Scenario: 降低阈值后补建
- **WHEN** 管理员降低一个启用规则的阈值,下一次扫描发现其有效套餐已达到新阈值
- **THEN** 系统创建预警并冻结新阈值,不修改既有预警快照
#### Scenario: 套餐无真流量额度不可启用
- **WHEN** 管理员为真流量商品额度不大于零的套餐启用规则
- **THEN** 系统拒绝并保持该套餐无有效规则
### Requirement: 有效套餐与汇总口径
系统 SHALL 以同一资产全部当前有效套餐的真流量汇总比例判断达量,比例分子为套餐使用记录真已用量,分母为套餐使用记录真总量快照,并使用该资产主套餐的规则。当前有效套餐 MUST 为 `status IN (1,2) AND refund_id IS NULL` 的使用记录,含加油包;系统 MUST 排除待生效、已过期与已失效记录,且判定过期 MUST 只依据状态,不得仅用到期时间。实际消耗流量的套餐使用记录所关联资产是权威归属;插拔卡时预警同时展示卡与当前关联设备,但 MUST NOT 汇总多张卡。虚流量、展示量、卡级累计与运营商通道累计值 MUST NOT 计入。主套餐 MUST 为 `master_usage_id IS NULL` 的使用记录,存在多条时按优先级、生效时间、编号依次取第一条。
#### Scenario: 多个有效套餐共同达量
- **WHEN** 某资产的多个当前有效套餐真流量汇总达到其主套餐规则阈值
- **THEN** 系统为命中套餐使用记录创建唯一预警,并只向扫描时该资产所属店铺的有效业务员投递通知
#### Scenario: 商品改价后重跑
- **WHEN** 管理员修改套餐商品的当前真流量配置值,同一使用记录被再次扫描
- **THEN** 汇总比例与预警结果不因商品当前值变化
#### Scenario: 已过期或已失效记录不计入
- **WHEN** 资产的某条套餐使用记录状态为已过期或已失效
- **THEN** 系统不将该记录的真已用量与真总量计入汇总
### Requirement: 去重与补建
系统 SHALL 以套餐使用记录和命中阈值快照的组合作为预警唯一键。同一组合 MUST 至多创建一条预警;唯一冲突 MUST 视为已处理且不重复投递通知。降低阈值后对同一使用记录产生新阈值快照的预警 MUST 视为预期补建,不受既有预警阻塞。
#### Scenario: 重复扫描
- **WHEN** 相同套餐使用记录和相同阈值被重复扫描命中
- **THEN** 系统保留原预警和通知,不创建重复记录
### Requirement: 预警通知
系统 SHALL 在预警创建事务内向资产所属店铺当时有效业务员创建站内通知。预警类别 MUST 沿用 `expiry`,并 MUST 注册通知类型 `package.traffic.alert` 的模板定义。有效业务员 MUST 为店铺 `business_owner_account_id` 指向的启用平台账号,系统 MUST NOT 向店铺代理账号补发。无有效业务员时系统 MUST 只保留预警,且 MUST NOT 补发给未来业务员。通知 MUST 幂等,幂等键 MUST 内嵌使用记录与阈值快照,且 MUST 注册指向预警详情的受控目标,不返回 URL。
#### Scenario: 存在有效业务员
- **WHEN** 资产所属店铺在扫描时存在有效业务员
- **THEN** 系统在同一事务创建预警与一条站内通知,通知在账户侧可见、未读数正确并可跳转受控目标
#### Scenario: 无有效业务员
- **WHEN** 资产所属店铺在扫描时无有效业务员
- **THEN** 系统只保存预警,不创建通知且不向未来业务员补发
### Requirement: 预警查询与导出
超级管理员和平台用户 SHALL 在既有资产数据范围内查询和导出预警;先应用既有资产数据范围,该范围当前对超级管理员与平台无实际过滤,保留为冻结语义与未来放开的前置。越权与不存在 MUST 统一按既有的资源不可见处理。导出 MUST 复用既有异步任务并在创建时冻结操作者、筛选、时间范围与可见资产范围,执行期间归属变化 MUST NOT 扩大范围,且 MUST 按触发时间筛选。列表、详情与导出 MUST 返回资产类型、资产标识、对应标识符、卡标识、设备类型、设备型号、套餐名称、真流量已用量、真流量额度、比例、阈值快照、到期时间、剩余天数、触发时间、店铺、业务员、用户组与通知投递结果,且 MUST NOT 包含运营商通道列。导出中套餐、用量、总量、阈值与到期时间 MUST 使用触发快照,店铺、业务员与用户组 MUST 按执行时当前归属补充;预警行仍冻结店铺与业务员快照供列表、详情与追溯,两种口径 MUST NOT 混用;用户组 MUST NOT 写入店铺表,按既有实时推导。
#### Scenario: 受限导出
- **WHEN** 平台用户在其资产数据范围内创建预警导出
- **THEN** 导出仅包含创建时可见预警,即使任务执行期间店铺归属发生变化
#### Scenario: 归属变更后导出
- **WHEN** 预警记录创建后资产所属店铺或业务员变更,再执行已创建导出任务
- **THEN** 套餐、用量、总量、阈值与到期时间仍使用触发快照,店铺、业务员与用户组使用执行时当前归属,且不超出任务创建时冻结的可见范围
#### Scenario: 越权或不存在
- **WHEN** 调用者读取不在其可见范围内的预警详情
- **THEN** 系统按资源不可见处理,不区分越权、不存在与已删除
### Requirement: 与运营商通道阈值分离
系统 SHALL 将本能力与运营商通道阈值控制严格分离。达量预警 MUST NOT 创建停机锁、调用运营商、执行停复机MUST NOT 读取通道计费周期或通道累计流量。
#### Scenario: 达量预警不触发通道动作
- **WHEN** 系统为某资产创建真流量达量预警
- **THEN** 系统不写入任何停机锁、不调用运营商接口且不改变卡停机状态
## 接口
接口:`GET /api/admin/package-traffic-alert-rules`(查询套餐真流量预警规则列表);`POST /api/admin/package-traffic-alert-rules`(创建套餐真流量预警规则);`PUT /api/admin/package-traffic-alert-rules/{id}`(修改套餐真流量预警规则);`GET /api/admin/package-traffic-alerts`(查询套餐真流量达量预警列表);`GET /api/admin/package-traffic-alerts/{id}`(查询套餐真流量达量预警详情);`POST /api/admin/package-traffic-alerts/export`(导出套餐真流量达量预警)。