import "server-only"; import { z } from "zod"; import type { HousekeepingCommand } from "../../../foundation/commands/registry"; import { anyCapability } from "../../../foundation/contracts"; import { type HotelMutationOperation, type HotelMutationService, hotelMutationService, } from "../services/mutations"; import { HOTEL_RADIO_COMMAND_DEFINITIONS } from "./radio-commands"; import { HOTEL_ROOM_COMMAND_DEFINITIONS } from "./room-commands"; const HOTEL_COMMAND_DEFINITIONS = [ ...HOTEL_ROOM_COMMAND_DEFINITIONS, ...HOTEL_RADIO_COMMAND_DEFINITIONS, ] as const; export const HOTEL_COMMAND_IDS = HOTEL_COMMAND_DEFINITIONS.map( ([id]) => id, ) as ReadonlyArray<(typeof HOTEL_COMMAND_DEFINITIONS)[number][0]>; const REASON_COMMANDS = new Set([ "hotel.rooms.delete", "hotel.rooms.furni.delete", "hotel.rooms.furni.bulk-delete", "hotel.rooms.runtime.control", "hotel.radio.shout.delete", "hotel.radio.api-key.create", "hotel.radio.api-key.delete", "hotel.radio.autodj.delete", "hotel.radio.banner.delete", "hotel.radio.rank.delete", ]); type HotelCommand = HousekeepingCommand, unknown> & { readonly operation: HotelMutationOperation; }; const commandInput = z.object({}).catchall(z.unknown()); export function createHotelCommands( service: Pick, ): readonly HotelCommand[] { return HOTEL_COMMAND_DEFINITIONS.map( ([id, operation, permission]): HotelCommand => ({ id, owner: "hotel", operation, risk: "sensitive", capability: anyCapability(permission), input: commandInput, requiresReason: REASON_COMMANDS.has(id), rateLimit: { attempts: 10, windowMs: 60_000 }, execute: (context, input) => service.execute( { correlationId: context.correlationId, expectedActorId: context.capability.actor.id, }, operation, input, ), }), ); } export const HOTEL_COMMANDS = createHotelCommands(hotelMutationService);