# 01 — 后台资产详情统一展示预计最终到期 **What to build:** 运营人员通过统一资产解析查看卡或设备详情时,可以看到全部有效主套餐按稳定队列连续使用后的“预计套餐到期时间”。系统以统一 Query 计算 `exact`、`waiting_activation`、`none`、`invalid_data` 四种状态,并返回预计日期、上海自然日剩余天数和临期派生结果;后台详情按状态展示明确文案,不再把当前套餐自身到期时间当作资产汇总口径。 **Blocked by:** `.scratch/ur55-package-expiry-base/issues/05-activate-and-queue-from-package-snapshots.md` — 05 — 套餐激活与队列接续只消费购买快照 **Status:** done(后端) - [x] 架构主通道为 Query,Infrastructure 仅负责 GORM 批量读取、历史套餐兜底和索引;完整收口预计最终到期的读取与投影边界,不迁移套餐激活、购买、退款或队列接续写逻辑。 - [x] 建立可供单资产和批量资产入口共同调用的纯计算核心;两种入口对同一组使用记录返回完全一致的状态、预计日期、剩余自然日和临期标记,卡、设备及各端不得各自实现推算规则。 - [x] 仅纳入未软删除、仍处于当前或排队生命周期且不属于加油包的主套餐;排除已过期、已失效和已退款记录,并按 `priority ASC, created_at ASC, id ASC` 稳定计算。 - [x] 当前生效主套餐的真实到期时间作为游标起点,后续套餐从前一段结束后的下一时刻接续;自然月和按天时长统一使用项目套餐生命周期日期语义,并以 `Asia/Shanghai` 解释业务自然日。 - [x] 排队记录优先使用各自购买时计时快照;仅允许 UR#55 上线前形成的历史缺失快照记录显式回退套餐当前值,非法队列、非法日期或无法安全解析的快照返回 `invalid_data`,不得伪造日期或降级为 `none`。 - [x] 结果完整区分 `exact`、`waiting_activation`、`none`、`invalid_data`;非 `exact` 时预计日期和剩余天数明确序列化为 `null`,不能省略字段表达状态。 - [x] 剩余天数按上海时区日期差计算,允许普通详情返回负数;仅 `exact` 且剩余 0~15 个自然日时 `is_expiring=true`。 - [x] 后台统一资产解析接口为卡和设备返回预计日期、剩余天数、状态、状态中文名称及临期标记;查询失败向上返回统一错误,不得静默返回 `none`。 - [ ] 后台卡和设备详情统一显示“预计套餐到期时间”:精确日期、待激活后起算、—、数据异常分别对应四种状态;当前套餐自身到期时间只保留在套餐明细中。(前端任务,不纳入后端交付) - [x] 为未软删除主套餐的资产、状态和队列读取建立经开发库 `EXPLAIN ANALYZE` 验证的非唯一或部分索引;索引迁移包含中文注释、可逆向下迁移,代表性查询满足项目性能目标。 - [x] 纯计算测试覆盖无套餐、仅当前套餐、多段队列、自然月、按天、月末、跨年、等待实名激活、历史回退、非法快照、重复优先级、退款、失效、软删除和加油包排除,并明确验证接续边界不多算或少算一天。 - [x] 使用真实开发 PostgreSQL、Redis、JWT 和进程内 Fiber App 完成后台卡/设备详情集成验证;新增、退款或失效排队套餐后无需刷新快照,下一次查询立即返回新结果。 - [x] 补充本功能中文总结文档并同步更新 README;不实现 UR#33 临期列表、Dashboard、提醒,不实现 UR#42 导出,也不维护资产级最终到期快照字段。