feat: cap per-user AI token spend
CI and Deploy / test (push) Successful in 2m43s
CI and Deploy / deploy (push) Successful in 57s

This commit is contained in:
cesnimda
2026-07-30 23:32:13 +02:00
parent 09fc2b03f7
commit 792814b04e
5 changed files with 18 additions and 9 deletions
@@ -44,10 +44,17 @@ public sealed class AiWorkspaceController : ControllerBase
if (_db is not null)
{
var roles = await _users.GetRolesAsync(user);
var limit = AccountPlans.ForRoles(roles).MonthlyAiCalls;
var entitlements = AccountPlans.ForRoles(roles);
var monthStart = new DateTimeOffset(DateTime.UtcNow.Year, DateTime.UtcNow.Month, 1, 0, 0, 0, TimeSpan.Zero);
var used = await _db.AiInteractions.CountAsync(x => x.OwnerUserId == user.Id && x.CreatedAtUtc >= monthStart, ct);
if (used >= limit) return StatusCode(StatusCodes.Status429TooManyRequests, $"Monthly AI limit reached ({limit} generations). Upgrade your plan or try again next month.");
var used = await _db.AiInteractions
.Where(x => x.OwnerUserId == user.Id && x.CreatedAtUtc >= monthStart)
.GroupBy(_ => 1)
.Select(g => new { Calls = g.Count(), Tokens = g.Sum(x => (long)x.EstimatedTokenCount) })
.FirstOrDefaultAsync(ct);
if ((used?.Calls ?? 0) >= entitlements.MonthlyAiCalls)
return StatusCode(StatusCodes.Status429TooManyRequests, $"Monthly AI limit reached ({entitlements.MonthlyAiCalls} generations). Upgrade your plan or try again next month.");
if ((used?.Tokens ?? 0) >= entitlements.MonthlyAiTokens)
return StatusCode(StatusCodes.Status429TooManyRequests, $"Monthly AI cost limit reached ({entitlements.MonthlyAiTokens:N0} estimated tokens). Upgrade your plan or try again next month.");
}
try