## Why 当前套餐价格在后台采购、C 端展示、自动购包和分配记录里口径不一致,`suggested_retail_price` 被直接当成展示价和成交价使用,空配置、旧 0 价和赠送语义也混在一起。现在业务已经明确两件事,普通可售套餐不能显式卖 0,赠送套餐则是独立语义,必须平台专属、仅后端发放,不能再继续靠价格字段临时凑语义。 ## What Changes - feature-001-package-effective-price-fallback:普通可售套餐在建议零售价未配置时,生效售价回退到成本价,覆盖后台采购、C 端展示与下单、自动购包及相关链路。 - feature-002-package-raw-vs-effective-price-view:配置页和编辑页继续展示原始值,销售页和购买页切换为展示生效值,避免把“配置值”和“成交值”混为一谈。 - feature-003-gift-package-independent-semantic:新增赠送套餐独立语义,不再依赖套餐类型去硬解释赠送行为,且必须与价格语义分离。 - feature-004-platform-only-gift-package-policy:赠送套餐仅允许平台侧创建和发放,不能分配给代理,也不能出现在 C 端可购买套餐列表中。 - feature-005-backend-grant-not-self-purchase:赠送加油包只能通过后台发放进入用户资产,不允许用户自购或前台下单获得。 - feature-006-history-and-migration:补齐历史数据与迁移规则,保证存量数据只保留可明确识别的“赠送 0 价”,其余旧 0 一律转为未配置并进入人工复核清单。 - **BREAKING** 价格与赠送语义不再共享同一含义,任何依赖旧口径的列表、下单、分配和展示链路都需要按新规则调整。 ## Capabilities ### New Capabilities - `package-price-policy`:定义普通可售套餐的原始价、生效价、回退规则、展示口径和历史迁移规则。 - `gift-package-policy`:定义赠送套餐的独立语义、平台专属限制、后端发放规则和 C 端可见性规则。 ### Modified Capabilities - `package-management`:套餐配置、编辑和详情页要按原始价与生效价分层展示。 - `package-purchase-validation`:购买校验要使用生效价,并排除赠送套餐的自购路径。 - `client-asset-info`:C 端可购买套餐列表要按生效价展示,并隐藏不可购买的赠送套餐。 - `client-order-purchase`:C 端列表、下单和自动购包要使用生效价,并隐藏不可购买的赠送套餐。 - `agent-series-grant`:套餐授权和发放链路要识别赠送套餐的平台专属属性,禁止向代理分配。 ## Impact - 影响模块:`internal/service/purchase_validation/service.go`、`internal/handler/app/client_asset.go`、`internal/service/client_order/service.go`、`internal/service/order/service.go`、`internal/task/auto_purchase.go`、`internal/service/shop_package_batch_allocation/service.go`、`internal/service/shop_series_grant/service.go`。 - 影响数据:套餐模型、分配记录、历史回填字段和迁移脚本都需要支持原始值、生效值与赠送语义的并存。 - 影响 API:后台套餐管理接口、C 端套餐列表与下单接口、代理授权与平台发放接口都会出现返回值和校验规则变化。 - 影响文档:需要同步更新 OpenSpec、接口文档和字段说明,确保“未配置价格”“赠送 0 价”“平台专属不可分配”三种语义不会再混用。 - 验证方式:实现阶段按项目约束使用手工接口验证和 PostgreSQL 数据核验,不引入新的自动化测试要求。