78 lines
1.9 KiB
TypeScript
78 lines
1.9 KiB
TypeScript
import fs from "node:fs/promises";
|
|
import path from "node:path";
|
|
import { getDb, isDatabaseConfigured } from "../db";
|
|
import { ENV } from "./env";
|
|
|
|
type RuntimeHealthState = "starting" | "ready" | "maintenance" | "shutting_down";
|
|
|
|
const startedAt = Date.now();
|
|
let ready = false;
|
|
let shuttingDown = false;
|
|
|
|
function resolveMaintenanceFlagPath() {
|
|
return path.resolve(ENV.maintenanceFlagPath || path.join(process.cwd(), "uploads/system/maintenance.flag"));
|
|
}
|
|
|
|
async function fileExists(filePath: string) {
|
|
try {
|
|
await fs.access(filePath);
|
|
return true;
|
|
} catch {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
export function markRuntimeReady() {
|
|
ready = true;
|
|
}
|
|
|
|
export function markRuntimeShuttingDown() {
|
|
shuttingDown = true;
|
|
ready = false;
|
|
}
|
|
|
|
export async function isMaintenanceModeEnabled() {
|
|
return fileExists(resolveMaintenanceFlagPath());
|
|
}
|
|
|
|
export async function buildRuntimeHealth() {
|
|
const uptimeMs = Date.now() - startedAt;
|
|
const db = await getDb();
|
|
const databaseOk = !isDatabaseConfigured() || Boolean(db);
|
|
const startupDelaySatisfied = uptimeMs >= ENV.appReadyDelayMs;
|
|
const maintenance = await isMaintenanceModeEnabled();
|
|
|
|
let state: RuntimeHealthState = "starting";
|
|
if (shuttingDown) {
|
|
state = "shutting_down";
|
|
} else if (maintenance) {
|
|
state = "maintenance";
|
|
} else if (ready && startupDelaySatisfied && databaseOk) {
|
|
state = "ready";
|
|
}
|
|
|
|
const ok = state === "ready" || state === "maintenance";
|
|
|
|
return {
|
|
ok,
|
|
state,
|
|
service: "portail-associations",
|
|
environment: process.env.NODE_ENV || "development",
|
|
timestamp: new Date().toISOString(),
|
|
uptimeMs,
|
|
maintenance,
|
|
checks: {
|
|
startupDelaySatisfied,
|
|
databaseConfigured: isDatabaseConfigured(),
|
|
databaseOk,
|
|
ready,
|
|
shuttingDown,
|
|
},
|
|
};
|
|
}
|
|
|
|
export async function ensureMaintenanceFlagDirectory() {
|
|
const filePath = resolveMaintenanceFlagPath();
|
|
await fs.mkdir(path.dirname(filePath), { recursive: true });
|
|
return filePath;
|
|
}
|