Add cost metrics to analytics dashboard

This commit is contained in:
2026-04-28 11:27:51 +08:00
parent 67e43b02bf
commit ab915e9292
13 changed files with 226 additions and 56 deletions

View File

@@ -130,19 +130,50 @@ export interface TrendPoint {
quota: number;
}
export type TrendGranularity = "hour" | "day" | "week" | "month";
export interface TrendFilters {
username?: string;
model?: string;
channelId?: number;
}
function appendTrendFilters(
where: string,
params: (string | number | boolean | null)[],
filters: TrendFilters = {}
): string {
if (filters.username) {
params.push(filters.username);
where += ` AND username = $${params.length}`;
}
if (filters.model) {
params.push(filters.model);
where += ` AND ${REAL_MODEL} = $${params.length}`;
}
if (filters.channelId !== undefined) {
params.push(filters.channelId);
where += ` AND channel_id = $${params.length}`;
}
return where;
}
export function getTrends(
granularity: "day" | "week" | "month" = "day",
granularity: TrendGranularity = "day",
startTs?: number,
endTs?: number
endTs?: number,
filters: TrendFilters = {}
): Promise<TrendPoint[]> {
return cached(cacheKey("trends", granularity, startTs, endTs), async () => {
return cached(cacheKey("trends", granularity, startTs, endTs, filters.username, filters.model, filters.channelId), async () => {
const params: (string | number | boolean | null)[] = [];
const where = timeWhere(params, startTs, endTs);
const where = appendTrendFilters(timeWhere(params, startTs, endTs), params, filters);
const truncExpr =
granularity === "day"
? `((to_timestamp(created_at) AT TIME ZONE 'Asia/Shanghai')::date)::text`
: `(date_trunc('${granularity}', to_timestamp(created_at) AT TIME ZONE 'Asia/Shanghai')::date)::text`;
granularity === "hour"
? `to_char(date_trunc('hour', to_timestamp(created_at) AT TIME ZONE 'Asia/Shanghai'), 'YYYY-MM-DD HH24:00')`
: granularity === "day"
? `((to_timestamp(created_at) AT TIME ZONE 'Asia/Shanghai')::date)::text`
: `(date_trunc('${granularity}', to_timestamp(created_at) AT TIME ZONE 'Asia/Shanghai')::date)::text`;
const rows = await query(
`SELECT
@@ -159,7 +190,7 @@ export function getTrends(
);
return rows.map((r) => ({
date: String(r.date).slice(0, 10),
date: String(r.date).slice(0, granularity === "hour" ? 16 : 10),
calls: Number(r.calls),
prompt_tokens: Number(r.prompt_tokens),
completion_tokens: Number(r.completion_tokens),