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