initial budget ui on the provider

This commit is contained in:
Owen
2026-08-10 12:03:46 -04:00
parent 187936e5dd
commit 211d3a53f5
7 changed files with 676 additions and 1 deletions
+70
View File
@@ -0,0 +1,70 @@
import type { AiBudget } from "@server/db";
export type AiBudgetScopeType =
| "provider"
| "model"
| "resource"
| "siteResource"
| "role";
export type AiBudgetScope = {
type: AiBudgetScopeType;
id: number;
};
export type AiBudgetScopeBodyField =
| "providerId"
| "modelId"
| "resourceId"
| "siteResourceId"
| "roleId";
const scopeConfig: Record<
AiBudgetScopeType,
{ listPath: (id: number) => string; bodyField: AiBudgetScopeBodyField }
> = {
provider: {
listPath: (id) => `/ai-provider/${id}/ai-budgets`,
bodyField: "providerId"
},
model: {
listPath: (id) => `/ai-model/${id}/ai-budgets`,
bodyField: "modelId"
},
resource: {
listPath: (id) => `/resource/${id}/ai-budgets`,
bodyField: "resourceId"
},
siteResource: {
listPath: (id) => `/site-resource/${id}/ai-budgets`,
bodyField: "siteResourceId"
},
role: {
listPath: (id) => `/role/${id}/ai-budgets`,
bodyField: "roleId"
}
};
export function getAiBudgetScopeListPath(scope: AiBudgetScope): string {
return scopeConfig[scope.type].listPath(scope.id);
}
export function getAiBudgetScopeBodyField(
scope: AiBudgetScope
): AiBudgetScopeBodyField {
return scopeConfig[scope.type].bodyField;
}
export type AiBudgetUnit = AiBudget["unit"];
export type AiBudgetPeriod = AiBudget["period"];
export const AI_BUDGET_UNITS: AiBudgetUnit[] = ["usd", "tokens"];
export const AI_BUDGET_PERIODS: AiBudgetPeriod[] = [
"hourly",
"daily",
"weekly",
"monthly",
"yearly",
"lifetime"
];
+18
View File
@@ -63,6 +63,11 @@ import type {
ListAiModelsResponse,
ListAiProvidersResponse
} from "@server/routers/aiProvider/types";
import type { ListAiBudgetsByScopeResponse } from "@server/routers/aiBudget/types";
import {
getAiBudgetScopeListPath,
type AiBudgetScope
} from "@app/lib/aiBudgetScope";
import type { ListUsersResponse } from "@server/routers/user";
import type ResponseT from "@server/types/Response";
import {
@@ -1213,6 +1218,19 @@ export const aiProviderQueries = {
})
};
export const aiBudgetQueries = {
scoped: ({ scope }: { scope: AiBudgetScope }) =>
queryOptions({
queryKey: ["AI_BUDGETS", scope.type, scope.id] as const,
queryFn: async ({ signal, meta }) => {
const res = await meta!.api.get<
AxiosResponse<ListAiBudgetsByScopeResponse>
>(getAiBudgetScopeListPath(scope), { signal });
return res.data.data.budgets;
}
})
};
export const resourceQueries = {
resourceUsers: ({ resourceId }: { resourceId: number }) =>
queryOptions({