Files
EpicNext-Cms/src/features/catalog/server/sync-status.ts
T
Simo 193b6686a9
CI / check (push) Successful in 1m16s
CI / deploy (push) Successful in 28s
refactor(catalog): unify commands and embed guarded catalog workspace
2026-09-06 19:40:52 +02:00

60 lines
1.7 KiB
TypeScript

import "server-only";
import { randomUUID } from "node:crypto";
import fs from "node:fs/promises";
import path from "node:path";
import { logger } from "@/lib/logger";
import { catalogStateRoot } from "@/lib/services/catalog-git-config";
import { rcon } from "@/lib/services/rcon";
export interface CatalogHotelStatus {
sent: boolean;
checkedAt: string;
reference?: string;
}
export async function readCatalogHotelStatus(): Promise<CatalogHotelStatus | null> {
try {
return JSON.parse(
await fs.readFile(
path.join(catalogStateRoot(), "hotel-status.json"),
"utf8",
),
);
} catch (error) {
if ((error as NodeJS.ErrnoException).code === "ENOENT") return null;
throw error;
}
}
/** An acknowledged socket write is an update request, not proof of client application. */
export async function sendCatalogUpdate(): Promise<CatalogHotelStatus> {
let sent = false;
let reference: string | undefined;
try {
sent = await rcon.updateCatalog();
if (!sent)
reference = logger.error(
"Catalog saved; hotel update was not delivered",
{ module: "catalog" },
);
} catch (error) {
reference = logger.error("Catalog saved; hotel update failed", {
module: "catalog",
error,
});
}
const status = { sent, checkedAt: new Date().toISOString(), reference };
const root = catalogStateRoot();
const temp = path.join(root, `hotel-${randomUUID()}.tmp`);
try {
await fs.mkdir(root, { recursive: true });
await fs.writeFile(temp, JSON.stringify(status), { flag: "wx" });
await fs.rename(temp, path.join(root, "hotel-status.json"));
} catch (error) {
logger.error("Cannot persist catalog hotel update status", {
module: "catalog",
error,
});
} finally {
await fs.rm(temp, { force: true }).catch(() => {});
}
return status;
}