Files
junhong_cmp_fiber/openspec/specs/commission-stats-caching/spec.md
huang 1da680a790
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m18s
重构: 店铺套餐分配系统从加价模式改为返佣模式
主要变更:
- 重构分配模型:从加价模式(pricing_mode/pricing_value)改为返佣模式(base_commission + tier_commission)
- 删除独立的 my_package 接口,统一到 /api/admin/packages(通过数据权限自动过滤)
- 新增批量分配和批量调价功能,支持事务和性能优化
- 新增配置版本管理,订单创建时锁定返佣配置
- 新增成本价历史记录,支持审计和纠纷处理
- 新增统计缓存系统(Redis + 异步任务),优化梯度返佣计算性能
- 删除冗余的梯度佣金独立 CRUD 接口(合并到分配配置中)
- 归档 3 个已完成的 OpenSpec changes 并同步 8 个新 capabilities 到 main specs

技术细节:
- 数据库迁移:000026_refactor_shop_package_allocation
- 新增 Store:AllocationConfigStore, PriceHistoryStore, CommissionStatsStore
- 新增 Service:BatchAllocationService, BatchPricingService, CommissionStatsService
- 新增异步任务:统计更新、定时同步、周期归档
- 测试覆盖:批量操作集成测试、梯度佣金 CRUD 清理验证

影响:
- API 变更:删除 4 个梯度 CRUD 接口(POST/GET/PUT/DELETE /:id/tiers)
- API 新增:批量分配、批量调价接口
- 数据模型:重构 shop_series_allocation 表结构
- 性能优化:批量操作使用 CreateInBatches,统计使用 Redis 缓存

相关文档:
- openspec/changes/archive/2026-01-28-refactor-shop-package-allocation/
- openspec/specs/agent-available-packages/
- openspec/specs/allocation-config-versioning/
- 等 8 个新 capability specs
2026-01-28 17:11:55 +08:00

88 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Capability: 返佣统计缓存管理
## Purpose
本 capability 定义如何使用 Redis 和异步任务管理梯度返佣统计数据,支持高并发场景下的性能优化和数据一致性。
## Requirements
### Requirement: 异步更新梯度统计数据
系统 SHALL 在充值订单成功后,通过异步任务更新梯度统计数据,而不是实时计算。异步任务 MUST 使用 Asynq 队列系统实现。
#### Scenario: 充值成功后发送异步任务
- **WHEN** 下级客户充值100元成功
- **THEN** 系统立即返回成功,并发送异步任务 "commission:stats:update" 到队列
#### Scenario: 异步任务更新统计数据
- **WHEN** 异步任务执行payload 包含 allocation_id=123, sales_count=1, sales_amount=10000
- **THEN** 系统更新 allocation_id=123 当前周期的统计数据
#### Scenario: 异步任务失败时重试
- **WHEN** 异步任务执行失败(如数据库连接超时)
- **THEN** 系统自动重试最多3次
---
### Requirement: 使用 Redis 缓存统计数据
系统 SHALL 使用 Redis 缓存梯度统计数据key 格式为 `commission:stats:{allocation_id}:{period}`,支持原子递增操作。
#### Scenario: Redis 原子递增销量
- **WHEN** 异步任务更新统计时allocation_id=123销量+1
- **THEN** 系统执行 HINCRBY commission:stats:123:2026-01 total_count 1
#### Scenario: Redis 原子递增销售额
- **WHEN** 异步任务更新统计时allocation_id=123销售额+10000
- **THEN** 系统执行 HINCRBY commission:stats:123:2026-01 total_amount 10000
#### Scenario: Redis key 设置过期时间
- **WHEN** 创建 Redis key 时当前周期结束时间为2026-01-31 23:59:59
- **THEN** 系统设置 key 过期时间为 2026-02-07 23:59:59周期结束后7天
---
### Requirement: 定时同步到数据库
系统 SHALL 每小时执行一次定时任务,将 Redis 中的统计数据同步到数据库表 `tb_shop_series_commission_stats`
#### Scenario: 每小时同步 Redis 数据到数据库
- **WHEN** 定时任务执行
- **THEN** 系统扫描所有 Redis keypattern: commission:stats:*),批量更新数据库
#### Scenario: 同步时使用乐观锁避免冲突
- **WHEN** 多个任务同时更新同一条统计记录
- **THEN** 系统使用 version 字段实现乐观锁,失败时重试
#### Scenario: 同步后不删除 Redis key
- **WHEN** 定时任务同步完成
- **THEN** Redis key 保留(用于实时查询),等待过期时间自动清理
---
### Requirement: 查询统计数据时优先从 Redis 获取
系统 SHALL 在查询当前周期的统计数据时,优先从 Redis 获取Redis 不存在时从数据库获取并回写到 Redis。
#### Scenario: Redis 存在时直接返回
- **WHEN** 查询 allocation_id=123 的当前周期统计
- **THEN** 系统从 Redis key `commission:stats:123:2026-01` 获取数据并返回
#### Scenario: Redis 不存在时从数据库加载
- **WHEN** 查询 allocation_id=123 的当前周期统计Redis key 不存在
- **THEN** 系统从数据库查询,并回写到 Redis
---
### Requirement: 周期结束后归档统计数据
系统 SHALL 在每个统计周期结束后,执行归档任务:确保 Redis 数据已同步到数据库,更新统计状态为 "completed",清理 Redis key。
#### Scenario: 月度周期结束时归档
- **WHEN** 2026年1月31日 23:59:59月度周期结束
- **THEN** 系统执行归档任务:同步数据、更新状态为 "completed"、删除 Redis key
#### Scenario: 归档后统计数据不再更新
- **WHEN** 周期已归档status = "completed"
- **THEN** 新的充值订单不再更新该周期的统计数据,而是创建新周期的统计记录