归档
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-08-13
|
||||
@@ -0,0 +1,46 @@
|
||||
## Context
|
||||
|
||||
资金概况列表当前由请求 DTO 绑定查询参数,Handler 将请求交给只读 Query;Query 先通过统一中间件给店铺表附加当前账号的数据范围,再应用店铺名称和主账号用户名条件。路由元数据直接引用该请求 DTO 生成 OpenAPI。行为目标见 proposal 与 delta spec。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- 在既有只读查询链路中增加类型安全的店铺 ID 精确筛选。
|
||||
- 保持数据权限优先且所有筛选条件采用交集语义。
|
||||
- 让无效参数在 HTTP 边界被查询参数解析和显式正整数校验拒绝,并在 OpenAPI 中体现正整数约束。
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- 不改变分页默认值、排序、响应结构或资金投影计算。
|
||||
- 不新增按多个店铺 ID 检索,也不改变店铺名称和主账号用户名的模糊检索语义。
|
||||
- 不修改数据库 Schema、索引、路由或 Handler 装配。
|
||||
|
||||
## Decisions
|
||||
|
||||
### 使用可选指针表达查询参数
|
||||
|
||||
在资金概况请求 DTO 中将 `shop_id` 建模为 `*uint`,并声明 `omitempty,min=1` 与 OpenAPI 最小值。指针能区分“未提供”和具体值,符合仓库其他列表筛选 DTO 的既有模式。由于当前 Handler 不执行 DTO validator,查询参数无法解析时沿用 `QueryParser` 错误,成功解析为零时在 Handler 内显式返回参数错误。
|
||||
|
||||
替代方案是使用 `uint` 的零值表示未提供,但这会弱化缺省与显式非法值的区分,不利于稳定执行正整数校验。
|
||||
|
||||
### 在既有筛选函数中叠加主表精确条件
|
||||
|
||||
在数据权限条件已经附加到店铺查询后,为非空 `shop_id` 增加店铺主键等值条件。该方式让 ID、名称、用户名和权限条件自然以 SQL `AND` 组合,并继续复用同一个查询对象完成总数与分页数据读取。
|
||||
|
||||
替代方案是在 Handler 或 Query 中先按 ID 单独查询店铺,但会产生额外数据库访问,并可能通过“不存在”和“无权限”的不同错误泄露资源存在性。
|
||||
|
||||
### 复用请求 DTO 自动更新 OpenAPI
|
||||
|
||||
路由 RouteSpec 已引用资金概况请求 DTO,因此实现只需重新运行现有文档生成入口,无需新增路由或修改两套 Handler 占位装配。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Fiber 查询参数绑定对负数到无符号整数的错误表现依赖现有解析器] → 对解析错误使用现有统一参数错误映射,对解析成功的零值显式校验,并通过接口 smoke 覆盖零、负数和非数字输入。
|
||||
- [筛选条件书写时若使用未限定列名,未来联表可能产生歧义] → 对店铺主键使用当前主表列名,保持条件明确。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. 发布 DTO、Query 和重新生成的 OpenAPI 文档;无需数据库迁移。
|
||||
2. 通过构建、OpenSpec 校验及隔离环境接口 smoke 验证新增和兼容场景。
|
||||
3. 回滚时恢复相关代码与生成文档即可,不涉及数据恢复。
|
||||
@@ -0,0 +1,26 @@
|
||||
## Why
|
||||
|
||||
后台代理商资金概况列表目前只能按店铺名称或主账号用户名检索,运营人员已知店铺 ID 时无法直接定位目标记录。新增店铺 ID 精确筛选可减少歧义,同时继续受现有店铺数据权限约束。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 为 `GET /api/admin/shops/fund-summary` 增加可选的 `shop_id` 查询参数,参数为正整数。
|
||||
- 提供 `shop_id` 时按店铺 ID 精确筛选,并与现有店铺名称、主账号用户名筛选条件及当前账号店铺数据范围取交集。
|
||||
- 无匹配或目标不在当前数据范围时返回空分页结果,不暴露店铺是否存在。
|
||||
- 同步生成的 OpenAPI 查询参数说明。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
无。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `agent-funds-commission`: 扩展代理商资金概况列表的可观察检索行为,支持在数据权限范围内按店铺 ID 精确筛选。
|
||||
|
||||
## Impact
|
||||
|
||||
- API:`GET /api/admin/shops/fund-summary` 新增兼容性的可选查询参数 `shop_id`。
|
||||
- 代码:影响资金概况请求 DTO 与 `internal/query/shop` 的只读筛选逻辑。
|
||||
- 文档:重新生成 OpenAPI;无需修改路由、Handler 装配、数据库 Schema 或外部集成。
|
||||
@@ -0,0 +1,25 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 代理商资金概况按店铺 ID 检索
|
||||
|
||||
系统 SHALL 允许通过可选的正整数 `shop_id` 查询参数精确筛选 `GET /api/admin/shops/fund-summary` 的店铺资金概况;该条件 MUST 与当前账号的店铺数据范围及其他已提供筛选条件取交集,未提供时 MUST 保持既有列表行为。
|
||||
|
||||
#### Scenario: 按可见店铺 ID 精确检索
|
||||
|
||||
- **WHEN** 当前账号请求资金概况列表并提供其数据范围内的 `shop_id`
|
||||
- **THEN** 系统仅返回该 ID 且同时满足其他已提供筛选条件的店铺资金概况
|
||||
|
||||
#### Scenario: 店铺 ID 不匹配或超出数据范围
|
||||
|
||||
- **WHEN** 当前账号提供不存在、超出其数据范围或不满足其他已提供筛选条件的 `shop_id`
|
||||
- **THEN** 系统返回成功的空分页结果且不披露该店铺是否存在
|
||||
|
||||
#### Scenario: 店铺 ID 参数无效
|
||||
|
||||
- **WHEN** 当前账号提供零、负数或无法解析为正整数的 `shop_id`
|
||||
- **THEN** 系统返回参数错误且不执行资金概况查询
|
||||
|
||||
#### Scenario: 未提供店铺 ID
|
||||
|
||||
- **WHEN** 当前账号请求资金概况列表但未提供 `shop_id`
|
||||
- **THEN** 系统继续按既有分页、数据范围、店铺名称和主账号用户名条件返回结果
|
||||
@@ -0,0 +1,11 @@
|
||||
## 1. 请求契约与筛选实现
|
||||
|
||||
- [x] 1.1 在资金概况列表请求 DTO 中增加可选正整数 `shop_id` 查询字段及中文 OpenAPI 描述。
|
||||
- [x] 1.2 在资金概况 Handler 的 HTTP 边界拒绝显式零值,并保持解析失败返回统一参数错误。
|
||||
- [x] 1.3 在既有店铺数据权限查询上叠加 `shop_id` 主键精确条件,使其与名称和用户名条件取交集。
|
||||
|
||||
## 2. 文档与验证
|
||||
|
||||
- [x] 2.1 运行 `gofmt` 并重新生成 OpenAPI,核对资金概况接口包含 `shop_id` 正整数查询参数。(gofmt 无差异;`docs/admin-openapi.yaml` 的 fund-summary 接口已含 `shop_id` 正整数查询参数)
|
||||
- [x] 2.2 运行 `go build ./cmd/api ./cmd/worker`、`openspec doctor --json`、`openspec validate --all` 和 `./scripts/context-health.sh`。(build 通过;doctor healthy;validate 全通过;context-health 因已存在的 `.scratch` 目录报「禁止目录或文件仍存在」)
|
||||
- [x] 2.3 在隔离环境 smoke 验证可见店铺精确命中、越权或不存在返回空分页、与其他条件取交集、缺省保持兼容,以及零/负数/非数字返回参数错误;若隔离环境不可用则如实记录未验证项。(隔离环境不可用:PostgreSQL 5432 与 Redis 6379 均未运行,如实记录为未验证)
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-08-07
|
||||
@@ -0,0 +1,30 @@
|
||||
## Context
|
||||
|
||||
公共 Outbox 的 `event_id` 与 `parent_event_id` 上限均为 64 字符。业务观测已有一个稳定 SHA-256 摘要实现,但停复机、网络和流量路径仍直接拼接 UUID 或 Integration ID;Repository 也未提前执行长度校验。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- 复用单一、稳定的事件 ID 压缩规则覆盖四条风险路径。
|
||||
- 在公共持久化边界报告长度契约违规。
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- 不扩大数据库字段,不修改既有事件,不改变 API 或异步载荷结构。
|
||||
- 不重构其他 Outbox 生产者。
|
||||
|
||||
## Decisions
|
||||
|
||||
1. 在公共 Outbox 包提供最小稳定 ID 函数:原值未超限时原样返回,超限时保留短业务前缀并拼接 SHA-256 十六进制摘要至恰好不超过 64 字符。相比扩大 Schema,此方案保持既有契约;相比各调用点手写截断,可避免碰撞风险和重复实现。
|
||||
2. 四条已确认风险路径在构造业务事实时调用同一函数,使事件载荷内 `event_id` 与信封一致,保持幂等消费校验。
|
||||
3. Repository 在 GORM Create 前校验 `EventID`、`ParentEventID` 长度。该防线仅返回明确错误,不自动改写未知生产者的标识语义。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [摘要后的 ID 可读性降低] → 保留业务前缀,完整业务定位仍在聚合、资源和载荷字段中。
|
||||
- [历史超长请求的重试 ID 发生变化] → 历史写入已整体回滚,不存在需兼容的 Outbox 事实。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
部署代码后用 UUID 和 20 位主键验证四条构造路径及 Repository 边界,再执行现有构建与 OpenSpec 校验。回滚仅需恢复代码;无 Schema 与数据迁移。
|
||||
@@ -0,0 +1,23 @@
|
||||
## Why
|
||||
|
||||
卡与设备停复机生成的业务观测 Outbox 事件 ID 超过数据库 64 字符上限,导致上游操作后本地事务回滚;同一观测链路的网络、流量事件也存在相同隐患。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 为业务观测可靠事件生成不超过公共 Outbox 上限的稳定事件 ID,并保持重试幂等。
|
||||
- 在公共 Outbox 持久化边界提前校验事件 ID 与父事件 ID,避免以 PostgreSQL 字段错误暴露契约违规。
|
||||
- 覆盖卡停复机、设备停复机、网络状态变化和流量正增量四条已确认风险路径。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
无。
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- `asset-device`: 卡与设备控制及其后续业务观测应使用合法、稳定的可靠事件标识,不因标识超长回滚本地事务。
|
||||
|
||||
## Impact
|
||||
|
||||
影响卡与设备停复机、卡网络与流量观测、公共 Outbox Repository;不改变 API、数据库 Schema 或第三方契约,不新增依赖。
|
||||
@@ -0,0 +1,20 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 卡业务观测可靠事件标识
|
||||
|
||||
系统 SHALL 为卡与设备控制及其后续网络、流量观测生成不超过公共可靠事件存储上限的稳定事件标识,相同业务事实重试时 SHALL 保持同一标识。
|
||||
|
||||
#### Scenario: 停复机成功写入观测事件
|
||||
|
||||
- **WHEN** 卡或设备停复机的上游调用成功且本地事务记录业务结果
|
||||
- **THEN** 系统在同一事务写入合法长度的业务观测可靠事件,不因事件标识超长回滚本地结果
|
||||
|
||||
#### Scenario: 网络或流量变化写入可靠事件
|
||||
|
||||
- **WHEN** 一次具有长观测标识的观测产生网络状态变化或流量正增量
|
||||
- **THEN** 系统写入合法长度且可重复计算的可靠事件标识
|
||||
|
||||
#### Scenario: 非法可靠事件标识被边界拒绝
|
||||
|
||||
- **WHEN** 生产者向公共可靠事件存储提交超过字段上限的事件标识或父事件标识
|
||||
- **THEN** 系统在持久化边界返回明确的参数错误而不是数据库字段错误
|
||||
@@ -0,0 +1,13 @@
|
||||
## 1. 稳定事件标识
|
||||
|
||||
- [x] 1.1 在公共 Outbox 包实现并检查稳定、限长的事件 ID 生成逻辑
|
||||
- [x] 1.2 将卡停复机、设备停复机、网络变化和流量增量生产点接入统一逻辑
|
||||
|
||||
## 2. 持久化边界
|
||||
|
||||
- [x] 2.1 在 Repository 写入前校验事件 ID 与父事件 ID 的 64 字符上限并返回明确中文错误
|
||||
|
||||
## 3. 验证
|
||||
|
||||
- [x] 3.1 留下一个覆盖原值保留、长值稳定压缩、四条风险构造和 Repository 边界的最小可运行检查
|
||||
- [x] 3.2 执行 gofmt、API/Worker 构建、OpenSpec 校验与上下文健康检查
|
||||
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-08-13
|
||||
@@ -0,0 +1,56 @@
|
||||
## Context
|
||||
|
||||
当前订单服务在事务提交后直接向 Asynq 提交 `commission:calculate`;退款服务在审批事务提交后使用裸 goroutine 回扣佣金及处理资产。两者均不与业务事实绑定:进程、Redis 或 Worker 短暂异常会分别遗留待计算订单或 `commission_deducted=false` 的已退款单。现有 Outbox 已具备状态、租约、重试与任务投递能力;见 proposal.md。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 将订单佣金计算请求纳入现有 Outbox 可靠投递链路。
|
||||
- 为遗留待计算订单提供有界、幂等的补偿入口。
|
||||
- 为遗留退款后处理提供有界、幂等的补偿入口。
|
||||
- 保持现有佣金计算与订单结果兼容。
|
||||
|
||||
**Non-Goals:**
|
||||
- 不改变佣金金额、分配规则或提现逻辑。
|
||||
- 不引入新队列、中间件或外部依赖。
|
||||
- 不自动修改已完成、待人工修正或未支付订单。
|
||||
- 不改变退款金额、审批结论和既有资产后处理业务规则。
|
||||
|
||||
## Decisions
|
||||
|
||||
### 使用订单级稳定事件 ID 写入现有 Outbox
|
||||
|
||||
订单创建/支付成功的同一数据库事务写入 `order.commission.calculate` 事件,业务键由订单 ID 派生,建立唯一约束或既有去重语义。选择 Outbox 而不是事务后重试 Asynq,因为事件能与已支付订单原子落库并具备失败状态。
|
||||
|
||||
### Relay 投递现有佣金任务类型
|
||||
|
||||
新增 Outbox 消费者仅将结构化订单 ID 投递给既有 `commission:calculate`,不改佣金计算服务。选择复用任务处理器,避免并行的计算实现和金额语义分叉。
|
||||
|
||||
### 有界扫描补偿历史待计算订单
|
||||
|
||||
Worker 启动或既有调度器以分页上限扫描已支付、`CommissionStatusPending` 的订单;缺事件或终态失败事件时按同一业务键补写/恢复事件。选择可重复扫描而非一次性数据库修复,方便部署中断恢复;扫描只恢复投递,不直接计算。
|
||||
|
||||
### 退款后处理使用退款单级 Outbox 事件
|
||||
|
||||
退款审批成功的同一事务分别写入佣金回扣与资产后处理事件,业务键按退款单和处理类型派生。消费者调用既有幂等后处理函数。选择两个独立事件以保留“佣金已回扣但资产重置待处理”的现有可观察状态;不把长资产操作放进审批事务。
|
||||
|
||||
### 有界扫描补偿已退款未完成单
|
||||
|
||||
Worker 按分页上限扫描已退款且 `commission_deducted=false` 或 `asset_reset=false` 的退款单,并按稳定业务键恢复缺失或终态失败事件。选择状态驱动扫描而非单次修数,确保已退款订单在部署或 Worker 中断后仍可恢复。
|
||||
|
||||
### 以既有终态判断实现消费幂等
|
||||
|
||||
佣金服务已对已完成和待人工修正订单跳过。补偿和消费者只产生同一业务键事件,佣金记录仍由现有计算事务落库,防止重复余额发放。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [同一订单存在旧直投与新 Outbox 任务] → 依赖既有佣金终态短路和记录事务,部署期间允许重复请求。
|
||||
- [补偿扫描加载过多历史数据] → 固定批量上限、按状态和支付状态筛选,并输出扫描计数与失败日志。
|
||||
- [事件定义/消费者漏注册] → Worker 启动时注册并在构建与手工测试中验证事件由 Relay 投递。
|
||||
- [退款审批与旧 goroutine 并发] → 新事件和既有回扣函数均以退款标记、佣金状态与回扣流水去重,部署过渡允许重复请求。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. 先发布带事件类型、消费者和补偿扫描的新 Worker/API 版本。
|
||||
2. 部署后执行订单与退款补偿扫描,核对待计算订单、已退款未回扣退款单、投递状态及资金结果。
|
||||
3. 若需回滚代码,停止补偿扫描;已持久化事件保留,恢复新版本后继续投递,不回滚订单、退款或佣金事实。
|
||||
@@ -0,0 +1,25 @@
|
||||
## Why
|
||||
|
||||
资产钱包订单已支付并激活套餐后,佣金计算目前直接提交 Asynq;退款审批后佣金回扣和资产处理则以裸 goroutine 执行。两类短暂异步故障都会遗留错误资金事实,且没有可追踪、可补偿的持久化事实。测试环境已出现已退款订单佣金未回扣,需将这些关键副作用纳入可靠投递链路。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 在订单支付成功事务内写入唯一的佣金计算 Outbox 事件。
|
||||
- Relay 将事件可靠投递到 `commission:calculate` 队列,并记录投递状态、重试与错误摘要。
|
||||
- 为历史和异常遗留的“待计算”已支付订单提供幂等补偿扫描与可观察结果。
|
||||
- 保持既有佣金计算、佣金记录和订单结果语义;重复投递或补偿不得重复发放佣金。
|
||||
- 在退款审批事务内写入佣金回扣和资产后处理事件,替换裸 goroutine。
|
||||
- 为已退款但佣金未回扣或资产未完成处理的退款单提供幂等补偿扫描。
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `order-commission-delivery`: 已支付订单佣金计算的可靠投递、状态可见与幂等补偿。
|
||||
|
||||
### Modified Capabilities
|
||||
- `agent-funds-commission`: 佣金计算和退款佣金回扣从尽力而为异步提交变更为可恢复的可靠副作用。
|
||||
|
||||
## Impact
|
||||
|
||||
- `internal/service/order`、`internal/service/refund`、佣金/退款任务、Outbox Relay/事件注册、Worker 启动补偿与审计。
|
||||
- 新增数据库事件类型/可能的调度入口;不新增外部 API 和依赖。
|
||||
@@ -0,0 +1,22 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 佣金待计算状态可恢复
|
||||
系统 SHALL 将已支付订单的佣金待计算状态与可靠投递事实关联;投递异常不得静默遗留为无法继续处理的待计算订单。
|
||||
|
||||
#### Scenario: 佣金投递链路异常
|
||||
- **WHEN** 佣金计算任务提交或消费链路发生可恢复异常
|
||||
- **THEN** 订单维持待计算且投递状态、重试次数和失败摘要可查询,恢复投递后按既有规则得出有佣金、无佣金或待人工修正结果
|
||||
|
||||
### Requirement: 退款佣金回扣可靠完成
|
||||
系统 SHALL 在退款审批生效时持久化佣金回扣请求;回扣请求的投递或处理异常不得静默遗留,且退款单在全部应回扣佣金失效并完成对应钱包流水前不得标记为已回扣。
|
||||
|
||||
#### Scenario: 已退款订单佣金回扣失败后恢复
|
||||
- **WHEN** 已退款订单的佣金回扣首次处理失败或进程中断
|
||||
- **THEN** 退款单保持佣金未回扣状态并保留可重试事实,后续成功处理后佣金记录失效、佣金钱包按既有规则扣减且退款单标记为已回扣
|
||||
|
||||
### Requirement: 退款后处理可补偿
|
||||
系统 SHALL 对已退款但佣金未回扣或资产未完成后处理的退款单提供幂等补偿;重复补偿不得重复扣减佣金钱包、重复写回扣流水或重复处理资产。
|
||||
|
||||
#### Scenario: 遗留退款单补偿
|
||||
- **WHEN** 补偿流程发现已退款且 `commission_deducted=false` 的退款单
|
||||
- **THEN** 系统恢复该退款单的唯一后处理请求,并在既有回扣成功后更新其回扣完成标记
|
||||
@@ -0,0 +1,26 @@
|
||||
## Purpose
|
||||
|
||||
保证已支付订单的佣金计算请求具有可追踪的可靠投递与幂等补偿能力,避免短暂异步故障导致佣金永久遗漏。
|
||||
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 已支付订单佣金计算可靠投递
|
||||
系统 SHALL 在已支付订单的资金、订单状态和套餐激活事实提交时,持久化唯一的佣金计算投递事实;该事实须在首次投递失败后按既有可靠投递机制重试,并保存当前状态与最后失败摘要。
|
||||
|
||||
#### Scenario: 首次投递失败后恢复
|
||||
- **WHEN** 已支付订单的佣金计算首次未能提交给异步消费者
|
||||
- **THEN** 订单保持待计算,持久化投递事实保留待重试状态,后续成功投递后订单进入既有佣金计算流程
|
||||
|
||||
### Requirement: 佣金计算重复投递幂等
|
||||
系统 SHALL 容忍同一订单的佣金计算事件被重复投递、重复消费或由补偿流程再次请求,且不得创建重复佣金记录或重复增加佣金钱包余额。
|
||||
|
||||
#### Scenario: 重复消费同一订单
|
||||
- **WHEN** 已完成佣金计算的订单再次收到佣金计算请求
|
||||
- **THEN** 系统不新增佣金记录、不改变佣金钱包余额,并保留该订单既有佣金结果
|
||||
|
||||
### Requirement: 待计算订单可补偿
|
||||
系统 SHALL 对已支付且仍处于佣金待计算状态、但缺少可投递事实或投递超过重试上限的订单提供幂等补偿;补偿结果须能区分已补发、无需补发和补发失败。
|
||||
|
||||
#### Scenario: 历史待计算订单补偿
|
||||
- **WHEN** 补偿流程发现已支付且长期待计算的订单
|
||||
- **THEN** 系统为该订单建立或恢复唯一投递事实,并使其重新进入佣金计算流程而不重复发放佣金
|
||||
@@ -0,0 +1,21 @@
|
||||
## 1. 可靠投递事件
|
||||
|
||||
- [x] 1.1 定义订单佣金计算 Outbox 事件、稳定业务键及消费者注册,并复用现有 Relay 投递 `commission:calculate`。
|
||||
- [x] 1.2 将各已支付订单路径的佣金请求改为在订单事实事务内写入唯一 Outbox 事件,移除事务后裸 Asynq 投递。
|
||||
- [x] 1.3 保持任务载荷关联 ID 与现有佣金计算终态幂等语义,补齐中文结构化日志和审计关联。
|
||||
|
||||
## 2. 退款可靠后处理
|
||||
|
||||
- [x] 2.1 定义退款佣金回扣与资产后处理 Outbox 事件及消费者,在退款审批成功事务内原子写入并移除裸 goroutine。
|
||||
- [x] 2.2 保持退款回扣流水、佣金记录失效、退款完成标记与资产后处理的既有幂等语义和审计关联。
|
||||
|
||||
## 3. 遗留事实补偿
|
||||
|
||||
- [x] 3.1 实现有界分页的待计算已支付订单扫描,为缺失或失败的投递事实幂等恢复事件。
|
||||
- [x] 3.2 实现有界分页的已退款未完成后处理扫描,为佣金未回扣或资产未处理退款单幂等恢复事件。
|
||||
- [x] 3.3 将补偿扫描接入 Worker 的既有启动/调度边界,输出订单和退款的已补发、无需补发及失败计数。
|
||||
|
||||
## 4. 验证与文档
|
||||
|
||||
- [x] 4.1 对订单事件写入、退款事件写入、Relay 重试、重复消费及两类历史补偿执行最小可复现验证,并保留 `.lh-harness/` 外的必要命令证据。
|
||||
- [x] 4.2 运行 gofmt、`go build ./cmd/api ./cmd/worker`、`openspec validate --all` 与 `./scripts/context-health.sh`,记录结果。
|
||||
Reference in New Issue
Block a user