包含 classes/exams/homework/grades/attendance/scheduling 域、outbox、iam-consumer、redis 配置等完整实现
76 lines
1.7 KiB
TypeScript
76 lines
1.7 KiB
TypeScript
import { Controller, Get, HttpException, HttpStatus } from "@nestjs/common";
|
|
import { sql } from "drizzle-orm";
|
|
import { db } from "../../config/database.js";
|
|
import { isRedisHealthy } from "../../config/redis.js";
|
|
import { isKafkaConnected } from "../../config/kafka.js";
|
|
|
|
const SERVICE_NAME = "core-edu";
|
|
|
|
interface HealthResponse {
|
|
status: string;
|
|
service: string;
|
|
timestamp: string;
|
|
checks?: Record<string, string>;
|
|
}
|
|
|
|
@Controller()
|
|
export class HealthController {
|
|
@Get("healthz")
|
|
liveness(): HealthResponse {
|
|
return {
|
|
status: "ok",
|
|
service: SERVICE_NAME,
|
|
timestamp: new Date().toISOString(),
|
|
};
|
|
}
|
|
|
|
@Get("readyz")
|
|
async readiness(): Promise<HealthResponse> {
|
|
const checks: Record<string, string> = {};
|
|
let allHealthy = true;
|
|
|
|
// DB check
|
|
try {
|
|
await db.execute(sql`SELECT 1`);
|
|
checks.db = "ok";
|
|
} catch (error) {
|
|
checks.db = error instanceof Error ? error.message : "unreachable";
|
|
allHealthy = false;
|
|
}
|
|
|
|
// Redis check (optional - degrade gracefully)
|
|
try {
|
|
const redisOk = await isRedisHealthy();
|
|
checks.redis = redisOk ? "ok" : "disabled";
|
|
} catch {
|
|
checks.redis = "disabled";
|
|
}
|
|
|
|
// Kafka check (optional - degrade gracefully)
|
|
try {
|
|
checks.kafka = isKafkaConnected() ? "ok" : "disconnected";
|
|
} catch {
|
|
checks.kafka = "unknown";
|
|
}
|
|
|
|
if (!allHealthy) {
|
|
throw new HttpException(
|
|
{
|
|
status: "error",
|
|
service: SERVICE_NAME,
|
|
timestamp: new Date().toISOString(),
|
|
checks,
|
|
},
|
|
HttpStatus.SERVICE_UNAVAILABLE,
|
|
);
|
|
}
|
|
|
|
return {
|
|
status: "ok",
|
|
service: SERVICE_NAME,
|
|
timestamp: new Date().toISOString(),
|
|
checks,
|
|
};
|
|
}
|
|
}
|