audit
This commit is contained in:
@@ -25,6 +25,23 @@ const StaffNotification = mongoose.model('StaffNotification');
|
||||
// In-memory cooldown map: `${userId}:${ticketId}` -> last notified timestamp
|
||||
const replyCooldowns = new Map();
|
||||
|
||||
const REPLY_COOLDOWN_SWEEP_TTL_MS = 48 * 60 * 60 * 1000;
|
||||
const REPLY_COOLDOWN_SWEEP_INTERVAL_MS = 6 * 60 * 60 * 1000;
|
||||
|
||||
function sweepReplyCooldowns(now = Date.now()) {
|
||||
const cutoff = now - REPLY_COOLDOWN_SWEEP_TTL_MS;
|
||||
for (const [key, ts] of replyCooldowns.entries()) {
|
||||
if (ts < cutoff) replyCooldowns.delete(key);
|
||||
}
|
||||
}
|
||||
|
||||
function startSweeps(trackInterval) {
|
||||
const handle = setInterval(() => sweepReplyCooldowns(), REPLY_COOLDOWN_SWEEP_INTERVAL_MS);
|
||||
if (typeof handle.unref === 'function') handle.unref();
|
||||
if (typeof trackInterval === 'function') trackInterval(handle);
|
||||
return handle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the claiming staff member when a non-staff user replies.
|
||||
* Respects the staff member's cooldownHours setting (default 1h).
|
||||
@@ -72,11 +89,13 @@ async function notifyAllStaffUnclaimed(client) {
|
||||
const sorted = [...thresholds].sort((a, b) => a - b);
|
||||
const now = Date.now();
|
||||
|
||||
// Bounded per-tick: oldest-first, capped at 500. A backlog larger than 500
|
||||
// gets drained in subsequent 30-minute ticks rather than one long run.
|
||||
const unclaimedTickets = await Ticket.find({
|
||||
status: 'open',
|
||||
claimedBy: null,
|
||||
createdAt: { $ne: null }
|
||||
}).lean();
|
||||
}).sort({ createdAt: 1 }).limit(500).lean();
|
||||
|
||||
if (unclaimedTickets.length === 0) return;
|
||||
|
||||
@@ -103,8 +122,7 @@ async function notifyAllStaffUnclaimed(client) {
|
||||
const channelName = ticket.discordThreadId
|
||||
? `<#${ticket.discordThreadId}>`
|
||||
: `ticket #${ticket.ticketNumber}`;
|
||||
const hoursAgo = Math.floor(ageHours);
|
||||
const alertMsg = `Unclaimed ticket alert: ${channelName} has been unclaimed for ${hoursAgo}+ hour(s) (${highest}h threshold).`;
|
||||
const alertMsg = `[${highest}h+ unclaimed] ${channelName}`;
|
||||
|
||||
for (const rec of staffRecords) {
|
||||
const chan = await guild.channels.fetch(rec.channelId).catch(() => null);
|
||||
@@ -122,4 +140,10 @@ async function notifyAllStaffUnclaimed(client) {
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = { notifyStaffOfReply, notifyAllStaffUnclaimed };
|
||||
module.exports = {
|
||||
notifyStaffOfReply,
|
||||
notifyAllStaffUnclaimed,
|
||||
startSweeps,
|
||||
sweepReplyCooldowns,
|
||||
_internals: { replyCooldowns, REPLY_COOLDOWN_SWEEP_TTL_MS }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user