diff --git a/src/app/api/metrics/contributions/hourly/route.ts b/src/app/api/metrics/contributions/hourly/route.ts index 7b32e8a2..601e34e3 100644 --- a/src/app/api/metrics/contributions/hourly/route.ts +++ b/src/app/api/metrics/contributions/hourly/route.ts @@ -33,39 +33,44 @@ export async function GET(req: NextRequest) { ttlSeconds: METRICS_CACHE_TTL_SECONDS.contributions, }, async () => { - const since = new Date(); + const since = new Date(); since.setDate(since.getDate() - days); const sinceStr = since.toISOString().slice(0, 10); - const searchRes = await fetch( - `${GITHUB_API}/search/commits?q=author:${session.githubLogin}+author-date:>=${sinceStr}&per_page=100&sort=author-date&order=desc`, - { - headers: { - Authorization: `Bearer ${session.accessToken}`, - Accept: "application/vnd.github+json", - }, - cache: "no-store", - } - ); + const allItems: Array<{ commit: { author: { date: string } } }> = []; + let page = 1; - if (!searchRes.ok) throw new Error("GitHub API error"); - - const data = (await searchRes.json()) as { - items: Array<{ commit: { author: { date: string } } }>; - }; + while (true) { + const searchRes = await fetch( + `${GITHUB_API}/search/commits?q=author:${session.githubLogin}+author-date:>=${sinceStr}&per_page=100&page=${page}&sort=author-date&order=desc`, + { + headers: { + Authorization: `Bearer ${session.accessToken}`, + Accept: "application/vnd.github+json", + }, + cache: "no-store", + } + ); + if (!searchRes.ok) throw new Error("GitHub API error"); + const data = (await searchRes.json()) as { + items: Array<{ commit: { author: { date: string } } }>; + }; + allItems.push(...data.items); + if (data.items.length < 100 || page >= 10) break; + page++; + } // Initialize all 24 hours to 0 const hourMap: Record = {}; for (let i = 0; i < 24; i++) hourMap[i] = 0; - // NOTE: date.getHours() returns UTC hours from the server, - // not the user's local timezone. The client displays these as-is. - for (const item of data.items) { + for (const item of allItems) { const date = new Date(item.commit.author.date); const hour = date.getHours(); hourMap[hour]++; } + const hours = Array.from({ length: 24 }, (_, i) => ({ hour: i, commits: hourMap[i], diff --git a/src/app/api/metrics/weekly-summary/route.ts b/src/app/api/metrics/weekly-summary/route.ts index e23d6575..88777f27 100644 --- a/src/app/api/metrics/weekly-summary/route.ts +++ b/src/app/api/metrics/weekly-summary/route.ts @@ -41,13 +41,26 @@ function calculateCurrentStreak(activeDates: Set): number { async function fetchActiveDates(githubLogin: string, token: string): Promise> { const since = new Date(); since.setDate(since.getDate() - 90); - const searchRes = await fetch( - `${GITHUB_API}/search/commits?q=author:${githubLogin}+author-date:>=${since.toISOString().slice(0, 10)}&per_page=100&sort=author-date&order=desc`, - { headers: { Authorization: `Bearer ${token}`, Accept: "application/vnd.github+json" }, cache: "no-store" } - ); - if (!searchRes.ok) throw new Error("GitHub API error"); - const data = (await searchRes.json()) as { items: Array<{ commit: { author: { date: string } } }> }; - return new Set(data.items.map(item => item.commit.author.date.slice(0, 10))); + const sinceStr = since.toISOString().slice(0, 10); + + const activeDates = new Set(); + let page = 1; + + while (true) { + const searchRes = await fetch( + `${GITHUB_API}/search/commits?q=author:${githubLogin}+author-date:>=${sinceStr}&per_page=100&page=${page}&sort=author-date&order=desc`, + { headers: { Authorization: `Bearer ${token}`, Accept: "application/vnd.github+json" }, cache: "no-store" } + ); + if (!searchRes.ok) throw new Error("GitHub API error"); + const data = (await searchRes.json()) as { items: Array<{ commit: { author: { date: string } } }> }; + for (const item of data.items) { + activeDates.add(item.commit.author.date.slice(0, 10)); + } + if (data.items.length < 100 || page >= 10) break; + page++; + } + + return activeDates; } export async function GET(req: NextRequest) {