fix(authorization): fix race condition in reward distribution calculation
When calculating reward distribution for community/province/city benefits, the totalTeamPlantingCount was being read after referral-service had already updated it with the current planting. This caused incorrect distribution where benefits were given to the community holder before they completed their assessment target. Fix: Subtract treeCount from rawTeamCount to restore the "before planting" team count, ensuring correct assessment calculation. Affected methods: - getCommunityRewardDistribution - getProvinceTeamRewardDistribution - getCityTeamRewardDistribution 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
fc55afb7b9
commit
f94e7283d5
|
|
@ -859,12 +859,20 @@ export class AuthorizationApplicationService {
|
|||
const communityStats = await this.statsRepository.findByAccountSequence(
|
||||
nearestCommunity.userId.accountSequence,
|
||||
)
|
||||
const currentTeamCount = communityStats?.totalTeamPlantingCount ?? 0
|
||||
const rawTeamCount = communityStats?.totalTeamPlantingCount ?? 0
|
||||
|
||||
// 重要:由于 referral-service 和 reward-service 都消费同一个 Kafka 事件,
|
||||
// 存在竞态条件,此时查询到的 totalTeamPlantingCount 可能已经包含了本次认种。
|
||||
// 因此需要减去本次认种数量来还原"认种前"的团队数。
|
||||
// 注意:如果 referral-service 还没处理完,rawTeamCount 可能还是旧值,
|
||||
// 此时 currentTeamCount 可能为负数,需要取 max(0, ...)
|
||||
const currentTeamCount = Math.max(0, rawTeamCount - treeCount)
|
||||
const initialTarget = nearestCommunity.getInitialTarget() // 社区初始考核目标:10棵
|
||||
|
||||
this.logger.debug(
|
||||
`[getCommunityRewardDistribution] Community ${nearestCommunity.userId.accountSequence} ` +
|
||||
`benefitActive=false, currentTeamCount=${currentTeamCount}, initialTarget=${initialTarget}`,
|
||||
`benefitActive=false, rawTeamCount=${rawTeamCount}, treeCount=${treeCount}, ` +
|
||||
`currentTeamCount(before)=${currentTeamCount}, initialTarget=${initialTarget}`,
|
||||
)
|
||||
|
||||
// 6. 查找上级社区(用于接收考核前的权益)
|
||||
|
|
@ -1023,9 +1031,15 @@ export class AuthorizationApplicationService {
|
|||
|
||||
// 5. 权益未激活,计算考核分配
|
||||
const stats = await this.statsRepository.findByAccountSequence(nearestAuthProvince.userId.accountSequence)
|
||||
const currentTeamCount = stats?.totalTeamPlantingCount ?? 0
|
||||
const rawTeamCount = stats?.totalTeamPlantingCount ?? 0
|
||||
// 修复竞态条件:减去本次认种数量来还原"认种前"的团队数
|
||||
const currentTeamCount = Math.max(0, rawTeamCount - treeCount)
|
||||
const initialTarget = nearestAuthProvince.getInitialTarget() // 500棵
|
||||
|
||||
this.logger.debug(
|
||||
`[getProvinceTeamRewardDistribution] rawTeamCount=${rawTeamCount}, treeCount=${treeCount}, currentTeamCount(before)=${currentTeamCount}`,
|
||||
)
|
||||
|
||||
// 6. 查找上级(用于接收考核前的权益)
|
||||
let parentAccountSequence: number = HEADQUARTERS_ACCOUNT_SEQUENCE
|
||||
let parentReason = '上级为总部社区'
|
||||
|
|
@ -1227,9 +1241,15 @@ export class AuthorizationApplicationService {
|
|||
|
||||
// 5. 权益未激活,计算考核分配
|
||||
const stats = await this.statsRepository.findByAccountSequence(nearestAuthCity.userId.accountSequence)
|
||||
const currentTeamCount = stats?.totalTeamPlantingCount ?? 0
|
||||
const rawTeamCount = stats?.totalTeamPlantingCount ?? 0
|
||||
// 修复竞态条件:减去本次认种数量来还原"认种前"的团队数
|
||||
const currentTeamCount = Math.max(0, rawTeamCount - treeCount)
|
||||
const initialTarget = nearestAuthCity.getInitialTarget() // 100棵
|
||||
|
||||
this.logger.debug(
|
||||
`[getCityTeamRewardDistribution] rawTeamCount=${rawTeamCount}, treeCount=${treeCount}, currentTeamCount(before)=${currentTeamCount}`,
|
||||
)
|
||||
|
||||
// 6. 查找上级
|
||||
let parentAccountSequence: number = HEADQUARTERS_ACCOUNT_SEQUENCE
|
||||
let parentReason = '上级为总部社区'
|
||||
|
|
|
|||
Loading…
Reference in New Issue