import type { MqttTransport } from '../mqtt/mqtt-service.js'; import { generateCommandId, type IotMessageService } from './iot-message-service.js'; export class DeviceCommandService { private sequence = 0; constructor( private readonly messages: Pick, private readonly transport: Pick ) {} async issue(input: { tenantId: string; assetId: string; deviceId: string; storeId: string; roomId?: string | null; orderId?: string | null; commandType: string; payloadFactory: (commandId: string) => Record; traceId: string; expiresAt?: Date | null; }) { const commandId = generateCommandId(Date.now(), this.sequence++); const payload = input.payloadFactory(commandId); await this.messages.createCommand({ tenantId: input.tenantId, assetId: input.assetId, storeId: input.storeId, roomId: input.roomId, orderId: input.orderId, commandId, commandType: input.commandType, payload, traceId: input.traceId, expiresAt: input.expiresAt }); try { await this.transport.publishDeviceCommand(input.deviceId, JSON.stringify(payload)); await this.messages.markPublished(input.tenantId, commandId); return { commandId, status: 'PUBLISHED' as const }; } catch (error) { await this.messages.markPublishFailed(input.tenantId, commandId, 'MQTT_PUBLISH_FAILED'); throw error; } } }