Files
junhong_cmp_fiber/.scratch/ur40-off-shelf-package-renewal/issues/04-package-history-renewal-projection.md
2026-07-22 17:49:25 +09:00

20 lines
2.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 04 — 套餐历史提供下架续费入口
**What to build:** 当前资产所有人查看套餐历史时,每条历史记录都能获得基于当前事实计算的购买资格。待生效、生效中、已用完和已过期套餐均可在符合条件时提供下架续费入口;同一套餐的多条历史记录展示一致决策。
**Blocked by:** 01 — 建立统一套餐可售决策与真实历史资格
**Status:** ready-for-agent
**架构通道:** Query。
**完整业务边界:** 本票只迁移和收口 `GET /api/c/v1/asset/package-history` 的权限、分页、批量可售投影与 DTO 契约。明确不修改套餐使用状态、不把历史行作为写授权、不实现前端页面或跨世代历史续费。
- [ ] 查询继续限定当前资产与当前 generation并保持现有套餐类型、状态筛选、分页、排序和统一错误格式。
- [ ] 每条历史记录增加 `can_purchase``purchase_mode``disabled_reason`,现有 `package_id` 作为续费提交的稳定标识,`package_usage_id` 仅用于展示和追踪。
- [ ] 状态为待生效、生效中、已用完或已过期的真实购买记录均可形成下架续费资格;已过期记录具有可实际消费的 `renew_only` 契约。
- [ ] 同一套餐存在多条历史记录时,各条记录基于套餐级当前购买资格返回相同结果;即使某一行自身已失效,只要同套餐另有有效历史,仍按统一当前决策投影。
- [ ] 套餐当前正常在售时返回 `normal`;当前渠道下架且资格成立时返回 `renew_only`;禁用、无有效历史、未授权或价格异常时返回 `disabled` 和稳定原因。
- [ ] 套餐、渠道分配和历史资格按当前页套餐 ID 批量读取或使用等价集合查询,同套餐复用决策结果,不产生逐行或逐套餐 N+1。
- [ ] PostgreSQL 与 HTTP 集成测试覆盖四种有效历史状态、已失效、软删除、退款撤销、同套餐多记录、不同套餐、不同资产、不同世代、分页筛选及查询次数边界。