This commit is contained in:
@@ -0,0 +1,17 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 赠送套餐不可纳入代理系列授权
|
||||
|
||||
系统 SHALL 将赠送套餐视为平台专属资产,禁止将其加入代理系列授权、套餐分配或任何下级可见的授权列表。赠送套餐的发放 MUST 走后台发放链路,而不是代理授权链路。
|
||||
|
||||
#### Scenario: 代理创建授权时包含赠送套餐
|
||||
- **WHEN** 代理在系列授权中尝试加入一个赠送套餐
|
||||
- **THEN** 系统返回错误并拒绝创建
|
||||
|
||||
#### Scenario: 平台后台发放赠送套餐
|
||||
- **WHEN** 平台管理员通过后台发放流程授予赠送套餐
|
||||
- **THEN** 系统允许创建发放记录,但不生成代理可分配权限
|
||||
|
||||
#### Scenario: 授权列表隐藏赠送套餐
|
||||
- **WHEN** 系统查询任意代理系列授权的可选套餐列表
|
||||
- **THEN** 赠送套餐 MUST 不出现在列表中
|
||||
@@ -0,0 +1,13 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: B2 可购买套餐列表接口
|
||||
|
||||
系统 SHALL 提供 `GET /api/c/v1/asset/packages?identifier=xxx`,并且 MUST 要求个人客户认证。接口 MUST 在归属校验通过后返回可购买套餐列表。价格规则 MUST 为:代理渠道取分配记录上的生效售价,平台渠道取套餐生效售价。若建议零售价未配置,系统 SHALL 使用成本价作为生效售价。过滤规则 MUST 同时满足:`Package.status=1`、`shelf_status` 可售、加油包前置主套餐条件成立,并且 MUST 排除赠送套餐。结果 MUST 按展示价格升序。响应体 SHALL 包含 `packages[]`,每项至少含 `package_id`、`package_name`、`package_type`、`retail_price`、`cost_price`、`validity`、`is_addon`。错误码/消息 MUST 至少包含:`INVALID_PARAM/参数错误`、`FORBIDDEN/无权限操作该资产或资源不存在`、`PACKAGE_NOT_AVAILABLE/当前无可购买套餐`。
|
||||
|
||||
#### Scenario: 代理渠道价格与过滤生效
|
||||
- **WHEN** 客户查询可购套餐且其销售链路为代理渠道,部分套餐建议零售价未配置
|
||||
- **THEN** 系统仅返回可售且满足价格约束的套餐,并按生效价格升序输出
|
||||
|
||||
#### Scenario: 赠送套餐不出现在可购列表
|
||||
- **WHEN** 赠送套餐已存在于后台数据中
|
||||
- **THEN** C 端可购买套餐列表 MUST 不返回该套餐
|
||||
@@ -0,0 +1,17 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 订单与自动购包价格规则
|
||||
|
||||
系统 SHALL 在既有订单创建和自动购包流程中统一使用生效售价。普通可售套餐若建议零售价未配置,则生效售价 MUST 回退到成本价;赠送套餐 MUST NOT 通过这些自购或自动购包路径创建。
|
||||
|
||||
#### Scenario: 普通可售套餐未配置建议零售价
|
||||
- **WHEN** 订单创建或自动购包处理一个普通可售套餐,且其建议零售价未配置
|
||||
- **THEN** 系统 SHALL 使用成本价作为生效售价
|
||||
|
||||
#### Scenario: 普通可售套餐已配置建议零售价
|
||||
- **WHEN** 订单创建或自动购包处理一个普通可售套餐,且其建议零售价已配置
|
||||
- **THEN** 系统 SHALL 使用已配置的建议零售价作为生效售价
|
||||
|
||||
#### Scenario: 赠送套餐进入购买路径
|
||||
- **WHEN** 任一自购或自动购包路径命中赠送套餐
|
||||
- **THEN** 系统 MUST 拒绝创建订单
|
||||
@@ -0,0 +1,49 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 赠送套餐语义必须显式标记,且 0 价仅用于赠送语义
|
||||
|
||||
系统 MUST 将赠送套餐视为独立业务语义,不能仅通过 `package_type` 推导赠送含义。若套餐显式配置为 0 价,则该 0 价 MUST 仅用于赠送语义。
|
||||
|
||||
#### Scenario: 赠送语义不能仅靠 package_type 推导
|
||||
- **WHEN** 套餐类型为 formal 或 addon,但未显式标记为赠送
|
||||
- **THEN** 系统 MUST NOT 仅凭套餐类型判断其是否为赠送套餐
|
||||
|
||||
#### Scenario: 赠送套餐显式使用 0 价
|
||||
- **WHEN** 平台创建赠送套餐并将建议零售价显式配置为 0
|
||||
- **THEN** 系统 MUST 保留该 0 价配置并将其识别为赠送语义
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 赠送套餐仅限平台侧且不可分配给代理
|
||||
|
||||
系统 SHALL 将赠送套餐限定为平台侧能力。赠送套餐 MUST NOT 被分配给代理,也 MUST NOT 出现在任何代理可操作的套餐授权列表中。
|
||||
|
||||
#### Scenario: 平台可创建赠送套餐
|
||||
- **WHEN** 平台管理员创建赠送套餐
|
||||
- **THEN** 系统允许保存该赠送语义
|
||||
|
||||
#### Scenario: 代理不能分配赠送套餐
|
||||
- **WHEN** 代理尝试将赠送套餐加入自己的授权或分配给下级
|
||||
- **THEN** 系统返回错误并拒绝操作
|
||||
|
||||
#### Scenario: 赠送套餐不进入代理可售列表
|
||||
- **WHEN** 系统生成代理可见的套餐授权列表
|
||||
- **THEN** 赠送套餐 MUST 被过滤掉
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 赠送套餐仅能后台发放,不能前台自购
|
||||
|
||||
系统 SHALL 仅允许通过后台发放流程创建赠送套餐资产。C 端与前台购买路径 MUST NOT 直接购买赠送套餐,且赠送套餐 MUST NOT 出现在 C 端可购买套餐列表中。
|
||||
|
||||
#### Scenario: 后台发放赠送加油包
|
||||
- **WHEN** 平台通过后台发放赠送加油包
|
||||
- **THEN** 系统创建发放记录并授予目标资产
|
||||
|
||||
#### Scenario: C 端不能自购赠送套餐
|
||||
- **WHEN** 个人客户在 C 端尝试购买赠送套餐
|
||||
- **THEN** 系统返回不可购买错误
|
||||
|
||||
#### Scenario: 赠送套餐不出现在 C 端可购列表
|
||||
- **WHEN** C 端请求可购买套餐列表
|
||||
- **THEN** 系统 MUST 不返回任何赠送套餐
|
||||
@@ -0,0 +1,29 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 套餐配置页展示原始价格与价格状态
|
||||
|
||||
系统 SHALL 在套餐创建、编辑、详情接口中返回原始建议成本价、原始建议零售价和价格配置状态。配置页 MUST 以原始值为准展示,不得用生效价覆盖原始值。
|
||||
|
||||
普通可售套餐 MUST NOT 把显式配置的建议零售价 0 作为正常销售路径;该 0 价仅应保留给赠送语义使用。
|
||||
|
||||
#### Scenario: 编辑页展示未配置价格
|
||||
- **WHEN** 管理员打开一个建议零售价未配置的套餐编辑页
|
||||
- **THEN** 页面 SHALL 显示原始建议零售价为空或未配置状态
|
||||
|
||||
#### Scenario: 编辑页展示赠送 0 价
|
||||
- **WHEN** 管理员打开一个已标记为赠送语义且建议零售价显式配置为 0 的套餐编辑页
|
||||
- **THEN** 页面 SHALL 显示原始建议零售价为 0,并同时展示赠送语义与已配置状态
|
||||
|
||||
#### Scenario: 普通可售套餐创建时填写 0 被拒绝
|
||||
- **WHEN** 管理员创建一个普通可售套餐,并将建议零售价填写为 0
|
||||
- **THEN** 系统 SHALL 拒绝保存
|
||||
- **THEN** 系统 SHALL 提示普通可售套餐不允许显式 0
|
||||
|
||||
#### Scenario: 普通可售套餐编辑时改成 0 被拒绝
|
||||
- **WHEN** 管理员编辑一个普通可售套餐,并将原建议零售价修改为 0
|
||||
- **THEN** 系统 SHALL 拒绝保存
|
||||
- **THEN** 系统 SHALL 保持原有价格状态不变
|
||||
|
||||
#### Scenario: 详情页不回填生效价
|
||||
- **WHEN** 管理员查看套餐详情
|
||||
- **THEN** 系统 SHALL 返回原始价格字段,而不是把回退后的生效价写回原始字段
|
||||
@@ -0,0 +1,57 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 价格配置状态与原始值分离
|
||||
|
||||
系统 MUST 同时保存套餐价格的原始配置值和价格配置状态,且 MUST 区分以下三种语义:未配置、赠送 0、已配置为非 0。普通可售套餐 MUST NOT 显式配置 0 作为售卖价,0 仅可用于赠送语义。配置页与编辑页 SHALL 展示原始值,不能用生效价覆盖原始值。
|
||||
|
||||
#### Scenario: 未配置价格与 0 价必须可区分
|
||||
- **WHEN** 管理员创建两个套餐,一个建议零售价未配置,一个已被标记为赠送且建议零售价显式配置为 0
|
||||
- **THEN** 系统 MUST 为两者保存不同的价格配置状态
|
||||
- **THEN** 系统 MUST NOT 仅依赖数值 0 判断价格是否已配置
|
||||
|
||||
#### Scenario: 普通可售套餐显式 0 被拒绝
|
||||
- **WHEN** 管理员创建或编辑一个普通可售套餐,并将建议零售价填写为 0
|
||||
- **THEN** 系统 MUST 拒绝保存
|
||||
- **THEN** 系统 MUST 返回普通可售套餐不允许显式 0 的错误
|
||||
|
||||
#### Scenario: 配置页展示原始值
|
||||
- **WHEN** 管理员进入套餐详情或编辑页
|
||||
- **THEN** 页面 SHALL 展示原始建议成本价和原始建议零售价
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 普通可售套餐的生效售价回退
|
||||
|
||||
系统 SHALL 对普通可售套餐计算生效售价。若建议零售价未配置,生效售价 MUST 回退为成本价。该规则 MUST 适用于后台采购、C 端展示与下单、自动购包以及所有依赖套餐成交价的链路。
|
||||
|
||||
#### Scenario: 建议零售价未配置时回退到成本价
|
||||
- **WHEN** 普通可售套餐的建议零售价未配置,成本价为 8000 分
|
||||
- **THEN** 系统返回的生效售价 MUST 为 8000 分
|
||||
|
||||
#### Scenario: 建议零售价已配置时保持原值
|
||||
- **WHEN** 普通可售套餐的建议零售价已配置为 12000 分,成本价为 8000 分
|
||||
- **THEN** 系统返回的生效售价 MUST 为 12000 分
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 历史数据回填与迁移
|
||||
|
||||
系统 MUST 对存量套餐、分配记录和订单相关价格快照执行迁移回填,补齐价格配置状态和生效价字段。迁移后,只有能被正向识别为赠送 0 的记录才保留为赠送 0,其余历史 0 数据 MUST 转为未配置并进入人工复核清单。
|
||||
|
||||
#### Scenario: 存量未配置价格被回填为未配置状态
|
||||
- **WHEN** 迁移执行前某套餐历史上从未配置过建议零售价
|
||||
- **THEN** 迁移后该套餐 MUST 保持未配置状态
|
||||
- **THEN** 其生效售价 MUST 按成本价回填
|
||||
|
||||
#### Scenario: 正向识别的赠送 0 被保留
|
||||
- **WHEN** 迁移执行前某套餐的建议零售价为 0,且历史记录能明确证明其为赠送语义
|
||||
- **THEN** 迁移后系统 MUST 保留赠送 0 状态
|
||||
|
||||
#### Scenario: 模糊旧 0 转为未配置并进入人工复核
|
||||
- **WHEN** 迁移执行前某套餐的建议零售价为 0,但历史记录无法明确证明其为赠送语义
|
||||
- **THEN** 迁移后系统 MUST 将其转为未配置状态
|
||||
- **THEN** 系统 MUST 将该记录加入人工复核清单
|
||||
|
||||
#### Scenario: 历史快照按生效价展示
|
||||
- **WHEN** 用户查询历史订单或历史分配记录
|
||||
- **THEN** 系统 SHALL 使用迁移后的生效价字段进行展示
|
||||
@@ -0,0 +1,48 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 获取购买价格
|
||||
|
||||
系统 MUST 根据买家身份返回正确的购买价格,并且 MUST 使用生效售价,不得直接把未配置的建议零售价当成交价返回。个人客户、平台自营和自动购包路径 SHALL 以套餐生效售价为准;代理为店铺购买时 SHALL 以分配记录上的生效售价为准。
|
||||
|
||||
#### Scenario: 个人客户购买
|
||||
- **WHEN** 个人客户购买一个普通可售套餐,且建议零售价未配置
|
||||
- **THEN** 系统 SHALL 返回回退后的生效售价,金额等于成本价
|
||||
|
||||
#### Scenario: 代理为店铺购买
|
||||
- **WHEN** 代理为自己店铺购买套餐
|
||||
- **THEN** 系统 SHALL 返回该分配记录对应的生效售价
|
||||
|
||||
---
|
||||
|
||||
### Requirement: validatePackages() 价格累加与展示校验
|
||||
|
||||
系统 MUST 在 `validatePackages()` 中按渠道来源使用一致的生效售价进行累加计算,并在代理渠道保持价格展示可见性校验。未配置建议零售价时,累计金额 MUST 使用回退后的生效售价,而不是原始空值。
|
||||
|
||||
#### Scenario: 代理渠道累加使用生效售价
|
||||
- **WHEN** `validatePackages()` 处理代理渠道的多套餐下单
|
||||
- **THEN** 总价累加 MUST 基于各套餐的生效售价
|
||||
|
||||
#### Scenario: 平台渠道累加使用生效售价
|
||||
- **WHEN** `validatePackages()` 处理平台渠道的多套餐下单
|
||||
- **THEN** 总价累加 MUST 基于各套餐的生效售价
|
||||
|
||||
#### Scenario: 未配置价格不再触发错误展示
|
||||
- **WHEN** 某个普通可售套餐的建议零售价未配置
|
||||
- **THEN** 系统 SHALL 使用回退后的生效售价继续校验
|
||||
- **THEN** 系统 MUST NOT 因原始建议零售价为空而把该套餐当成异常价格直接拦截
|
||||
|
||||
---
|
||||
|
||||
### Requirement: 赠送套餐禁止进入自购下单
|
||||
|
||||
系统 SHALL 拒绝任何用户通过自购路径购买赠送套餐。赠送加油包只能通过后台发放进入资产,不能通过 C 端或后台自助下单购买。
|
||||
|
||||
赠送场景 SHALL 仅允许使用显式配置的建议零售价 0,但该 0 价仅表示赠送语义,不能作为普通可售套餐的正常销售路径。
|
||||
|
||||
#### Scenario: C 端自购赠送套餐被拦截
|
||||
- **WHEN** 个人客户尝试购买一个启用赠送语义的套餐
|
||||
- **THEN** 系统返回不可购买错误,订单不创建
|
||||
|
||||
#### Scenario: 后台自助下单赠送套餐被拦截
|
||||
- **WHEN** 后台操作者尝试通过普通购买接口创建赠送套餐订单
|
||||
- **THEN** 系统 MUST 拒绝该订单
|
||||
Reference in New Issue
Block a user