From a4641d0b9fe6039a7153571e4d424d4accc96255 Mon Sep 17 00:00:00 2001 From: Charis <26616127+charislam@users.noreply.github.com> Date: Wed, 18 Mar 2026 04:36:19 -0400 Subject: [PATCH] refactor: move /incident-status to app router (#43881) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## I have read the [CONTRIBUTING.md](https://github.com/supabase/supabase/blob/master/CONTRIBUTING.md) file. YES ## What kind of change does this PR introduce? Refactor ## What is the current behavior? `/incident-status` is handled via Pages Router. ## What is the new behavior? `/incident-status` is handled via App Router, enabling use of Vercel Data Cache to cache the upstream fetch. ## Additional context Adding the first App Router route handler triggered `next typegen` (run as `pretypecheck`) to generate `.next/dev/types/validator.ts`, which imports all route files and expanded the type-checked graph. This surfaced pre-existing `null`-safety errors in: - `components/grid/SupabaseGrid.utils.ts` — `useSearchParams()` result - `components/layouts/ProjectLayout/UpgradingState/index.tsx` — `useSearchParams()` result - `pages/project/[ref]/sql/quickstarts.tsx` — `useParams()` result - `pages/project/[ref]/sql/templates.tsx` — `useParams()` result These are fixed with optional chaining. The `tsconfig.json` change (adding `.next/dev/types/**/*.ts` to `include`) is auto-generated by Next.js and committed as correct behavior. --- .../api/incident-status/route.ts} | 50 +++++++++++-------- .../components/grid/SupabaseGrid.utils.ts | 4 +- .../ProjectLayout/UpgradingState/index.tsx | 2 +- apps/studio/lib/api/incident-status.ts | 5 +- .../pages/project/[ref]/sql/quickstarts.tsx | 2 +- .../pages/project/[ref]/sql/templates.tsx | 2 +- apps/studio/tsconfig.json | 3 +- 7 files changed, 37 insertions(+), 31 deletions(-) rename apps/studio/{pages/api/incident-status.ts => app/api/incident-status/route.ts} (72%) diff --git a/apps/studio/pages/api/incident-status.ts b/apps/studio/app/api/incident-status/route.ts similarity index 72% rename from apps/studio/pages/api/incident-status.ts rename to apps/studio/app/api/incident-status/route.ts index ded8eb02d98..456806054a9 100644 --- a/apps/studio/pages/api/incident-status.ts +++ b/apps/studio/app/api/incident-status/route.ts @@ -1,5 +1,5 @@ import { IS_PLATFORM } from 'common' -import { NextApiRequest, NextApiResponse } from 'next' +import { NextResponse } from 'next/server' import { InternalServerError } from '@/lib/api/apiHelpers' import { getActiveIncidents, type IncidentCache } from '@/lib/api/incident-status' @@ -42,22 +42,26 @@ async function fetchIncidentCache(incidentIds: Array): Promise { - const sort = searchParams.getAll('sort') - const filter = searchParams.getAll('filter') + const sort = searchParams?.getAll('sort') ?? [] + const filter = searchParams?.getAll('filter') ?? [] return { sort, filter } }, [searchParams]) diff --git a/apps/studio/components/layouts/ProjectLayout/UpgradingState/index.tsx b/apps/studio/components/layouts/ProjectLayout/UpgradingState/index.tsx index 42ed5734c16..7a115e941a9 100644 --- a/apps/studio/components/layouts/ProjectLayout/UpgradingState/index.tsx +++ b/apps/studio/components/layouts/ProjectLayout/UpgradingState/index.tsx @@ -36,7 +36,7 @@ export const UpgradingState = () => { { projectRef: ref, projectStatus: project?.status, - trackingId: queryParams.get('trackingId'), + trackingId: queryParams?.get('trackingId'), }, { enabled: IS_PLATFORM, diff --git a/apps/studio/lib/api/incident-status.ts b/apps/studio/lib/api/incident-status.ts index 0ea751dcae9..670aa261a0c 100644 --- a/apps/studio/lib/api/incident-status.ts +++ b/apps/studio/lib/api/incident-status.ts @@ -1,7 +1,6 @@ -import z from 'zod' - import { IS_PLATFORM } from 'common' import { InternalServerError } from 'lib/api/apiHelpers' +import z from 'zod' export type IncidentCache = { affected_regions: Array | null @@ -81,7 +80,7 @@ export async function getActiveIncidents(): Promise { Accept: 'application/json', 'Content-Type': 'application/json', }, - cache: 'no-store', + next: { revalidate: 180 }, signal: AbortSignal.timeout(30_000), }) const responseText = await response.text() diff --git a/apps/studio/pages/project/[ref]/sql/quickstarts.tsx b/apps/studio/pages/project/[ref]/sql/quickstarts.tsx index 2b69bbc2512..ea7b3b34d43 100644 --- a/apps/studio/pages/project/[ref]/sql/quickstarts.tsx +++ b/apps/studio/pages/project/[ref]/sql/quickstarts.tsx @@ -12,7 +12,7 @@ import type { NextPageWithLayout } from 'types' const SqlQuickstarts: NextPageWithLayout = () => { const router = useRouter() - const { ref } = useParams<{ ref: string }>() + const ref = useParams<{ ref: string }>()?.ref const tabs = useTabsStateSnapshot() useEffect(() => { diff --git a/apps/studio/pages/project/[ref]/sql/templates.tsx b/apps/studio/pages/project/[ref]/sql/templates.tsx index 2e219edaa52..c1e2db63994 100644 --- a/apps/studio/pages/project/[ref]/sql/templates.tsx +++ b/apps/studio/pages/project/[ref]/sql/templates.tsx @@ -12,7 +12,7 @@ import type { NextPageWithLayout } from 'types' const SqlTemplates: NextPageWithLayout = () => { const router = useRouter() - const { ref } = useParams<{ ref: string }>() + const ref = useParams<{ ref: string }>()?.ref const tabs = useTabsStateSnapshot() useEffect(() => { diff --git a/apps/studio/tsconfig.json b/apps/studio/tsconfig.json index 4ae881822a2..f6061f9781c 100644 --- a/apps/studio/tsconfig.json +++ b/apps/studio/tsconfig.json @@ -36,7 +36,8 @@ "**/*.js", "**/*.jsx", ".next/types/**/*.ts", - "./../../packages/ui/src/**/*.d.ts" + "./../../packages/ui/src/**/*.d.ts", + ".next/dev/types/**/*.ts" ], "exclude": ["node_modules", "public/deno/*.ts"] }