From 7bceb475a95a8197e9c1bb3d1417481b4e91eaff Mon Sep 17 00:00:00 2001 From: Anthony Ettinger Date: Tue, 6 Oct 2026 18:40:28 +0000 Subject: [PATCH] Add public GET /api/health with a database check Returns 200 {"status":"ok","db":"ok"} after a select 1 (3s ceiling), 503 {"status":"error","db":"down"} otherwise. No auth, no-store, no error details. For status.profullstack.com. Co-Authored-By: Claude Opus 5.5 --- app/api/health/route.ts | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 app/api/health/route.ts diff --git a/app/api/health/route.ts b/app/api/health/route.ts new file mode 100644 index 0000000..802bc5a --- /dev/null +++ b/app/api/health/route.ts @@ -0,0 +1,27 @@ +import { NextResponse } from "next/server"; +import { db } from "@/lib/db"; + +export const runtime = "nodejs"; +export const dynamic = "force-dynamic"; + +const DB_TIMEOUT_MS = 3000; +const headers = { "Cache-Control": "no-store" }; + +// Public health check for status.profullstack.com: one `select 1` with a 3s +// ceiling. No auth and no error details in the response. +export async function GET() { + let timer: ReturnType | undefined; + try { + await Promise.race([ + db().execute("select 1"), + new Promise((_, reject) => { + timer = setTimeout(() => reject(new Error("timeout")), DB_TIMEOUT_MS); + }), + ]); + return NextResponse.json({ status: "ok", db: "ok" }, { headers }); + } catch { + return NextResponse.json({ status: "error", db: "down" }, { status: 503, headers }); + } finally { + clearTimeout(timer); + } +}