From 08fa6ef801ee339af0634268b7b0ddc1e96693ed Mon Sep 17 00:00:00 2001 From: vipul674 Date: Wed, 17 Jun 2026 23:05:10 +0530 Subject: [PATCH 1/4] fix: report correct cache status for cold requests X-Cache-Status was always HIT when bypassCache was not requested, even for first-time/cold requests where no cache entry existed. Now checks if the cache had data before the fetch and reports MISS for cold requests. Fixes #5503 --- app/api/stats/route.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/app/api/stats/route.ts b/app/api/stats/route.ts index 9a6a7ba95..8e0c39ba9 100644 --- a/app/api/stats/route.ts +++ b/app/api/stats/route.ts @@ -1,6 +1,6 @@ // app/api/stats/route.ts import { NextResponse } from 'next/server'; -import { fetchGitHubContributions } from '@/lib/github'; +import { fetchGitHubContributions, contributionsCache, cacheKey } from '@/lib/github'; import { calculateStreak } from '@/lib/calculate'; import { statsParamsSchema } from '@/lib/validations'; import { getClientIp } from '@/utils/getClientIp'; @@ -122,6 +122,9 @@ export async function GET(request: Request) { } try { + const key = cacheKey('contributions', user); + const wasCachedBefore = await contributionsCache.has(key); + // Authenticated -> user's OAuth token (their quota); anonymous -> undefined (global PAT). const userToken = await getUserGitHubToken(); const userData = await fetchGitHubContributions(user, { @@ -144,7 +147,7 @@ export async function GET(request: Request) { headers.set('Pragma', 'no-cache'); headers.set('Expires', '0'); } - headers.set('X-Cache-Status', shouldBypassCache ? 'MISS' : 'HIT'); + headers.set('X-Cache-Status', shouldBypassCache ? 'MISS' : wasCachedBefore ? 'HIT' : 'MISS'); headers.set( 'X-Refresh-Status', shouldBypassCache ? 'Fresh' : isRefreshRequested ? 'Cooldown-Served-Cached' : 'Cached' From dbf918db085804c89df2fcfa1715ab29401227cc Mon Sep 17 00:00:00 2001 From: vipul674 Date: Thu, 18 Jun 2026 14:22:18 +0530 Subject: [PATCH 2/4] fix(stats): add missing mocks for getUserGitHubToken and contributionsCache in validation tests --- app/api/stats/route.validation.test.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/api/stats/route.validation.test.ts b/app/api/stats/route.validation.test.ts index b15d2fc68..9b3ca047e 100644 --- a/app/api/stats/route.validation.test.ts +++ b/app/api/stats/route.validation.test.ts @@ -3,6 +3,12 @@ import { GET } from './route'; vi.mock('@/lib/github', () => ({ fetchGitHubContributions: vi.fn(), + contributionsCache: { has: vi.fn().mockResolvedValue(true) }, + cacheKey: vi.fn().mockReturnValue('key'), +})); + +vi.mock('@/lib/githubtoken', () => ({ + getUserGitHubToken: vi.fn().mockResolvedValue(undefined), })); import { fetchGitHubContributions } from '@/lib/github'; From 0744c223687f4521797ba8b7d6c45da91db2b305 Mon Sep 17 00:00:00 2001 From: vipul674 Date: Sun, 21 Jun 2026 11:32:42 +0530 Subject: [PATCH 3/4] fix(test): add contributionsCache and cacheKey mocks to stats empty-fallback test --- app/api/stats/route.empty-fallback.test.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/api/stats/route.empty-fallback.test.ts b/app/api/stats/route.empty-fallback.test.ts index e04351b2b..7797b8d70 100644 --- a/app/api/stats/route.empty-fallback.test.ts +++ b/app/api/stats/route.empty-fallback.test.ts @@ -4,6 +4,8 @@ import type { ContributionCalendar } from '../../../types'; vi.mock('../../../lib/github', () => ({ fetchGitHubContributions: vi.fn(), + contributionsCache: { has: vi.fn().mockResolvedValue(false) }, + cacheKey: vi.fn().mockReturnValue('key'), })); import { fetchGitHubContributions } from '../../../lib/github'; From 2a1f7996cfeb8edd0a8c131ce434bdf176fa4ee0 Mon Sep 17 00:00:00 2001 From: vipul674 Date: Sun, 21 Jun 2026 11:49:36 +0530 Subject: [PATCH 4/4] fix(test): add contributionsCache and cacheKey mocks to remaining stats test files --- app/api/stats/route.mouse-interactivity.test.ts | 2 ++ app/api/stats/route.test.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/api/stats/route.mouse-interactivity.test.ts b/app/api/stats/route.mouse-interactivity.test.ts index 790038cd5..4de5099c4 100644 --- a/app/api/stats/route.mouse-interactivity.test.ts +++ b/app/api/stats/route.mouse-interactivity.test.ts @@ -8,6 +8,8 @@ import type { ContributionCalendar, ExtendedContributionData } from '@/types'; vi.mock('@/lib/github', () => ({ fetchGitHubContributions: vi.fn(), + contributionsCache: { has: vi.fn().mockResolvedValue(false) }, + cacheKey: vi.fn().mockReturnValue('key'), })); const mockCalendar: ContributionCalendar = { diff --git a/app/api/stats/route.test.ts b/app/api/stats/route.test.ts index afafd7f0f..ad3062328 100644 --- a/app/api/stats/route.test.ts +++ b/app/api/stats/route.test.ts @@ -3,6 +3,8 @@ import { GET } from './route'; vi.mock('../../../lib/github', () => ({ fetchGitHubContributions: vi.fn(), + contributionsCache: { has: vi.fn().mockResolvedValue(false) }, + cacheKey: vi.fn().mockReturnValue('key'), })); import { fetchGitHubContributions } from '../../../lib/github';