Files
Epicnabbo-Catalogus-Updated…/src/app/api/health/route.ts
T
SimoandCursor 968ca15c27 feat: jwt cache, redis health, help-ticket admin, and write rate limits
Cut Auth.js DB load with cached jwtVersion checks, surface Redis in /api/health and deploy warnings, add admin help-center ticket reply UI, rate-limit API tickets/reactions/referral claims, and revoke PATs on sign-out-everywhere.

Co-authored-by: Cursor <[email protected]>
2026-07-21 21:58:48 +02:00

65 lines
1.6 KiB
TypeScript

import { env } from "@/env";
import { apiJson } from "@/lib/api";
import { prisma } from "@/lib/prisma";
import { redis } from "@/lib/redis";
import { rcon } from "@/lib/services/rcon";
export const dynamic = "force-dynamic";
/**
* Ops health probe: database reachability, Redis (when configured), emulator
* RCON, SMTP (when configured), and runtime info. Returns HTTP 200 always
* (read the `status`/`database` fields), so it's safe for uptime monitors that
* only care about reachability.
*/
export async function GET() {
const database = await prisma.$queryRaw`SELECT 1`
.then(() => true)
.catch(() => false);
let redisOk: boolean | null = null;
if (env.REDIS_URL) {
if (!redis) {
redisOk = false;
} else {
try {
const pong = await redis.ping();
redisOk = pong === "PONG";
} catch {
redisOk = false;
}
}
}
const emulator = await rcon.send("ping", null).catch(() => false);
let smtp = null;
if (env.SMTP_HOST) {
const nodemailer = await import("nodemailer");
const test = nodemailer.createTransport({
host: env.SMTP_HOST,
port: env.SMTP_PORT,
secure: env.SMTP_SECURE,
auth: env.SMTP_USER
? { user: env.SMTP_USER, pass: env.SMTP_PASSWORD ?? "" }
: undefined,
});
smtp = await test
.verify()
.then(() => true)
.catch(() => false);
}
const degraded = !database || redisOk === false;
return apiJson({
status: degraded ? "degraded" : "ok",
database,
redis: redisOk,
emulator,
smtp,
node: process.version,
uptime: Math.round(process.uptime()),
time: new Date().toISOString(),
});
}