Files
Qris-Soundbox/dist/shared/store/bindingStore.js
2026-05-25 08:22:12 +07:00

98 lines
3.4 KiB
JavaScript

import { randomUUID } from "node:crypto";
import { getPool, withClient } from "../db/pool";
function nowIso() {
return new Date().toISOString();
}
function mapBinding(row) {
return {
id: row.id,
device_id: row.device_id,
merchant_id: row.merchant_id,
outlet_id: row.outlet_id,
terminal_id: row.terminal_id,
active_flag: row.active_flag,
bound_at: row.bound_at,
unbound_at: row.unbound_at || undefined
};
}
export async function getActiveBindingByDevice(deviceId) {
const { rows } = await getPool().query(`SELECT * FROM device_bindings
WHERE device_id = $1 AND active_flag = TRUE
ORDER BY bound_at DESC
LIMIT 1`, [deviceId]);
return rows[0] ? mapBinding(rows[0]) : null;
}
export async function getActiveBindingByTerminal(terminalId) {
const { rows } = await getPool().query(`SELECT * FROM device_bindings
WHERE terminal_id = $1 AND active_flag = TRUE
ORDER BY bound_at DESC
LIMIT 1`, [terminalId]);
return rows[0] ? mapBinding(rows[0]) : null;
}
export async function getBindingsByDeviceId(deviceId) {
const { rows } = await getPool().query(`SELECT * FROM device_bindings
WHERE device_id = $1
ORDER BY bound_at DESC`, [deviceId]);
return rows.map(mapBinding);
}
export async function bindDevice(payload) {
const now = nowIso();
const result = await withClient(async (client) => {
const existing = await client.query(`SELECT * FROM device_bindings
WHERE device_id = $1 AND active_flag = TRUE
ORDER BY bound_at DESC
LIMIT 1`, [payload.device_id]);
const same = existing.rows[0]
? mapBinding(existing.rows[0])
: null;
if (same &&
same.merchant_id === payload.merchant_id &&
same.outlet_id === payload.outlet_id &&
same.terminal_id === payload.terminal_id) {
return same;
}
await client.query("BEGIN");
try {
if (existing.rows[0]) {
await client.query(`UPDATE device_bindings
SET active_flag = FALSE, unbound_at = $2
WHERE id = $1`, [same.id, now]);
}
const id = randomUUID();
const inserted = await client.query(`INSERT INTO device_bindings (
id,
device_id,
merchant_id,
outlet_id,
terminal_id,
active_flag,
bound_at
) VALUES ($1,$2,$3,$4,$5,TRUE,$6)
RETURNING *`, [id, payload.device_id, payload.merchant_id, payload.outlet_id, payload.terminal_id, now]);
await client.query("COMMIT");
return mapBinding(inserted.rows[0]);
}
catch (error) {
await client.query("ROLLBACK");
throw error;
}
});
return result;
}
export async function unbindDevice(deviceId) {
const now = nowIso();
const { rows } = await getPool().query(`UPDATE device_bindings
SET active_flag = FALSE,
unbound_at = $2
WHERE device_id = $1 AND active_flag = TRUE
RETURNING *`, [deviceId, now]);
return rows[0] ? mapBinding(rows[0]) : null;
}
export async function getBindingById(id) {
const { rows } = await getPool().query("SELECT * FROM device_bindings WHERE id = $1", [id]);
return rows[0] ? mapBinding(rows[0]) : null;
}
export function toBindingPayload(binding) {
return { ...binding };
}