import { randomUUID } from "node:crypto"; import { getPool } from "../db/pool"; function nowIso() { return new Date().toISOString(); } function normalizeStatus(status) { if (status === "accepted" || status === "delivered" || status === "failed" || status === "timeout") { return status; } return "accepted"; } function mapCommand(row) { return { id: row.id, device_id: row.device_id, command: row.command, payload: row.payload_json || {}, status: row.status, requested_at: row.requested_at, acknowledged_at: row.acknowledged_at || null, result_payload: row.result_payload_json || null, reason: row.reason || null }; } export async function createDeviceCommand(payload) { const entity = { id: `cmd_${randomUUID()}`, device_id: payload.device_id, command: payload.command, payload: payload.payload || {}, status: normalizeStatus(payload.status || "accepted"), requested_at: nowIso(), acknowledged_at: null, result_payload: null, reason: null }; const { rows } = await getPool().query(`INSERT INTO device_commands ( id, device_id, command, payload_json, status, requested_at, acknowledged_at, result_payload_json, reason ) VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9) RETURNING *`, [ entity.id, entity.device_id, entity.command, entity.payload, entity.status, entity.requested_at, entity.acknowledged_at, entity.result_payload, entity.reason ]); return mapCommand(rows[0]); } export async function listDeviceCommands(deviceId) { const { rows } = await getPool().query("SELECT * FROM device_commands WHERE device_id = $1 ORDER BY requested_at DESC", [deviceId]); return rows.map(mapCommand); } export async function getDeviceCommandById(deviceId, commandId) { const { rows } = await getPool().query("SELECT * FROM device_commands WHERE device_id = $1 AND id = $2", [deviceId, commandId]); return rows[0] ? mapCommand(rows[0]) : null; } export function toDeviceCommandPayload(command) { return mapCommand(command); } export function toDeviceCommandPayloadBrief(command) { return { command_id: command.id, device_id: command.device_id, command: command.command, status: command.status, requested_at: command.requested_at, acknowledged_at: command.acknowledged_at }; } export async function acknowledgeDeviceCommand(payload) { const now = nowIso(); const { rows } = await getPool().query(`UPDATE device_commands SET status = $3, acknowledged_at = $4, result_payload_json = $5, reason = $6 WHERE device_id = $1 AND id = $2 RETURNING *`, [payload.device_id, payload.command_id, payload.status, now, payload.result_payload || null, payload.reason || null]); return rows[0] ? mapCommand(rows[0]) : null; }