HaniBlindBox/.kiro/specs/designated-prize-winner/requirements.md
2026-01-31 02:52:42 +08:00

5.0 KiB

Requirements Document

Introduction

指定用户中奖功能允许后台管理员为每个盒子配置"指定用户中奖"规则,使某个奖品只能由指定用户抽中。该功能不修改奖品本身的概率,指定用户仍需按概率抽奖,但非指定用户无法抽中该奖品。

Glossary

  • Goods: 盒子/商品,包含多个奖品的抽奖容器
  • GoodsItem: 奖品,盒子中的单个可抽取物品
  • DesignatedPrize: 指定中奖配置,将特定奖品指定给特定用户
  • LotteryEngine: 抽奖引擎,负责执行抽奖逻辑的核心服务
  • FiniteLottery: 有限赏抽奖,基于库存概率的抽奖模式(一番赏、福袋等),抽完即止
  • InfiniteLottery: 无限赏抽奖,基于固定概率的抽奖模式(无限赏、领主赏等),无限池
  • PrizePool: 奖品池,当前可抽取的奖品集合
  • FallbackMechanism: 兜底机制,当普通奖品池为空时允许普通用户抽取指定奖品

Requirements

Requirement 1: 指定中奖配置数据管理

User Story: As a 后台管理员, I want to 为盒子中的奖品配置指定中奖用户, so that 特定奖品只能被指定用户抽中。

Acceptance Criteria

  1. THE GoodsDesignatedPrize Entity SHALL store goods_id, goods_item_id, user_id, is_active, remark, created_at, and updated_at fields
  2. WHEN a designated prize configuration is created, THE System SHALL enforce that one prize can only be designated to one user per goods (unique constraint on goods_id + goods_item_id)
  3. WHEN a designated prize configuration is queried, THE System SHALL only return active configurations (is_active = true)
  4. THE System SHALL support enabling and disabling designated prize configurations via the is_active field

Requirement 2: 有限赏抽奖流程改造(带兜底机制)

User Story: As a 用户, I want to 在有限赏抽奖时遵循指定中奖规则, so that 指定奖品优先给指定用户,但保证每抽必中。

Acceptance Criteria

  1. WHEN a user draws from a finite lottery, THE LotteryEngine SHALL query designated prize configurations for the goods
  2. WHEN designated prize configurations exist, THE LotteryEngine SHALL separate the prize pool into normal prizes and designated prizes
  3. WHEN the current user is a designated user for any prize, THE LotteryEngine SHALL include that user's designated prizes in their prize pool
  4. WHEN the current user is not a designated user, THE LotteryEngine SHALL exclude designated prizes from their prize pool
  5. IF the normal prize pool is empty (only designated prizes remain), THEN THE LotteryEngine SHALL allow the user to draw from all prizes (fallback mechanism)
  6. WHEN the fallback mechanism is triggered, THE LotteryEngine SHALL log a warning for operational tracking

Requirement 3: 无限赏抽奖流程改造(严格过滤)

User Story: As a 用户, I want to 在无限赏抽奖时遵循指定中奖规则, so that 指定奖品只能被指定用户抽中。

Acceptance Criteria

  1. WHEN a user draws from an infinite lottery, THE LotteryEngine SHALL query designated prize configurations for the goods
  2. WHEN designated prize configurations exist, THE LotteryEngine SHALL strictly filter the prize pool
  3. WHEN a prize has a designated user configuration and the current user is not the designated user, THE LotteryEngine SHALL remove that prize from the pool
  4. WHEN a prize has a designated user configuration and the current user is the designated user, THE LotteryEngine SHALL keep that prize in the pool
  5. THE InfiniteLottery SHALL NOT have a fallback mechanism (designated prizes are strictly protected)

Requirement 4: 后台管理 API

User Story: As a 后台管理员, I want to 通过 API 管理指定中奖配置, so that 我可以灵活配置和调整指定中奖规则。

Acceptance Criteria

  1. WHEN an admin creates a designated prize configuration, THE System SHALL validate that the goods_id, goods_item_id, and user_id exist
  2. WHEN an admin queries designated prize configurations for a goods, THE System SHALL return all configurations with user information
  3. WHEN an admin updates a designated prize configuration, THE System SHALL update the is_active, user_id, or remark fields
  4. WHEN an admin deletes a designated prize configuration, THE System SHALL remove the configuration from the database
  5. IF a duplicate configuration is attempted (same goods_id and goods_item_id), THEN THE System SHALL return an error message

Requirement 5: 概率保持不变

User Story: As a 产品经理, I want to 确保指定中奖不改变奖品概率, so that 抽奖公平性得到保证。

Acceptance Criteria

  1. WHEN calculating prize probabilities, THE LotteryEngine SHALL use the original probability calculation method
  2. THE DesignatedPrize configuration SHALL NOT modify the prize's stock, real_pro, or any probability-related fields
  3. WHEN a designated user draws, THE LotteryEngine SHALL calculate probabilities based on the filtered prize pool