diff --git a/server/index.js b/server/index.js index 68f9430..3f07c46 100644 --- a/server/index.js +++ b/server/index.js @@ -2465,8 +2465,32 @@ async function autoActivateReservationSlotIfNeededUnlocked(options = {}) { await persistStationReservationsIfChanged(reservations, { lastAction: "reserve-sync" }); const activeEntry = findActiveReservationEntry(reservations, nowMs); if (!activeEntry) { + if (runtime.station.manualReleaseReservationUserId || runtime.station.manualReleaseReservationUntil) { + runtime.station.manualReleaseReservationUserId = null; + runtime.station.manualReleaseReservationUntil = null; + runtime.station.updatedAt = new Date().toISOString(); + await writeJson(files.station, runtime.station); + } return false; } + + const holdUserId = String(runtime.station.manualReleaseReservationUserId || ""); + const holdUntilMs = parseIsoMs(runtime.station.manualReleaseReservationUntil); + if ( + holdUserId + && Number.isFinite(holdUntilMs) + && holdUntilMs > nowMs + && String(activeEntry.userId || "") === holdUserId + ) { + return false; + } + if (holdUserId || runtime.station.manualReleaseReservationUntil) { + runtime.station.manualReleaseReservationUserId = null; + runtime.station.manualReleaseReservationUntil = null; + runtime.station.updatedAt = new Date().toISOString(); + await writeJson(files.station, runtime.station); + } + if (excludeUserId && String(activeEntry.userId || "") === excludeUserId) { return false; } @@ -2491,6 +2515,8 @@ async function autoActivateReservationSlotIfNeededUnlocked(options = {}) { startedAt: activeEntry.from, endsAt: activeEntry.to, reservations, + manualReleaseReservationUserId: null, + manualReleaseReservationUntil: null, updatedAt: new Date().toISOString(), lastAction: "activate-auto-slot" }; @@ -2520,6 +2546,14 @@ async function reconcileStationLeaseOnStartup() { runtime.station.endsAt = null; changed = true; } + if (!Object.prototype.hasOwnProperty.call(runtime.station, "manualReleaseReservationUserId")) { + runtime.station.manualReleaseReservationUserId = null; + changed = true; + } + if (!Object.prototype.hasOwnProperty.call(runtime.station, "manualReleaseReservationUntil")) { + runtime.station.manualReleaseReservationUntil = null; + changed = true; + } if (runtime.station.isInUse && runtime.station.startedAt && !runtime.station.endsAt) { runtime.station.endsAt = computeLeaseEndIso(runtime.station.startedAt); changed = true; @@ -2766,6 +2800,8 @@ async function runActivationJob(job, user) { startedAt, endsAt, reservations: reservationsAfterActivate, + manualReleaseReservationUserId: null, + manualReleaseReservationUntil: null, updatedAt: new Date().toISOString(), lastAction: "activate" }; @@ -2870,6 +2906,12 @@ async function handleStationRelease(res, user) { startedAt: null, endsAt: null, reservations: lockInfo.reservations, + manualReleaseReservationUserId: lockInfo.activeEntry && String(lockInfo.activeEntry.userId || "") === String(user && user.id ? user.id : "") + ? String(user.id || "") + : null, + manualReleaseReservationUntil: lockInfo.activeEntry && String(lockInfo.activeEntry.userId || "") === String(user && user.id ? user.id : "") + ? String(lockInfo.activeEntry.to || "") + : null, updatedAt: new Date().toISOString(), lastAction: "deactivate" }; @@ -2961,6 +3003,12 @@ async function handleDeleteOwnReservation(res, user) { startedAt: null, endsAt: null, reservations: removed.reservations, + manualReleaseReservationUserId: String(runtime.station.manualReleaseReservationUserId || "") === String(user && user.id ? user.id : "") + ? null + : (runtime.station.manualReleaseReservationUserId || null), + manualReleaseReservationUntil: String(runtime.station.manualReleaseReservationUserId || "") === String(user && user.id ? user.id : "") + ? null + : (runtime.station.manualReleaseReservationUntil || null), updatedAt: new Date().toISOString(), lastAction: "reserve-remove-current" }; @@ -2978,6 +3026,12 @@ async function handleDeleteOwnReservation(res, user) { runtime.station = { ...runtime.station, reservations: removed.reservations, + manualReleaseReservationUserId: String(runtime.station.manualReleaseReservationUserId || "") === String(user && user.id ? user.id : "") + ? null + : (runtime.station.manualReleaseReservationUserId || null), + manualReleaseReservationUntil: String(runtime.station.manualReleaseReservationUserId || "") === String(user && user.id ? user.id : "") + ? null + : (runtime.station.manualReleaseReservationUntil || null), updatedAt: new Date().toISOString(), lastAction: "reserve-remove" }; @@ -6957,6 +7011,8 @@ function buildDefaultStationState() { startedAt: null, endsAt: null, reservations: [], + manualReleaseReservationUserId: null, + manualReleaseReservationUntil: null, updatedAt: new Date().toISOString(), lastAction: "init" };