All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 10m49s
33 lines
3.5 KiB
Markdown
33 lines
3.5 KiB
Markdown
## Context
|
||
|
||
个人客户通知已有隔离、已读和投递能力,物流换货已有状态机。弹窗配置不能替代通知事实,风险换卡不能另建待处理记录。
|
||
|
||
## Decisions
|
||
|
||
- 新增运营弹窗配置及版本/投放去重事实;候选查询在同一资产上下文计算风险优先级和配置匹配,创建/复用个人通知。
|
||
- 风险地址提交以客户+旧资产唯一约束和事务创建物流换货单,地址写入换货单而不单独建表。
|
||
- 频率去重使用客户、配置版本、资产/日期键;通知内容冻结在投放时,已读复用现有服务。
|
||
- 后台仅管理配置,不得写任意 URL;H5 只接收受控目标类型。
|
||
|
||
## 后台与 H5 动作契约
|
||
|
||
### 运营弹窗配置
|
||
|
||
- `POST /h5-popup-configurations`:仅超级管理员、平台用户。请求 `title`(1~100 字符)、`content`(1~2000 字符)、`starts_at`、`ends_at`、`enabled`、`priority`、`pages`(首页/资产详情/套餐购买/资产钱包充值)、可选店铺/设备类型/卡类型集合、`frequency`(`once`/`daily`)和可选 `action_type`(`package_purchase`/`asset_wallet_recharge`)。结束时间不得早于开始时间;不接受 URL、前端路由或任意动作参数。
|
||
- `PUT /h5-popup-configurations/:id` 更新时递增配置版本;旧版本通知不改写。`POST /:id/enable`、`/disable` 仅影响后续候选;全部成功写操作记录操作者、前后值、版本和时间。
|
||
|
||
### H5 候选查询与风险换卡
|
||
|
||
- `GET /api/c/v1/popup-candidates`:当前个人客户必须提交 `page` 和当前资产标识;首页也必须先由客户选定当前资产。服务校验该资产属于当前客户或其既有授权范围,否则按资源不可见返回。
|
||
- 查询先判断广电卡、运营商扩展状态风险停机、无活动物流换货单、未提交风险地址和“客户+资产+上海自然日”未展示;命中时创建/复用风险通知并只返回风险换卡候选。关闭或稍后处理只调用既有通知已读,不修改风险资格,次日允许再次投放。
|
||
- 未命中风险时,按当前时间、启用状态、页面、店铺/设备类型/卡类型范围和频率匹配运营配置;同维度多值取任一命中,无配置即全量。只返回优先级最高一条,同优先级取最近更新时间;以客户、配置版本、资产、日期/一次性键创建或复用通知。
|
||
|
||
### 风险地址提交与通知读取
|
||
|
||
- `POST /api/c/v1/risk-exchanges/:asset_id/address`:当前个人客户提交 `recipient_name`、`recipient_phone`、`recipient_address`;均必填且沿用既有换货地址字段长度校验。事务中锁定客户和旧资产,复核风险资格,以客户+旧资产唯一约束创建物流换货单,`migrate_data=false`;重复提交返回首次创建的换货单与首次地址,禁止覆盖。
|
||
- 弹窗通知内容、配置版本、资产和受控动作在投放时冻结并写个人站内通知,保留 90 天。候选查询不标记已读;关闭、点击受控操作、进入通知详情仅通过既有 `PUT /api/c/v1/notifications/:id/read` 幂等标记当前客户自己的通知。
|
||
- 通知受控操作只返回类型与资产关联,不返回 URL;前端按白名单映射页面。客户读取他人通知或不属于其资产的风险换卡均按既有隔离规则不可见。
|
||
|
||
## Migration Plan
|
||
|
||
新增成对迁移和索引;隔离库验证风险条件、每日限制、地址幂等、优先级、版本重投、范围匹配、通知隔离及 up/down/up。 |