69 lines
1.5 KiB
TypeScript
69 lines
1.5 KiB
TypeScript
|
|
import { NextResponse } from 'next/server';
|
||
|
|
import { db } from '@/lib/db';
|
||
|
|
import { redis } from '@/lib/redis';
|
||
|
|
import { minioClient } from '@/lib/minio';
|
||
|
|
import { env } from '@/lib/env';
|
||
|
|
import { sql } from 'drizzle-orm';
|
||
|
|
|
||
|
|
type CheckStatus = 'ok' | 'error';
|
||
|
|
|
||
|
|
interface HealthChecks {
|
||
|
|
postgres: CheckStatus;
|
||
|
|
redis: CheckStatus;
|
||
|
|
minio: CheckStatus;
|
||
|
|
}
|
||
|
|
|
||
|
|
interface HealthResponse {
|
||
|
|
status: 'healthy' | 'degraded';
|
||
|
|
checks: HealthChecks;
|
||
|
|
timestamp: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export async function GET(): Promise<NextResponse<HealthResponse>> {
|
||
|
|
const checks: HealthChecks = {
|
||
|
|
postgres: 'error',
|
||
|
|
redis: 'error',
|
||
|
|
minio: 'error',
|
||
|
|
};
|
||
|
|
|
||
|
|
await Promise.allSettled([
|
||
|
|
db
|
||
|
|
.execute(sql`SELECT 1`)
|
||
|
|
.then(() => {
|
||
|
|
checks.postgres = 'ok';
|
||
|
|
})
|
||
|
|
.catch(() => {
|
||
|
|
checks.postgres = 'error';
|
||
|
|
}),
|
||
|
|
|
||
|
|
redis
|
||
|
|
.ping()
|
||
|
|
.then(() => {
|
||
|
|
checks.redis = 'ok';
|
||
|
|
})
|
||
|
|
.catch(() => {
|
||
|
|
checks.redis = 'error';
|
||
|
|
}),
|
||
|
|
|
||
|
|
minioClient
|
||
|
|
.bucketExists(env.MINIO_BUCKET)
|
||
|
|
.then(() => {
|
||
|
|
checks.minio = 'ok';
|
||
|
|
})
|
||
|
|
.catch(() => {
|
||
|
|
checks.minio = 'error';
|
||
|
|
}),
|
||
|
|
]);
|
||
|
|
|
||
|
|
const allHealthy = Object.values(checks).every((s) => s === 'ok');
|
||
|
|
const status: HealthResponse['status'] = allHealthy ? 'healthy' : 'degraded';
|
||
|
|
|
||
|
|
const body: HealthResponse = {
|
||
|
|
status,
|
||
|
|
checks,
|
||
|
|
timestamp: new Date().toISOString(),
|
||
|
|
};
|
||
|
|
|
||
|
|
return NextResponse.json(body, { status: allHealthy ? 200 : 503 });
|
||
|
|
}
|