import { PERMS } from "@/lib/permission-slugs"; import { authorizeHousekeeping } from "../../foundation/authorization"; import { anyCapability, fail, type HousekeepingCapabilityContext, type HousekeepingWidgetDefinition, ok, } from "../../foundation/contracts"; import { studioOperationRepository } from "./queries/studio"; export const HOTEL_WIDGET_IDS = ["hotel.studio.active-operations"] as const; type HotelWidgetLoader = ( context: HousekeepingCapabilityContext, signal: AbortSignal, ) => Promise>>; export interface HotelWidgetAdapters { readonly activeOperations: HotelWidgetLoader; } export function createHotelWidgets( adapters: HotelWidgetAdapters, ): readonly HousekeepingWidgetDefinition[] { const capability = anyCapability(PERMS.ASSETS_IMPORT, PERMS.CATALOG_EDIT); return [ { id: "hotel.studio.active-operations", owner: "hotel", kind: "mandatory", capability, async load(context, signal) { const authorization = authorizeHousekeeping(context, capability); if (!authorization.ok) return authorization; try { if (signal.aborted) throw new Error("aborted Hotel widget"); return ok( await adapters.activeOperations(context, signal), authorization.correlationId, ); } catch { return fail( "DEPENDENCY_UNAVAILABLE", "errors.housekeeping.dependencyUnavailable", authorization.correlationId, ); } }, }, ]; } export const HOTEL_WIDGETS = createHotelWidgets({ async activeOperations(_context, signal) { if (signal.aborted) throw new Error("aborted Hotel operations widget"); const { items } = await studioOperationRepository.list({ pageSize: 100, offset: 0, }); return { queued: items.filter((item) => item.phase === "queued").length, running: items.filter((item) => item.phase === "running").length, partial: items.filter((item) => item.phase === "partial").length, failed: items.filter((item) => item.phase === "failed").length, }; }, });