72 lines
3.1 KiB
JavaScript
72 lines
3.1 KiB
JavaScript
// Generated, do not edit. sha256:d8bebac302697ff7428ee4125057b7ffc589ad6f6f375379f00af756b5b865fc
|
|
import * as db from '../db.js';
|
|
import { CONFIG, ENUMS } from '../../shared/config.js';
|
|
import { assertEnum, nowIso } from './_shared.js';
|
|
import { emitChange } from './_events.js';
|
|
|
|
function uitRij(r) {
|
|
if (!r) return r;
|
|
let lading = null;
|
|
if (r.payload != null) {
|
|
try { lading = JSON.parse(r.payload); } catch { lading = null; }
|
|
}
|
|
return { ...r, payload: lading };
|
|
}
|
|
|
|
export async function createCommand({ kind, payload = null, expiresAt = null }) {
|
|
assertEnum('kind', ENUMS.COMMAND_KIND, kind);
|
|
db.run(`INSERT INTO Command (kind, payload, state, expiresAt, createdAt) VALUES (?,?,?,?,?)`,
|
|
[kind, payload == null ? null : JSON.stringify(payload), 'open', expiresAt, nowIso()]);
|
|
const id = db.lastId();
|
|
pruneCommands();
|
|
await db.persist();
|
|
emitChange('commands-changed');
|
|
return id;
|
|
}
|
|
|
|
export async function claimNextCommand(tabblad, soorten = null) {
|
|
if (!tabblad) throw new Error('A claim without a tab cannot be assigned.');
|
|
const lijst = soorten == null ? null : [...soorten];
|
|
if (lijst) {
|
|
if (!lijst.length) throw new Error('A claim on zero kinds can never yield anything.');
|
|
for (const soort of lijst) assertEnum('kind', ENUMS.COMMAND_KIND, soort);
|
|
}
|
|
const nu = nowIso();
|
|
db.run(`UPDATE Command SET state = 'expired', detail = ?, resolvedAt = ?
|
|
WHERE state = 'open' AND expiresAt IS NOT NULL AND expiresAt < ?`,
|
|
['Niemand heeft deze opdracht op tijd opgepakt.', nu, nu]);
|
|
const filter = lijst ? `AND kind IN (${lijst.map(() => '?').join(',')})` : '';
|
|
db.run(`UPDATE Command SET state = 'claimed', claimedBy = ?, claimedAt = ?
|
|
WHERE id = (SELECT id FROM Command WHERE state = 'open' ${filter} ORDER BY id LIMIT 1)`,
|
|
[String(tabblad), nu, ...(lijst || [])]);
|
|
const rij = db.one(`SELECT * FROM Command WHERE state = 'claimed' AND claimedBy = ? AND resolvedAt IS NULL
|
|
ORDER BY id DESC LIMIT 1`, [String(tabblad)]);
|
|
await db.persist();
|
|
return uitRij(rij) || null;
|
|
}
|
|
|
|
export async function resolveCommand(id, tabblad, uitkomst, detail = null) {
|
|
assertEnum('state', ENUMS.COMMAND_STATE, uitkomst);
|
|
if (uitkomst === 'open' || uitkomst === 'claimed') {
|
|
throw new Error(`'${uitkomst}' is not a conclusion; a command closes as done, rejected or expired.`);
|
|
}
|
|
db.run(`UPDATE Command SET state = ?, detail = ?, resolvedAt = ?
|
|
WHERE id = ? AND claimedBy = ? AND resolvedAt IS NULL`,
|
|
[uitkomst, detail, nowIso(), Number(id), String(tabblad)]);
|
|
await db.persist();
|
|
emitChange('commands-changed');
|
|
}
|
|
|
|
export function getCommand(id) {
|
|
return uitRij(db.one(`SELECT * FROM Command WHERE id = ?`, [Number(id)])) || null;
|
|
}
|
|
|
|
export function pruneCommands(uren = CONFIG.COMMANDS.RETENTION_HOURS) {
|
|
const grens = new Date(Date.now() - Math.max(1, Number(uren) || CONFIG.COMMANDS.RETENTION_HOURS) * 3600_000)
|
|
.toISOString();
|
|
const r = db.one(`SELECT COUNT(*) AS n FROM Command WHERE resolvedAt IS NOT NULL AND resolvedAt < ?`, [grens]);
|
|
const aantal = r ? r.n : 0;
|
|
if (aantal) db.run(`DELETE FROM Command WHERE resolvedAt IS NOT NULL AND resolvedAt < ?`, [grens]);
|
|
return aantal;
|
|
}
|