# 02 — 套餐商城只展示正常在售套餐

**What to build:** 当前资产所有人查看套餐商城时，只能看到当前销售渠道正常启用、上架且满足既有购买规则的套餐。每个返回项携带统一购买资格字段，下架套餐即使拥有历史续费资格也不会重新进入商城或成为新购入口。

**Blocked by:** 01 — 建立统一套餐可售决策与真实历史资格

**Status:** ready-for-agent

**架构通道:** Query。

**完整业务边界:** 本票只迁移和收口 `GET /api/c/v1/asset/packages` 的读取、权限、批量可售投影与 DTO 契约。明确不提供下架续费入口、不修改订单、不迁移资产信息或套餐历史查询、不经过聚合根。

- [ ] 查询继续执行个人客户认证和当前资产有效绑定校验，无权与资源不存在保持统一安全错误语义。
- [ ] 商城只返回统一策略判定为 `normal` 的套餐，并保持既有系列、赠送套餐、主套餐/加油包、价格、排序和空结果语义。
- [ ] 下架套餐无论是否存在当前资产历史资格都不会出现在商城；套餐全局禁用、代理分配缺失、禁用、软删除或价格异常时也不会返回。
- [ ] 每个正常返回项稳定包含 `can_purchase=true`、`purchase_mode=normal` 和 `disabled_reason=""`，现有套餐 ID、名称、类型、价格及流量字段保持兼容。
- [ ] Query 使用批量读取或等价集合策略解析套餐与代理分配，不在循环中逐项访问数据库，也不把查询结果用于后续写入授权。
- [ ] HTTP 集成测试穿过真实 Fiber 认证、Handler、Query、GORM/PostgreSQL 和统一响应，覆盖平台与代理渠道、下架历史用户、禁用、未授权、价格异常及正常上架新购不回归。
