fix(notify): remove percentage threshold from balance notification
Balance low notification only supports fixed USD amount threshold. Percentage threshold is a quota concept, not applicable to balance. Reverted threshold_type from admin settings, user profile, and all backend/frontend layers. DB fields (balance_notify_threshold_type, total_recharged) retained for potential future quota use.
This commit is contained in:
@@ -51,12 +51,16 @@ func (s *BalanceNotifyService) CheckBalanceAfterDeduction(ctx context.Context, u
|
||||
return
|
||||
}
|
||||
|
||||
globalEnabled, globalThresholdType, globalThresholdValue := s.getBalanceNotifyConfig(ctx)
|
||||
globalEnabled, globalThreshold := s.getBalanceNotifyConfig(ctx)
|
||||
if !globalEnabled {
|
||||
return
|
||||
}
|
||||
|
||||
threshold := s.resolveEffectiveThreshold(user, globalThresholdType, globalThresholdValue)
|
||||
// User custom threshold overrides system default
|
||||
threshold := globalThreshold
|
||||
if user.BalanceNotifyThreshold != nil {
|
||||
threshold = *user.BalanceNotifyThreshold
|
||||
}
|
||||
if threshold <= 0 {
|
||||
return
|
||||
}
|
||||
@@ -76,30 +80,6 @@ func (s *BalanceNotifyService) CheckBalanceAfterDeduction(ctx context.Context, u
|
||||
}
|
||||
}
|
||||
|
||||
// resolveEffectiveThreshold computes the actual USD threshold based on type and user settings.
|
||||
// When user sets a custom threshold, their type is used independently (defaults to "fixed" if unset).
|
||||
func (s *BalanceNotifyService) resolveEffectiveThreshold(user *User, globalType string, globalValue float64) float64 {
|
||||
if user.BalanceNotifyThreshold != nil {
|
||||
thresholdType := user.BalanceNotifyThresholdType
|
||||
if thresholdType == "" {
|
||||
thresholdType = ThresholdTypeFixed // user custom value defaults to fixed, not inherited
|
||||
}
|
||||
return computeThreshold(thresholdType, *user.BalanceNotifyThreshold, user.TotalRecharged)
|
||||
}
|
||||
return computeThreshold(globalType, globalValue, user.TotalRecharged)
|
||||
}
|
||||
|
||||
// computeThreshold converts a threshold value to USD based on type.
|
||||
func computeThreshold(thresholdType string, value, totalRecharged float64) float64 {
|
||||
if thresholdType == ThresholdTypePercentage {
|
||||
if totalRecharged <= 0 {
|
||||
return 0 // no recharge history → skip percentage check
|
||||
}
|
||||
return totalRecharged * value / 100
|
||||
}
|
||||
return value // fixed USD amount
|
||||
}
|
||||
|
||||
// quotaDim describes one quota dimension for notification checking.
|
||||
type quotaDim struct {
|
||||
name string
|
||||
@@ -154,21 +134,13 @@ func (s *BalanceNotifyService) asyncSendQuotaAlert(adminEmails []string, account
|
||||
}
|
||||
|
||||
// getBalanceNotifyConfig reads global balance notification settings.
|
||||
func (s *BalanceNotifyService) getBalanceNotifyConfig(ctx context.Context) (enabled bool, thresholdType string, threshold float64) {
|
||||
keys := []string{
|
||||
SettingKeyBalanceLowNotifyEnabled,
|
||||
SettingKeyBalanceLowNotifyThresholdType,
|
||||
SettingKeyBalanceLowNotifyThreshold,
|
||||
}
|
||||
func (s *BalanceNotifyService) getBalanceNotifyConfig(ctx context.Context) (enabled bool, threshold float64) {
|
||||
keys := []string{SettingKeyBalanceLowNotifyEnabled, SettingKeyBalanceLowNotifyThreshold}
|
||||
settings, err := s.settingRepo.GetMultiple(ctx, keys)
|
||||
if err != nil {
|
||||
return false, ThresholdTypeFixed, 0
|
||||
return false, 0
|
||||
}
|
||||
enabled = settings[SettingKeyBalanceLowNotifyEnabled] == "true"
|
||||
thresholdType = settings[SettingKeyBalanceLowNotifyThresholdType]
|
||||
if thresholdType == "" {
|
||||
thresholdType = ThresholdTypeFixed
|
||||
}
|
||||
if v := settings[SettingKeyBalanceLowNotifyThreshold]; v != "" {
|
||||
if f, err := strconv.ParseFloat(v, 64); err == nil {
|
||||
threshold = f
|
||||
|
||||
Reference in New Issue
Block a user