# My Packages (代理可售套餐) Specification

## ADDED Requirements

### Requirement: 我的可售套餐列表查询

系统 SHALL 提供代理商查询被分配套餐的功能。

#### Scenario: 查询当前代理商的可售套餐

- **WHEN** 代理商用户访问可售套餐页面
- **THEN** 系统显示被分配给该代理商的套餐列表
- **AND** 每个套餐包含：套餐ID、套餐编码、套餐名称、套餐类型、系列信息
- **AND** 显示成本价（cost_price，单位：分）
- **AND** 显示建议售价（suggested_retail_price，单位：分）
- **AND** 显示利润空间（profit_margin = 建议售价 - 成本价）
- **AND** 显示价格来源（series_pricing:系列加价 / package_override:单套餐覆盖）
- **AND** 显示套餐状态和上架状态
- **AND** 支持分页，每页最多100条记录

#### Scenario: 按系列筛选

- **WHEN** 代理商选择特定系列ID筛选
- **THEN** 系统返回该系列下的所有可售套餐

#### Scenario: 按套餐类型筛选

- **WHEN** 代理商选择套餐类型（formal/addon）筛选
- **THEN** 系统返回该类型的所有可售套餐

### Requirement: 可售套餐详情查询

系统 SHALL 允许代理商查看单个可售套餐的详细信息。

#### Scenario: 查询套餐详情

- **WHEN** 代理商点击查看套餐详情
- **THEN** 系统显示套餐完整信息
- **AND** 包含套餐描述、流量信息、时长等
- **AND** 显示定价详情（成本价、建议售价、利润空间、价格来源）
- **AND** 显示系列信息

#### Scenario: 查询未分配的套餐

- **WHEN** 代理商查询未被分配的套餐ID
- **THEN** 系统返回404错误或无权访问错误

### Requirement: 我的被分配系列列表

系统 SHALL 提供代理商查询被分配系列的功能。

#### Scenario: 查询被分配系列列表

- **WHEN** 代理商访问被分配系列列表
- **THEN** 系统显示分配给该代理商的系列列表
- **AND** 每个系列包含：分配ID、系列ID、系列编码、系列名称
- **AND** 显示定价模式（fixed:固定金额 / percent:百分比）
- **AND** 显示定价值（pricing_value）
- **AND** 显示分配者店铺名称
- **AND** 显示可售套餐数量
- **AND** 显示状态
- **AND** 支持分页

### Requirement: 成本价计算规则

系统 SHALL 根据价格来源计算代理商的成本价。

#### Scenario: 系列加价模式（series_pricing）

- **WHEN** 套餐通过系列分配获得定价
- **AND** 定价模式为 fixed（固定金额）
- **THEN** 成本价 = 套餐价格 + 固定加价金额

- **WHEN** 定价模式为 percent（百分比）
- **THEN** 成本价 = 套餐价格 × (1 + 加价百分比)

#### Scenario: 单套餐覆盖模式（package_override）

- **WHEN** 套餐被单独分配并设置了成本价
- **THEN** 成本价 = 单套餐分配中设置的成本价
- **AND** 价格来源显示为 package_override

### Requirement: 数据隔离

系统 SHALL 确保代理商只能查看被分配给自己的套餐。

#### Scenario: 数据访问隔离

- **WHEN** 代理商查询可售套餐列表
- **THEN** 系统仅返回分配给该代理商的套餐
- **AND** 不显示其他代理商的套餐信息

#### Scenario: 跨代理商访问保护

- **WHEN** 代理商尝试访问未分配给自己的套餐详情
- **THEN** 系统返回403无权访问错误

### Requirement: 权限控制

系统 SHALL 对可售套餐查询功能实施权限控制。

#### Scenario: 仅代理商可访问

- **WHEN** 非代理商用户访问可售套餐接口
- **THEN** 系统返回403无权访问错误

#### Scenario: 未认证用户访问

- **WHEN** 未登录用户访问可售套餐接口
- **THEN** 系统返回401未认证错误
