## ADDED Requirements

### Requirement: Package Allocation Expiry Base Override Contract

The shop package allocation contract SHALL support an explicit `expiry_base_override` when creating or updating an allocation. The allowed request values MUST be `null`, `from_purchase`, and `from_activation`. The frontend MUST NOT send `from_realname`.

#### Scenario: Create allocation following the package default

- **GIVEN** 用户在套餐授权/分配弹框选择“跟随套餐默认”
- **WHEN** 用户创建店铺套餐分配
- **THEN** 系统 MUST call `POST /api/admin/shop-package-allocations`
- **AND** 请求 MUST explicitly contain `expiry_base_override: null`
- **AND** 系统 MUST NOT omit `expiry_base_override` to represent following the default

#### Scenario: Create allocation with purchase activation override

- **GIVEN** 用户在套餐授权/分配弹框选择“购买即生效”
- **WHEN** 用户创建店铺套餐分配
- **THEN** 请求 MUST contain `expiry_base_override: "from_purchase"`

#### Scenario: Create allocation with activation override

- **GIVEN** 用户在套餐授权/分配弹框选择“实名激活时生效”
- **WHEN** 用户创建店铺套餐分配
- **THEN** 请求 MUST contain `expiry_base_override: "from_activation"`

### Requirement: Package Allocation Expiry Base Update

The system SHALL update an existing package allocation's expiry-base override through `PATCH /api/admin/shop-package-allocations/{id}/expiry-base` with a body containing `expiry_base_override`.

#### Scenario: Update allocation expiry base override

- **GIVEN** 用户正在编辑已分配套餐的生效条件
- **WHEN** 用户选择“购买即生效”或“实名激活时生效”并保存
- **THEN** 系统 MUST call `PATCH /api/admin/shop-package-allocations/{id}/expiry-base`
- **AND** 请求体 MUST contain the selected `expiry_base_override`

#### Scenario: Restore allocation to package default

- **GIVEN** 用户正在编辑已分配套餐的生效条件
- **WHEN** 用户选择“跟随套餐默认”并保存
- **THEN** 请求体 MUST explicitly contain `expiry_base_override: null`

#### Scenario: Use activation override enum

- **GIVEN** 用户在已分配套餐编辑弹框选择“实名激活时生效”
- **WHEN** 用户保存生效条件
- **THEN** 请求体 MUST contain `expiry_base_override: "from_activation"`
- **AND** 请求体 MUST NOT contain `expiry_base_override: "from_realname"`

### Requirement: Package Allocation Expiry Base Resolution Response

The package allocation response SHALL provide `default_expiry_base`, `expiry_base_override`, and `effective_expiry_base`, together with their corresponding Chinese name fields. The frontend MUST render the returned effective value and name without calculating it from other fields.

#### Scenario: Display distinct expiry base values

- **WHEN** 前端加载或更新店铺套餐分配记录
- **THEN** 前端类型 MUST support `default_expiry_base`、`expiry_base_override`、`effective_expiry_base`
- **AND** 前端类型 MUST support the corresponding Chinese name fields
- **AND** 页面 MUST distinguish the default value, override value, and effective value

#### Scenario: Use backend effective expiry base

- **GIVEN** 分配响应同时返回默认值和覆盖值
- **WHEN** 页面展示最终生效条件
- **THEN** 页面 MUST display the backend returned `effective_expiry_base_name`
- **AND** 前端 MUST NOT calculate or replace the effective value from the default value and override value

#### Scenario: Display null override as following package default

- **GIVEN** 分配响应的 `expiry_base_override` 为 `null`
- **WHEN** 页面展示覆盖生效条件
- **THEN** 页面 MUST use `expiry_base_override_name` when it is returned
- **AND** 页面 MUST display “跟随套餐默认” when the returned override name is empty or null

### Requirement: Package Allocation Expiry Base Applies Prospectively

The package allocation expiry-base override SHALL apply only to future new orders. The allocation creation and editing UI MUST inform the user that purchased packages are unaffected.

#### Scenario: Inform user before changing allocation expiry base

- **WHEN** 用户在已分配套餐编辑弹框查看或修改生效条件
- **THEN** 页面 MUST display `仅影响后续新订单，不影响已购买套餐`

#### Scenario: Preserve purchased package behavior

- **WHEN** 用户创建、更新或恢复套餐分配的生效条件
- **THEN** 前端 MUST NOT attempt to update existing purchased packages or historical orders

### Requirement: Package Allocation Response Field Contract

All package allocation and package response objects involved in allocation management SHALL preserve the six expiry-base fields returned by the backend: `default_expiry_base`, `default_expiry_base_name`, `expiry_base_override`, `expiry_base_override_name`, `effective_expiry_base`, and `effective_expiry_base_name`.

#### Scenario: Preserve six expiry-base fields in allocation responses

- **WHEN** 前端接收套餐分配创建、更新、详情或列表响应
- **THEN** 前端类型 MUST support all six expiry-base fields
- **AND** 页面 MUST use backend-provided `*_name` fields for display

#### Scenario: Preserve six expiry-base fields in package responses

- **WHEN** 前端接收套餐列表、套餐详情、套餐创建或套餐更新响应
- **THEN** 前端类型 MUST support all six expiry-base fields when returned by the API
- **AND** 前端 MUST NOT infer allocation effective expiry behavior from package default fields
