diff --git a/.scratch/ur55-package-expiry-base/issues/01-create-allocation-expiry-base-override.md b/.scratch/ur55-package-expiry-base/issues/01-create-allocation-expiry-base-override.md index 9bd29c0..e1ca443 100644 --- a/.scratch/ur55-package-expiry-base/issues/01-create-allocation-expiry-base-override.md +++ b/.scratch/ur55-package-expiry-base/issues/01-create-allocation-expiry-base-override.md @@ -6,12 +6,11 @@ **Status:** ready-for-agent -- [ ] 架构主通道为简单写,读取投影使用 Query 或现有只读门面;完整收口创建分配时解析和保存覆盖值的业务边界,不迁移套餐管理 CRUD、价格、佣金或历史购买记录。 -- [ ] 数据库迁移为套餐分配增加可空的生效条件覆盖字段,`NULL` 明确表示跟随套餐当前默认值,并包含中文字段注释及可逆的向下迁移。 -- [ ] 系列首次授权、系列后续追加套餐和批量套餐分配均要求显式提交同一个覆盖选择,并写入本次创建的每条分配;跟随默认必须提交 JSON `null`,不能依靠省略字段表达。 -- [ ] 仅接受 `null`、`from_purchase`、`from_activation`,非法值或字段缺失统一返回参数错误,DTO 枚举说明与套餐常量原文一致。 -- [ ] 分配列表、详情及创建结果返回默认值、覆盖值、最终有效值及其中文名称;最终有效值由后端计算,前端不得自行合并。 -- [ ] 任一套餐不存在、跨系列、越权、不可授权或写入失败时整批回滚,不产生部分系列授权、套餐分配或成功副作用。 +- [x] 架构主通道为简单写,读取投影使用 Query 或现有只读门面;完整收口创建分配时解析和保存覆盖值的业务边界,不迁移套餐管理 CRUD、价格、佣金或历史购买记录。 +- [x] 数据库迁移为套餐分配增加可空的生效条件覆盖字段,`NULL` 明确表示跟随套餐当前默认值,并包含中文字段注释及可逆的向下迁移。 +- [x] 系列首次授权、系列后续追加套餐和批量套餐分配均要求显式提交同一个覆盖选择,并写入本次创建的每条分配;跟随默认必须提交 JSON `null`,不能依靠省略字段表达。 +- [x] 仅接受 `null`、`from_purchase`、`from_activation`,非法值或字段缺失统一返回参数错误,DTO 枚举说明与套餐常量原文一致。 +- [x] 分配列表、详情及创建结果返回默认值、覆盖值、最终有效值及其中文名称;最终有效值由后端计算,前端不得自行合并。 +- [x] 任一套餐不存在、跨系列、越权、不可授权或写入失败时整批回滚,不产生部分系列授权、套餐分配或成功副作用。 - [ ] 后台分配表单提供“跟随套餐默认、购买即生效、实名即生效”三个选项,并正确发送显式 `null`。 - [ ] HTTP 集成测试覆盖全部创建入口、三个选择、整批一致性、字段缺失、非法枚举、越权及事务回滚;前端验收列表和详情的默认值、覆盖值、最终值显示一致。 - diff --git a/.scratch/ur55-package-expiry-base/issues/02-update-allocation-expiry-base-override.md b/.scratch/ur55-package-expiry-base/issues/02-update-allocation-expiry-base-override.md index 9a8277f..4c8c355 100644 --- a/.scratch/ur55-package-expiry-base/issues/02-update-allocation-expiry-base-override.md +++ b/.scratch/ur55-package-expiry-base/issues/02-update-allocation-expiry-base-override.md @@ -6,13 +6,12 @@ **Status:** ready-for-agent -- [ ] 架构主通道为简单写,读取投影使用 Query 或现有只读门面;完整收口单条分配覆盖值修改,不扩展为批量修改或迁移套餐默认配置接口。 -- [ ] 提供修改单条套餐分配生效条件覆盖的后台 PATCH 接口,请求必须包含覆盖字段,并能区分字段缺失与显式 JSON `null`。 -- [ ] 接口仅接受 `null`、`from_purchase`、`from_activation`;`null` 恢复跟随默认,非法值和字段缺失统一返回参数错误。 -- [ ] 分配不存在、已软删除或越权时遵守统一防越权错误语义,不向调用方区分无权限与资源不存在。 -- [ ] 重复提交当前值按幂等成功处理,不修改已有套餐使用记录,也不产生与实际变更不符的业务副作用。 -- [ ] 修改成功后响应或重新查询结果包含默认值、覆盖值、最终有效值及其中文名称,最终值始终由后端计算。 -- [ ] 敏感配置变更写入统一审计,记录操作人、变更前后覆盖值及分配标识,但不把底层错误或无权资源信息暴露给客户端。 +- [x] 架构主通道为简单写,读取投影使用 Query 或现有只读门面;完整收口单条分配覆盖值修改,不扩展为批量修改或迁移套餐默认配置接口。 +- [x] 提供修改单条套餐分配生效条件覆盖的后台 PATCH 接口,请求必须包含覆盖字段,并能区分字段缺失与显式 JSON `null`。 +- [x] 接口仅接受 `null`、`from_purchase`、`from_activation`;`null` 恢复跟随默认,非法值和字段缺失统一返回参数错误。 +- [x] 分配不存在、已软删除或越权时遵守统一防越权错误语义,不向调用方区分无权限与资源不存在。 +- [x] 重复提交当前值按幂等成功处理,不修改已有套餐使用记录,也不产生与实际变更不符的业务副作用。 +- [x] 修改成功后响应或重新查询结果包含默认值、覆盖值、最终有效值及其中文名称,最终值始终由后端计算。 +- [x] 敏感配置变更写入统一审计,记录操作人、变更前后覆盖值及分配标识,但不把底层错误或无权资源信息暴露给客户端。 - [ ] 前端编辑区域显示“仅影响后续新订单,不影响已购买套餐”,成功后重新拉取分配详情,不在本地推导最终有效值。 -- [ ] HTTP 集成测试覆盖两个覆盖值、显式恢复默认、字段缺失、非法值、不存在、软删除、越权、重复 PATCH 幂等及已购买记录不变。 - +- [x] HTTP 集成测试覆盖两个覆盖值、显式恢复默认、字段缺失、非法值、不存在、软删除、越权、重复 PATCH 幂等及已购买记录不变。 diff --git a/.scratch/ur55-package-expiry-base/issues/04-snapshot-auto-purchase-package-usages.md b/.scratch/ur55-package-expiry-base/issues/04-snapshot-auto-purchase-package-usages.md index c037120..11ccad0 100644 --- a/.scratch/ur55-package-expiry-base/issues/04-snapshot-auto-purchase-package-usages.md +++ b/.scratch/ur55-package-expiry-base/issues/04-snapshot-auto-purchase-package-usages.md @@ -6,12 +6,11 @@ **Status:** ready-for-agent -- [ ] 架构主通道为复杂写,Application 通过 Port/Adapter 编排自动任务和持久化;只迁移自动购包形成套餐使用记录的完整用例,不迁移其调度、定价、支付或其他订单规则。 -- [ ] 自动购包创建主套餐和加油包时调用与同步购买相同的计时条款解析能力,不再自行读取套餐当前生效条件和时长决定使用记录语义。 -- [ ] 自动任务能够解析对应代理分配的覆盖值;无覆盖时使用套餐默认值,并为每条新使用记录写入四个非空、有效的计时快照。 -- [ ] 使用记录及其快照在同一业务事务提交,任一步骤失败均不留下部分订单、部分主套餐、部分加油包或空快照记录。 -- [ ] 重复任务和并发消费依赖数据库业务幂等事实或状态条件,不以 Redis 锁代替权威幂等;同一业务只生成一组套餐使用记录。 -- [ ] 队列载荷使用结构体或 map,不向统一入队能力传入预序列化字节。 -- [ ] 新自动购包记录无法生成完整快照时明确失败并记录中文上下文日志,不允许静默使用历史兼容回退。 +- [x] 架构主通道为复杂写,Application 通过 Port/Adapter 编排自动任务和持久化;只迁移自动购包形成套餐使用记录的完整用例,不迁移其调度、定价、支付或其他订单规则。 +- [x] 自动购包创建主套餐和加油包时调用与同步购买相同的计时条款解析能力,不再自行读取套餐当前生效条件和时长决定使用记录语义。 +- [x] 自动任务能够解析对应代理分配的覆盖值;无覆盖时使用套餐默认值,并为每条新使用记录写入四个非空、有效的计时快照。 +- [x] 使用记录及其快照在同一业务事务提交,任一步骤失败均不留下部分订单、部分主套餐、部分加油包或空快照记录。 +- [x] 重复任务和并发消费依赖数据库业务幂等事实或状态条件,不以 Redis 锁代替权威幂等;同一业务只生成一组套餐使用记录。 +- [x] 队列载荷使用结构体或 map,不向统一入队能力传入预序列化字节。 +- [x] 新自动购包记录无法生成完整快照时明确失败并记录中文上下文日志,不允许静默使用历史兼容回退。 - [ ] 自动任务集成测试覆盖两个生效条件、跟随默认、主套餐、加油包、重复消费、并发、事务中途失败和购买后配置变化不修改快照。 - diff --git a/.scratch/ur55-package-expiry-base/issues/05-activate-and-queue-from-package-snapshots.md b/.scratch/ur55-package-expiry-base/issues/05-activate-and-queue-from-package-snapshots.md index cd0e725..a4aecd7 100644 --- a/.scratch/ur55-package-expiry-base/issues/05-activate-and-queue-from-package-snapshots.md +++ b/.scratch/ur55-package-expiry-base/issues/05-activate-and-queue-from-package-snapshots.md @@ -9,13 +9,13 @@ **Status:** ready-for-agent -- [ ] 架构主通道为复杂写,Infrastructure 负责历史数据读取和可观测设施;完整收口套餐激活与接续用例,不实现 UR#46 最终到期展示、UR#33 临期能力或未触碰的套餐管理 CRUD。 -- [ ] 首次激活、实名后激活、前一主套餐到期后的排队接续和退款后的接续,共享同一套餐生命周期规则,并只从使用记录快照读取生效条件、周期类型、月数和天数。 -- [ ] `from_purchase` 与 `from_activation` 的起算语义由使用记录快照决定;购买后修改套餐默认值、周期、时长或分配覆盖,不改变已有记录的激活时间、到期计算或队列接续结果。 -- [ ] 正式主套餐和加油包的激活均消费各自快照;加油包继续遵守既有主套餐关联规则,不借本票改变其生命周期范围。 -- [ ] 仅 UR#55 上线前形成且快照缺失的历史记录允许显式回退套餐当前值;每次回退都记录可定位使用记录的结构化告警和指标。 -- [ ] UR#55 上线后形成的新记录缺少或包含非法快照时,必须拒绝或标记异常并告警,不得静默进入历史回退路径。 -- [ ] 移除触碰用例中直接读取套餐当前 `expiry_base`、周期或时长的生产分支;不得保留“行业卡永远直接激活”等绕过统一实名规则的特殊判断。 -- [ ] 重复激活和重复接续通过状态条件保证幂等;事务失败不会留下部分状态、错误到期时间或重复激活下一套餐。 +- [x] 架构主通道为复杂写,Infrastructure 负责历史数据读取和可观测设施;完整收口套餐激活与接续用例,不实现 UR#46 最终到期展示、UR#33 临期能力或未触碰的套餐管理 CRUD。 +- [x] 首次激活、实名后激活、前一主套餐到期后的排队接续和退款后的接续,共享同一套餐生命周期规则,并只从使用记录快照读取生效条件、周期类型、月数和天数。 +- [x] `from_purchase` 与 `from_activation` 的起算语义由使用记录快照决定;购买后修改套餐默认值、周期、时长或分配覆盖,不改变已有记录的激活时间、到期计算或队列接续结果。 +- [x] 正式主套餐和加油包的激活均消费各自快照;加油包继续遵守既有主套餐关联规则,不借本票改变其生命周期范围。 +- [x] 仅 UR#55 上线前形成且快照缺失的历史记录允许显式回退套餐当前值;每次回退都记录可定位使用记录的结构化告警和指标。 +- [x] UR#55 上线后形成的新记录缺少或包含非法快照时,必须拒绝或标记异常并告警,不得静默进入历史回退路径。 +- [x] 移除触碰用例中直接读取套餐当前 `expiry_base`、周期或时长的生产分支;不得保留“行业卡永远直接激活”等绕过统一实名规则的特殊判断。 +- [x] 重复激活和重复接续通过状态条件保证幂等;事务失败不会留下部分状态、错误到期时间或重复激活下一套餐。 - [ ] 领域与集成测试覆盖首次购买即生效、等待实名后生效、连续排队、退款接续、历史回退、新记录缺失快照、重复执行及购买后修改全部相关配置。 - [ ] 发布验证遵循“兼容读取应用先就绪,再执行迁移并在同一维护窗口切换所有写入路径”;窗口结束后确认没有新增空快照,并能观测历史回退数量。