From f225f911f889d86a4201979a549fb46e57c91959 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 08:08:08 +0000 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=A7=B9=20[=E3=82=B3=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=81=AE=E5=81=A5=E5=85=A8=E6=80=A7=E5=90=91=E4=B8=8A]=20Dashb?= =?UTF-8?q?oard=20API=E3=83=AB=E3=83=BC=E3=83=88=E3=81=AE=E5=85=B1?= =?UTF-8?q?=E9=80=9A=E5=87=A6=E7=90=86=E3=82=92=E3=83=AA=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=AF=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: is0692vs <135803462+is0692vs@users.noreply.github.com> --- src/app/api/dashboard/stats/route.ts | 32 +++++++++++--------------- src/app/api/dashboard/summary/route.ts | 24 ++++++++----------- src/app/api/dashboard/year/route.ts | 32 +++++++++++--------------- src/lib/apiUtils.ts | 21 +++++++++++++++++ 4 files changed, 56 insertions(+), 53 deletions(-) create mode 100644 src/lib/apiUtils.ts diff --git a/src/app/api/dashboard/stats/route.ts b/src/app/api/dashboard/stats/route.ts index 84c997d..0352c3e 100644 --- a/src/app/api/dashboard/stats/route.ts +++ b/src/app/api/dashboard/stats/route.ts @@ -1,31 +1,25 @@ import { NextRequest, NextResponse } from "next/server"; -import { getServerSession } from "next-auth"; +import { getAuthenticatedUser, handleErrorResponse } from "@/lib/apiUtils"; -import { authOptions } from "@/lib/auth"; -import { fetchViewerLogin } from "@/lib/githubViewer"; import { fetchCommitActivityHeatmap } from "@/lib/githubYearInReview"; export async function GET(request: NextRequest) { - const session = await getServerSession(authOptions); - const token = session?.accessToken; + try { + const user = await getAuthenticatedUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } - if (!session || !token) { - return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); - } + const yearParam = request.nextUrl.searchParams.get("year"); + const year = yearParam ? Number.parseInt(yearParam, 10) : new Date().getUTCFullYear(); - const yearParam = request.nextUrl.searchParams.get("year"); - const year = yearParam ? Number.parseInt(yearParam, 10) : new Date().getUTCFullYear(); + if (!Number.isFinite(year) || year < 2008 || year > new Date().getUTCFullYear()) { + return NextResponse.json({ error: "Invalid year" }, { status: 400 }); + } - if (!Number.isFinite(year) || year < 2008 || year > new Date().getUTCFullYear()) { - return NextResponse.json({ error: "Invalid year" }, { status: 400 }); - } - - try { - const username = session.user?.login ?? (await fetchViewerLogin(token)); - const heatmap = await fetchCommitActivityHeatmap(username, year, token); + const heatmap = await fetchCommitActivityHeatmap(user.username, year, user.token); return NextResponse.json({ year, heatmap }); } catch (error) { - const message = error instanceof Error ? error.message : "Unknown error"; - return NextResponse.json({ error: message }, { status: 500 }); + return handleErrorResponse(error); } } diff --git a/src/app/api/dashboard/summary/route.ts b/src/app/api/dashboard/summary/route.ts index b99930c..7292c8e 100644 --- a/src/app/api/dashboard/summary/route.ts +++ b/src/app/api/dashboard/summary/route.ts @@ -1,24 +1,18 @@ import { NextResponse } from "next/server"; -import { getServerSession } from "next-auth"; +import { getAuthenticatedUser, handleErrorResponse } from "@/lib/apiUtils"; -import { authOptions } from "@/lib/auth"; import { fetchUserSummary } from "@/lib/github"; -import { fetchViewerLogin } from "@/lib/githubViewer"; export async function GET() { - const session = await getServerSession(authOptions); - const token = session?.accessToken; - - if (!session || !token) { - return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); - } - try { - const username = session.user?.login ?? (await fetchViewerLogin(token)); - const summary = await fetchUserSummary(username, token); - return NextResponse.json({ username, summary }); + const user = await getAuthenticatedUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } + + const summary = await fetchUserSummary(user.username, user.token); + return NextResponse.json({ username: user.username, summary }); } catch (error) { - const message = error instanceof Error ? error.message : "Unknown error"; - return NextResponse.json({ error: message }, { status: 500 }); + return handleErrorResponse(error); } } diff --git a/src/app/api/dashboard/year/route.ts b/src/app/api/dashboard/year/route.ts index 10e757f..b858132 100644 --- a/src/app/api/dashboard/year/route.ts +++ b/src/app/api/dashboard/year/route.ts @@ -1,31 +1,25 @@ import { NextRequest, NextResponse } from "next/server"; -import { getServerSession } from "next-auth"; +import { getAuthenticatedUser, handleErrorResponse } from "@/lib/apiUtils"; -import { authOptions } from "@/lib/auth"; -import { fetchViewerLogin } from "@/lib/githubViewer"; import { fetchYearInReviewData } from "@/lib/githubYearInReview"; export async function GET(request: NextRequest) { - const session = await getServerSession(authOptions); - const token = session?.accessToken; + try { + const user = await getAuthenticatedUser(); + if (!user) { + return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); + } - if (!session || !token) { - return NextResponse.json({ error: "Unauthorized" }, { status: 401 }); - } + const yearParam = request.nextUrl.searchParams.get("year"); + const year = yearParam ? Number.parseInt(yearParam, 10) : new Date().getUTCFullYear(); - const yearParam = request.nextUrl.searchParams.get("year"); - const year = yearParam ? Number.parseInt(yearParam, 10) : new Date().getUTCFullYear(); + if (!Number.isFinite(year) || year < 2008 || year > new Date().getUTCFullYear()) { + return NextResponse.json({ error: "Invalid year" }, { status: 400 }); + } - if (!Number.isFinite(year) || year < 2008 || year > new Date().getUTCFullYear()) { - return NextResponse.json({ error: "Invalid year" }, { status: 400 }); - } - - try { - const username = session.user?.login ?? (await fetchViewerLogin(token)); - const data = await fetchYearInReviewData(username, year, token); + const data = await fetchYearInReviewData(user.username, year, user.token); return NextResponse.json(data); } catch (error) { - const message = error instanceof Error ? error.message : "Unknown error"; - return NextResponse.json({ error: message }, { status: 500 }); + return handleErrorResponse(error); } } diff --git a/src/lib/apiUtils.ts b/src/lib/apiUtils.ts new file mode 100644 index 0000000..42258ca --- /dev/null +++ b/src/lib/apiUtils.ts @@ -0,0 +1,21 @@ +import { NextResponse } from "next/server"; +import { getServerSession } from "next-auth"; +import { authOptions } from "@/lib/auth"; +import { fetchViewerLogin } from "@/lib/githubViewer"; + +export async function getAuthenticatedUser() { + const session = await getServerSession(authOptions); + const token = session?.accessToken; + + if (!session || !token) { + return null; + } + + const username = session.user?.login ?? (await fetchViewerLogin(token)); + return { username, token }; +} + +export function handleErrorResponse(error: unknown) { + const message = error instanceof Error ? error.message : "Unknown error"; + return NextResponse.json({ error: message }, { status: 500 }); +} From d3f82368f114fa3633a9a650516fb4a349c78540 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Fri, 17 Apr 2026 08:38:26 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=A7=B9=20[=E3=82=B3=E3=83=BC=E3=83=89?= =?UTF-8?q?=E3=81=AE=E5=81=A5=E5=85=A8=E6=80=A7=E5=90=91=E4=B8=8A]=20Dashb?= =?UTF-8?q?oard=20API=E3=83=AB=E3=83=BC=E3=83=88=E3=81=AE=E5=85=B1?= =?UTF-8?q?=E9=80=9A=E5=87=A6=E7=90=86=E3=82=92=E3=83=AA=E3=83=95=E3=82=A1?= =?UTF-8?q?=E3=82=AF=E3=82=BF=E3=83=AA=E3=83=B3=E3=82=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: is0692vs <135803462+is0692vs@users.noreply.github.com>