fix: improve the UI for set the limit token for the user

This commit is contained in:
2026-07-18 16:03:34 +07:00
parent 8f6e57dfc6
commit 21532e0f00
10 changed files with 239 additions and 48 deletions
+11 -2
View File
@@ -38,6 +38,9 @@ function quota(sessionLimit, sessionUsed, weeklyLimit, weeklyUsed) {
remainingPercentage: limit > 0 ? Math.round((Math.max(0, limit - used) / limit) * 100) : null,
isUnlimited: limit === 0,
windowStart,
resetAt: windowStart === "2026-07-17T05:00:00.000Z"
? "2026-07-17T10:00:00.000Z"
: "2026-07-20T17:00:00.000Z",
});
return {
@@ -92,8 +95,14 @@ describe("/api/usage/system-quota personal token quota overlay", () => {
expect(providerById(payload, "codex").accountCount).toBeUndefined();
expect(providerById(payload, "codex").quotaAccountCount).toBeUndefined();
expect(providerById(payload, "codex").quotas).toMatchObject([
{ name: "Session", tokenBudget: true, limit: 100, used: 25, remaining: 75, remainingPercentage: 75 },
{ name: "Weekly", tokenBudget: true, limit: 1000, used: 200, remaining: 800, remainingPercentage: 80 },
{
name: "Session", tokenBudget: true, limit: 100, used: 25,
remaining: 75, remainingPercentage: 75, resetAt: "2026-07-17T10:00:00.000Z",
},
{
name: "Weekly", tokenBudget: true, limit: 1000, used: 200,
remaining: 800, remainingPercentage: 80, resetAt: "2026-07-20T17:00:00.000Z",
},
]);
expect(providerById(payload, "orbit-provider").quotas).toMatchObject([
{ name: "Session", tokenBudget: true, limit: 100, used: 25 },
+18
View File
@@ -2,11 +2,13 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
const getUserTokenLimits = vi.fn();
const getUserProviderTokenUsageSince = vi.fn();
const getUserProviderEarliestTokenUsageSince = vi.fn();
const getUserTokenLimitWindowStart = vi.fn();
vi.mock("@/lib/db/index.js", () => ({
getUserTokenLimits,
getUserProviderTokenUsageSince,
getUserProviderEarliestTokenUsageSince,
}));
vi.mock("@/lib/tokenLimitEnforcer.js", () => ({ getUserTokenLimitWindowStart }));
@@ -23,6 +25,7 @@ describe("user token quota snapshot", () => {
beforeEach(() => {
getUserTokenLimits.mockReset();
getUserProviderTokenUsageSince.mockReset();
getUserProviderEarliestTokenUsageSince.mockReset();
getUserTokenLimitWindowStart.mockReset();
getUserTokenLimits.mockResolvedValue({
@@ -42,6 +45,7 @@ describe("user token quota snapshot", () => {
const windowType = since.getTime() === sessionStart.getTime() ? "session" : "weekly";
return usage.get(usageKey(provider, windowType));
});
getUserProviderEarliestTokenUsageSince.mockResolvedValue(null);
});
it("calculates both provider windows and preserves zero as unlimited", async () => {
@@ -58,7 +62,21 @@ describe("user token quota snapshot", () => {
},
});
expect(quota.codex.session.windowStart).toBe(sessionStart.toISOString());
expect(quota.codex.session.resetAt).toBeNull();
expect(quota.codex.weekly.resetAt).toBe("2026-07-20T17:00:00.000Z");
expect(getUserProviderTokenUsageSince).toHaveBeenCalledTimes(4);
expect(getUserProviderEarliestTokenUsageSince).toHaveBeenCalledTimes(2);
});
it("reports when the next tokens leave a rolling session window", async () => {
getUserProviderEarliestTokenUsageSince.mockImplementation(async (_userId, provider) => (
provider === "orbit-provider" ? "2026-07-17T06:30:00.000Z" : null
));
const quota = await getUserTokenQuota("user-1", new Date("2026-07-17T10:00:00.000Z"));
expect(quota["orbit-provider"].session.resetAt).toBe("2026-07-17T11:30:00.000Z");
expect(quota.codex.session.resetAt).toBeNull();
});
it("requires a user id", async () => {