feat: add 5-min in-memory cache to dashboard stats endpoint

This commit is contained in:
2026-05-16 17:02:48 +08:00
parent e7a48d4e6f
commit 64b026386d
+53 -1
View File
@@ -10,6 +10,51 @@ import {
import { eq, count, sql, gte, and, desc } from "drizzle-orm";
import { requireContributorOrAdmin } from "@/lib/auth/guard";
// In-memory cache for dashboard stats (TTL 300s)
interface DashboardStatsResult {
overview: {
totalGames: number;
totalBenchmarks: number;
totalUsers: number;
pendingReports: number;
pendingSuggestions: number;
};
recent: {
benchmarksLast30Days: number;
gamesLast30Days: number;
};
topContributors: Array<{
userId: string | null;
name: string;
count: number;
}>;
syncHealth: Record<string, number>;
gamesBySource: Record<string, number>;
playabilityDistribution: Record<string, number>;
}
interface CacheEntry<T> {
data: T;
expiresAt: number;
}
const statsCache = new Map<string, CacheEntry<unknown>>();
const STATS_CACHE_TTL = 300_000; // 5 minutes
function getCached<T>(key: string): T | null {
const entry = statsCache.get(key) as CacheEntry<T> | undefined;
if (!entry) return null;
if (Date.now() > entry.expiresAt) {
statsCache.delete(key);
return null;
}
return entry.data;
}
function setCached<T>(key: string, data: T): void {
statsCache.set(key, { data, expiresAt: Date.now() + STATS_CACHE_TTL });
}
export const dashboardRoutes = new Elysia({ prefix: "/dashboard", detail: { tags: ["Dashboard"] } }).get(
"/stats",
async ({ request, set }) => {
@@ -19,6 +64,10 @@ export const dashboardRoutes = new Elysia({ prefix: "/dashboard", detail: { tags
return { error: guard.error };
}
// Check cache
const cached = getCached<DashboardStatsResult>("dashboard_stats");
if (cached) return cached;
const thirtyDaysAgo = new Date();
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
@@ -120,7 +169,7 @@ export const dashboardRoutes = new Elysia({ prefix: "/dashboard", detail: { tags
.groupBy(games.playabilityStatus),
]);
return {
const result = {
overview: {
totalGames: totalGames[0]?.count ?? 0,
totalBenchmarks: totalBenchmarks[0]?.count ?? 0,
@@ -159,5 +208,8 @@ export const dashboardRoutes = new Elysia({ prefix: "/dashboard", detail: { tags
{} as Record<string, number>,
),
};
setCached("dashboard_stats", result);
return result;
},
);