## 1. 数据库迁移

- [x] 1.1 创建迁移文件，为 `tb_shop_package_allocation` 新增 `shelf_status INT NOT NULL DEFAULT 1` 字段，添加字段注释"上架状态 1-上架 2-下架"
- [x] 1.2 执行迁移，确认字段已添加，存量记录 shelf_status 均为 1

## 2. Model 和 Store 层

- [x] 2.1 在 `internal/model/shop_package_allocation.go` 中为 `ShopPackageAllocation` 结构体新增 `ShelfStatus` 字段（gorm tag + json tag）
- [x] 2.2 在 `internal/store/postgres/shop_package_allocation_store.go` 中新增 `UpdateShelfStatus(ctx, id, shelfStatus, updaterID)` 方法
- [x] 2.3 在 `internal/store/postgres/package_allocation_store_interface.go`（或对应接口文件）中更新接口定义，添加 `UpdateShelfStatus` 方法签名

## 3. 分配上下架能力（allocation-shelf-status）

- [x] 3.1 在 `internal/service/shop_package_allocation/service.go` 中新增 `UpdateShelfStatus(ctx, allocationID, shelfStatus)` 方法，实现：套餐禁用时拒绝上架（查 Package.status）、成功则调用 Store 更新
- [x] 3.2 在 `internal/service/shop_package_allocation/service.go` 的 `UpdateStatus()` 方法中加入所有者校验：代理用户需验证 `allocation.allocator_shop_id == caller.shopID`，不匹配则返回 `errors.CodeForbidden`

## 4. 套餐上下架接口角色分流（package-management）

- [x] 4.1 在 `internal/service/package/service.go` 的 `UpdateShelfStatus()` 方法中，增加角色判断：代理用户走分配记录路径（查找并更新 `allocation.shelf_status`），平台/超管走原有套餐路径（更新 `package.shelf_status`）
- [x] 4.2 代理路径需处理：分配记录不存在时返回 "该套餐未分配给您，无法操作上下架"；Package.status=禁用时拒绝上架

## 5. 代理查询套餐响应（agent-available-packages）

- [x] 5.1 在 `internal/service/package/service.go` 的 `toResponse()` 和 `toResponseWithAllocation()` 方法中，代理角色时将响应的 `ShelfStatus` 替换为 `allocation.ShelfStatus`（而非 `package.ShelfStatus`）
- [x] 5.2 确认 `PackageStore.List()` 对代理用户的过滤逻辑：不再按 `package.shelf_status` 过滤（代理看到的套餐不因平台下架而消失），改为代理能看到自己所有已分配（allocation.status=启用）的套餐

## 6. 购买校验逻辑（package-purchase-validation）

- [x] 6.1 在 `internal/service/purchase_validation/service.go` 的套餐状态校验中，增加购买场景判断：代理渠道购买时获取卖家代理的 `allocation.shelf_status` 进行校验，不检查 `package.shelf_status`；平台自营渠道保持检查 `package.shelf_status`
- [x] 6.2 确认 `PurchaseValidationService` 能获取到卖家代理的 shop_id（通过 ctx 或参数传入），并调用 `ShopPackageAllocationStore.GetByShopAndPackage()` 获取 allocation 记录

## 7. DTO 更新

- [x] 7.1 在 `internal/model/dto/shop_package_allocation_dto.go` 中为 `ShopPackageAllocationResponse` 新增 `ShelfStatus` 字段（含 description 标签）
- [x] 7.2 新增 `UpdateShopPackageAllocationShelfStatusRequest` DTO 和对应 Params（包含路由 ID + body），用于 handler 绑定（如未来需要独立路由时备用，当前复用 package 接口的分流即可，此 DTO 可仅用于 service 内部）

## 8. 验证

- [x] 8.1 使用 PostgreSQL MCP 工具确认 `tb_shop_package_allocation` 表含 `shelf_status` 字段，存量数据默认值为 1
- [x] 8.2 调用 `PATCH /api/admin/packages/:id/shelf`（代理身份），验证只更新了 `allocation.shelf_status`，`tb_package.shelf_status` 不变
- [x] 8.3 调用 `PATCH /api/admin/packages/:id/shelf`（平台身份），验证更新了 `tb_package.shelf_status`，allocation 不变
- [x] 8.4 代理下架套餐后，验证另一代理的同一套餐 shelf_status 不受影响
- [x] 8.5 代理下架套餐后，验证其客户下单时购买校验报错"套餐已下架"
- [x] 8.6 平台下架套餐后，验证代理仍可在其列表中看到该套餐（shelf_status 显示代理自己的状态）
- [x] 8.7 验证代理无法修改别人分配给自己的 allocation.status（调用 `PUT /shop-package-allocations/:id/status` 应返回 403）
