feat: Healthcheck-Endpunkt für Reverse-Proxy und Monitoring

/api/health prüft die Datenbankverbindung mit und antwortet bei Ausfall mit
503 — eine App ohne Datenbank ist nicht gesund, auch wenn der Prozess läuft.
This commit is contained in:
Florian Wilde
2026-09-01 18:46:55 +02:00
parent 2e8e4df6cf
commit b05dd1b01e
2 changed files with 58 additions and 6 deletions
+34
View File
@@ -0,0 +1,34 @@
import { NextResponse } from "next/server";
import { prisma } from "@/lib/db";
import pkg from "../../../../package.json";
export const dynamic = "force-dynamic";
/**
* Healthcheck für Reverse-Proxy und Uptime-Monitoring.
* Prüft die Datenbankverbindung mit — eine App ohne DB ist nicht gesund.
*/
export async function GET() {
const startedAt = Date.now();
try {
await prisma.$queryRaw`SELECT 1`;
return NextResponse.json({
status: "ok",
version: pkg.version,
database: "ok",
latencyMs: Date.now() - startedAt,
timestamp: new Date().toISOString(),
});
} catch (error) {
return NextResponse.json(
{
status: "error",
version: pkg.version,
database: "unreachable",
message: error instanceof Error ? error.message : "unbekannter Fehler",
timestamp: new Date().toISOString(),
},
{ status: 503 },
);
}
}
+24 -6
View File
@@ -1,7 +1,11 @@
{
"compilerOptions": {
"target": "ES2022",
"lib": ["dom", "dom.iterable", "esnext"],
"lib": [
"dom",
"dom.iterable",
"esnext"
],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
@@ -11,14 +15,28 @@
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"jsx": "react-jsx",
"incremental": true,
"noUncheckedIndexedAccess": true,
"plugins": [{ "name": "next" }],
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./src/*"]
"@/*": [
"./src/*"
]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
"include": [
"next-env.d.ts",
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
".next/dev/types/**/*.ts"
],
"exclude": [
"node_modules"
]
}