Skip to content

Commit 55f048c

Browse files
authored
Cost over time in admin (#5052)
1 parent 0c105a2 commit 55f048c

File tree

5 files changed

+102
-15
lines changed

5 files changed

+102
-15
lines changed

bifrost/lib/clients/jawnTypes/private.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19509,6 +19509,8 @@ export interface operations {
1950919509
/** Format: double */
1951019510
all_time_count: number;
1951119511
monthly_usage: {
19512+
/** Format: double */
19513+
cost: number;
1951219514
/** Format: double */
1951319515
requestCount: number;
1951419516
month: string;

valhalla/jawn/src/controllers/private/adminController.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,7 @@ export class AdminController extends Controller {
13151315
monthly_usage: {
13161316
month: string;
13171317
requestCount: number;
1318+
cost: number;
13181319
}[];
13191320
all_time_count: number;
13201321
}> {
@@ -1332,7 +1333,8 @@ export class AdminController extends Controller {
13321333
const monthlyUsageQuery = `
13331334
SELECT
13341335
toStartOfMonth(request_created_at) AS month,
1335-
COUNT(*) AS requestCount
1336+
COUNT(*) AS requestCount,
1337+
SUM(cost) / 1000000000 AS cost
13361338
FROM
13371339
request_response_rmt
13381340
WHERE
@@ -1359,6 +1361,7 @@ export class AdminController extends Controller {
13591361
clickhouseDb.dbQuery<{
13601362
month: string;
13611363
requestCount: string;
1364+
cost: string;
13621365
}>(monthlyUsageQuery, [orgId]),
13631366
clickhouseDb.dbQuery<{
13641367
all_time_count: string;
@@ -1379,6 +1382,7 @@ export class AdminController extends Controller {
13791382
monthly_usage: monthlyUsage.map((item) => ({
13801383
month: item.month,
13811384
requestCount: Number(item.requestCount),
1385+
cost: Number(item.cost),
13821386
})),
13831387
all_time_count: Number(allTimeCount),
13841388
};

valhalla/jawn/src/tsoa-build/private/swagger.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56776,6 +56776,10 @@
5677656776
"monthly_usage": {
5677756777
"items": {
5677856778
"properties": {
56779+
"cost": {
56780+
"type": "number",
56781+
"format": "double"
56782+
},
5677956783
"requestCount": {
5678056784
"type": "number",
5678156785
"format": "double"
@@ -56785,6 +56789,7 @@
5678556789
}
5678656790
},
5678756791
"required": [
56792+
"cost",
5678856793
"requestCount",
5678956794
"month"
5679056795
],

web/components/templates/admin/orgSearch.tsx

Lines changed: 88 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -207,19 +207,26 @@ const OrgSearch = () => {
207207
});
208208
}
209209

210-
// Create a map of existing usage data
210+
// Create maps for usage and cost data
211211
const usageMap = new Map(
212212
monthlyUsage.map((item) => [
213213
new Date(item.month).toISOString().slice(0, 7),
214-
item.requestCount || 0,
214+
{
215+
requestCount: item.requestCount || 0,
216+
cost: item.cost || 0,
217+
},
215218
]),
216219
);
217220

218221
// Fill in all 12 months with data or 0
219-
return last12Months.map(({ monthKey, month }) => ({
220-
month,
221-
requestCount: usageMap.get(monthKey) || 0,
222-
}));
222+
return last12Months.map(({ monthKey, month }) => {
223+
const data = usageMap.get(monthKey) || { requestCount: 0, cost: 0 };
224+
return {
225+
month,
226+
requestCount: data.requestCount,
227+
cost: data.cost,
228+
};
229+
});
223230
};
224231

225232
const getOwnerFromMembers = (
@@ -1064,30 +1071,30 @@ const OrgTableRow = ({
10641071
</div>
10651072
</div>
10661073

1067-
{/* Right: Compact Monthly Usage Chart */}
1068-
<div className="flex flex-col gap-4">
1069-
{/* Chart */}
1070-
<div className="flex h-full flex-col gap-2">
1074+
{/* Right: Charts - Split evenly */}
1075+
<div className="flex h-full flex-col gap-4">
1076+
{/* Usage Chart */}
1077+
<div className="flex min-h-0 flex-1 flex-col gap-2">
10711078
<Small className="font-medium">
10721079
Monthly Usage (Last 12 Months)
10731080
</Small>
10741081
{usageLoading ? (
1075-
<div className="flex h-full w-full items-center justify-center border border-border bg-muted/10">
1082+
<div className="flex min-h-0 w-full flex-1 items-center justify-center border border-border bg-muted/10">
10761083
<div className="flex items-center gap-2">
10771084
<Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
10781085
<Muted className="text-xs">Loading chart data...</Muted>
10791086
</div>
10801087
</div>
10811088
) : usageData?.monthly_usage ? (
1082-
<div className="w-full flex-1">
1089+
<div className="min-h-0 w-full flex-1">
10831090
<ChartContainer
10841091
config={{
10851092
requestCount: {
10861093
label: "Requests",
10871094
color: "hsl(200 90% 50%)",
10881095
},
10891096
}}
1090-
className="aspect-auto h-full w-full"
1097+
className="h-full w-full"
10911098
>
10921099
<BarChart
10931100
data={sortAndFormatMonthlyUsage(
@@ -1127,7 +1134,74 @@ const OrgTableRow = ({
11271134
</ChartContainer>
11281135
</div>
11291136
) : (
1130-
<div className="flex h-full w-full items-center justify-center border border-border bg-muted/10">
1137+
<div className="flex min-h-0 w-full flex-1 items-center justify-center border border-border bg-muted/10">
1138+
<Muted className="text-xs">Unable to load chart data</Muted>
1139+
</div>
1140+
)}
1141+
</div>
1142+
1143+
{/* Cost Chart */}
1144+
<div className="flex min-h-0 flex-1 flex-col gap-2">
1145+
<Small className="font-medium">
1146+
Monthly Cost (Last 12 Months)
1147+
</Small>
1148+
{usageLoading ? (
1149+
<div className="flex min-h-0 w-full flex-1 items-center justify-center border border-border bg-muted/10">
1150+
<div className="flex items-center gap-2">
1151+
<Loader2 className="h-5 w-5 animate-spin text-muted-foreground" />
1152+
<Muted className="text-xs">Loading chart data...</Muted>
1153+
</div>
1154+
</div>
1155+
) : usageData?.monthly_usage ? (
1156+
<div className="min-h-0 w-full flex-1">
1157+
<ChartContainer
1158+
config={{
1159+
cost: {
1160+
label: "Cost",
1161+
color: "hsl(142 76% 36%)",
1162+
},
1163+
}}
1164+
className="h-full w-full"
1165+
>
1166+
<BarChart
1167+
data={sortAndFormatMonthlyUsage(
1168+
usageData.monthly_usage,
1169+
)}
1170+
margin={{ top: 5, right: 5, left: 5, bottom: 0 }}
1171+
>
1172+
<CartesianGrid
1173+
vertical={false}
1174+
strokeDasharray="3 3"
1175+
opacity={0.2}
1176+
/>
1177+
<XAxis
1178+
dataKey="month"
1179+
tickLine={false}
1180+
tickMargin={8}
1181+
axisLine={false}
1182+
tickFormatter={(value) => value.slice(0, 3)}
1183+
fontSize={11}
1184+
/>
1185+
<ChartTooltip
1186+
content={
1187+
<ChartTooltipContent
1188+
valueFormatter={(value) =>
1189+
`$${(value as number).toFixed(2)}`
1190+
}
1191+
/>
1192+
}
1193+
/>
1194+
<Bar
1195+
dataKey="cost"
1196+
fill="var(--color-cost)"
1197+
radius={[3, 3, 0, 0]}
1198+
maxBarSize={35}
1199+
/>
1200+
</BarChart>
1201+
</ChartContainer>
1202+
</div>
1203+
) : (
1204+
<div className="flex min-h-0 w-full flex-1 items-center justify-center border border-border bg-muted/10">
11311205
<Muted className="text-xs">Unable to load chart data</Muted>
11321206
</div>
11331207
)}

web/lib/clients/jawnTypes/private.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19509,6 +19509,8 @@ export interface operations {
1950919509
/** Format: double */
1951019510
all_time_count: number;
1951119511
monthly_usage: {
19512+
/** Format: double */
19513+
cost: number;
1951219514
/** Format: double */
1951319515
requestCount: number;
1951419516
month: string;

0 commit comments

Comments
 (0)