## Context 当前临期资产查询已统一筛选最终到期可精确推算、剩余 0 至 15 个上海自然日的卡和设备,并在同一投影中计算颜色等级。提醒候选在此结果上再次限定为 15、7、3 天,造成 14、13 至 0 天的大多数日期漏发。 ## Goals / Non-Goals **Goals:** - 让临期窗口内的资产每天产生一次可幂等投递的提醒。 - 保持既有列表范围、颜色等级、通知接收人和 Outbox 投递链路。 **Non-Goals:** - 不修改临期窗口长度、颜色阈值、通知模板、接收人解析或数据库结构。 - 不补写历史漏发日期;上线后的当天扫描按当前剩余天数创建一次提醒。 ## Decisions ### 复用临期列表候选集 提醒候选直接保留统一临期查询返回的全部项目,不再按 15、7、3 天二次筛选。该查询已经排除负天数、超过 15 天和不可精确推算的资产,避免维护第二套范围规则。 备选方案是在提醒查询中复制范围条件;该方案会与列表规则漂移,予以排除。 ### 以既有事件身份实现每日幂等 继续使用包含最终到期日期和剩余天数的事件身份。剩余天数每天变化,因此每日扫描产生当天的一次提醒;同日重试仍命中同一身份,不重复投递。 备选方案是新增扫描日期字段或去重表;现有事件身份已满足每日去重,无需新增持久化事实。 ## Risks / Trade-offs - [通知量从三个节点增加到最多十六天] → 保持当前异步 Outbox 批量投递与接收人幂等。 - [部署前已错过的历史扫描不会自动回补] → 上线后可执行一次手动扫描,生成当天仍在窗口内资产的提醒。 ## Migration Plan 1. 部署 Worker 与 API 代码。 2. 执行一次手动临期扫描,验证窗口内资产生成当天提醒。 3. 回滚时恢复原代码;不涉及 Schema 或数据回滚。