fix: update the quota tracker for user role

This commit is contained in:
2026-07-18 13:23:02 +07:00
parent c77127aaf3
commit 8f6e57dfc6
11 changed files with 516 additions and 155 deletions
@@ -1,15 +1,9 @@
import { NextResponse } from "next/server";
import {
getUserById,
getUserProviderTokenUsageSince,
getUserTokenLimits,
} from "@/lib/db/index.js";
import { requireAdminUser } from "@/lib/auth/currentUser.js";
import { getUserTokenLimitWindowStart } from "@/lib/tokenLimitEnforcer.js";
import {
USER_TOKEN_LIMIT_PROVIDER_IDS,
USER_TOKEN_LIMIT_WINDOW_IDS,
} from "open-sse/config/userTokenLimits.js";
import { getUserTokenQuota } from "@/lib/userTokenQuota.js";
export const dynamic = "force-dynamic";
@@ -27,25 +21,6 @@ function errorResponse(error) {
return NextResponse.json({ error: message }, { status, headers: NO_STORE_HEADERS });
}
function buildWindowUsage(limit, used, windowStart) {
const normalizedLimit = Math.max(0, Number(limit) || 0);
const normalizedUsed = Math.max(0, Number(used) || 0);
const remaining = normalizedLimit > 0
? Math.max(0, normalizedLimit - normalizedUsed)
: null;
const remainingPercentage = normalizedLimit > 0
? Math.round((remaining / normalizedLimit) * 100)
: null;
return {
limit: normalizedLimit,
used: normalizedUsed,
remaining,
remainingPercentage,
windowStart: windowStart.toISOString(),
};
}
export async function GET(_request, { params }) {
try {
await requireAdminUser();
@@ -56,39 +31,11 @@ export async function GET(_request, { params }) {
if (user.role !== "user") throw new Error("Token usage only applies to user accounts");
const now = new Date();
const limits = await getUserTokenLimits(user.id);
const windows = Object.fromEntries(USER_TOKEN_LIMIT_WINDOW_IDS.map((windowType) => [
windowType,
getUserTokenLimitWindowStart(windowType, now),
]));
const usageEntries = await Promise.all(
USER_TOKEN_LIMIT_PROVIDER_IDS.flatMap((provider) => (
USER_TOKEN_LIMIT_WINDOW_IDS.map(async (windowType) => {
const used = await getUserProviderTokenUsageSince(
user.id,
provider,
windows[windowType],
);
return [provider, windowType, used];
})
)),
);
const usageByProvider = Object.fromEntries(
USER_TOKEN_LIMIT_PROVIDER_IDS.map((provider) => [provider, {}]),
);
for (const [provider, windowType, used] of usageEntries) {
usageByProvider[provider][windowType] = buildWindowUsage(
limits[provider]?.[windowType],
used,
windows[windowType],
);
}
const providers = await getUserTokenQuota(user.id, now);
return NextResponse.json({
userId: user.id,
providers: usageByProvider,
providers,
updatedAt: now.toISOString(),
}, { headers: NO_STORE_HEADERS });
} catch (error) {