fix(billing): extend quantity validation and saturating conversions to remaining paths
Bound max-tokens fields across all relay format validators, saturate tiered-expression rounding and audio/tool/task token conversions, and route legacy remix ratios through the guarded setter.
This commit is contained in:
@@ -291,6 +291,12 @@ func TestQuotaRound(t *testing.T) {
|
||||
{999.4999, 999},
|
||||
{999.5, 1000},
|
||||
{1e9 + 0.5, 1e9 + 1},
|
||||
// Oversized expression results must saturate at int32 bounds
|
||||
// instead of wrapping into a negative charge.
|
||||
{3.6893488147419103e19, math.MaxInt32},
|
||||
{-3.6893488147419103e19, math.MinInt32},
|
||||
{math.Inf(1), math.MaxInt32},
|
||||
{math.NaN(), 0},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
got := billingexpr.QuotaRound(tt.in)
|
||||
|
||||
@@ -5,6 +5,20 @@ import "math"
|
||||
// QuotaRound converts a float64 quota value to int using half-away-from-zero
|
||||
// rounding. Every tiered billing path (pre-consume, settlement, breakdown
|
||||
// validation, log fields) MUST use this function to avoid +-1 discrepancies.
|
||||
//
|
||||
// The result saturates at int32 bounds: quota columns are 32-bit integers in
|
||||
// the database, and an oversized expression result must never wrap around
|
||||
// and turn a charge into a credit.
|
||||
func QuotaRound(f float64) int {
|
||||
return int(math.Round(f))
|
||||
r := math.Round(f)
|
||||
if math.IsNaN(r) {
|
||||
return 0
|
||||
}
|
||||
if r >= math.MaxInt32 {
|
||||
return math.MaxInt32
|
||||
}
|
||||
if r <= math.MinInt32 {
|
||||
return math.MinInt32
|
||||
}
|
||||
return int(r)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user