fix(billing): surface quota saturation events for admin auditing

Thread int32 saturation clamps from tiered settlement and video task
recompute into the consume/task logs under admin_info, so oversized or
malformed billing inputs stay auditable. Clamp negative audio duration
before token conversion and gate the saturation UI markers on admin.
This commit is contained in:
CaIon
2026-07-07 12:20:07 +08:00
parent c9943d37ad
commit bae799ccb1
32 changed files with 710 additions and 104 deletions
+18 -2
View File
@@ -202,7 +202,9 @@ func RelayTaskSubmit(c *gin.Context, info *relaycommon.RelayInfo) (*TaskSubmitRe
quotaWithRatios *= ra
}
}
info.PriceData.Quota = common.QuotaFromFloat(quotaWithRatios)
quota, clamp := common.QuotaFromFloatChecked(quotaWithRatios)
info.PriceData.Quota = quota
noteTaskQuotaClamp(info, clamp)
}
// 7. 预扣费(仅首次 — 重试时 info.Billing 已存在,跳过)
@@ -278,7 +280,21 @@ func recalcQuotaFromRatios(info *relaycommon.RelayInfo, ratios map[string]float6
result *= ra
}
}
return common.QuotaFromFloat(result)
quota, clamp := common.QuotaFromFloatChecked(result)
noteTaskQuotaClamp(info, clamp)
return quota
}
// noteTaskQuotaClamp records the first quota saturation event onto the task's
// RelayInfo so LogTaskConsumption can surface it on the submit log's
// admin_info. First non-nil clamp wins.
func noteTaskQuotaClamp(info *relaycommon.RelayInfo, clamp *common.QuotaClamp) {
if clamp == nil || info == nil {
return
}
if info.QuotaClamp == nil {
info.QuotaClamp = clamp
}
}
var fetchRespBuilders = map[int]func(c *gin.Context) (respBody []byte, taskResp *dto.TaskError){