export type HealthCheck = () => Promise; type HealthRedis = { ping(): Promise; exists(key: string): Promise; get(key: string): Promise; setex(key: string, ttl: number, value: string): Promise; }; const checkResult = async (check: HealthCheck) => { try { const result = await check(); return result instanceof Response ? result.ok : !!result; } catch { return false; } }; export function createHealthHandler({ redis, checks, }: { redis: HealthRedis; checks: Record; }) { return async function GET() { const red = await redis .ping() .then(() => true) .catch(() => false); const entries = await Promise.all( Object.entries(checks).map(async ([name, check]) => { const key = `health:${name}`; if (red) { try { if (await redis.exists(key)) return [name, (await redis.get(key)) === "ok"] as const; } catch {} } const healthy = await checkResult(check); if (red && healthy) { try { await redis.setex(key, 900, "ok"); } catch {} } return [name, healthy] as const; }), ); const results = Object.fromEntries(entries) as Record; return Response.json( { red, ...results }, { status: red && results.database ? 200 : 503 }, ); }; }