Files
Edu/services/core-edu/src/shared/health/health.controller.ts
SpecialX 58c0ba1bd9 feat(core-edu): 完整实现 core-edu 教学核心服务
包含 classes/exams/homework/grades/attendance/scheduling 域、outbox、iam-consumer、redis 配置等完整实现
2026-07-10 19:08:56 +08:00

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,
};
}
}