diff --git a/backend/server.js b/backend/server.js index 4fe2667..216f093 100644 --- a/backend/server.js +++ b/backend/server.js @@ -1197,66 +1197,83 @@ function buildAIAutoCommentRateLimitStatus(profileNumber, settings = getAIAutoCo let blockedReason = null; let blockedUntil = null; - if (!settings.enabled) { - blocked = false; - } else if (profileState && profileState.cooldown_until) { - const cooldownUntil = new Date(profileState.cooldown_until); - if (!Number.isNaN(cooldownUntil.getTime()) && cooldownUntil.getTime() > now.getTime()) { - blocked = true; - blockedReason = 'cooldown'; - blockedUntil = cooldownUntil.toISOString(); + if (settings.enabled) { + const blockingCandidates = []; + const addBlockingCandidate = (reason, untilIso) => { + if (!untilIso) { + return; + } + const untilDate = new Date(untilIso); + if (Number.isNaN(untilDate.getTime()) || untilDate.getTime() <= now.getTime()) { + return; + } + blockingCandidates.push({ + reason, + until: untilDate.toISOString(), + untilMs: untilDate.getTime() + }); + }; + + if (profileState && profileState.cooldown_until) { + addBlockingCandidate('cooldown', profileState.cooldown_until); } - } - if (!blocked && activeHours.configured && !activeHours.active) { - blocked = true; - blockedReason = 'active_hours'; - blockedUntil = activeHours.nextAllowedAt; - } + if (activeHours.configured && !activeHours.active) { + addBlockingCandidate('active_hours', activeHours.nextAllowedAt); + } - if (!blocked && settings.min_delay_seconds > 0 && lastEvent && lastEvent.created_at) { - const lastEventDate = new Date(lastEvent.created_at); - if (!Number.isNaN(lastEventDate.getTime())) { - const nextAllowedAt = new Date(lastEventDate.getTime() + (settings.min_delay_seconds * 1000)); - if (nextAllowedAt.getTime() > now.getTime()) { - blocked = true; - blockedReason = 'min_delay'; - blockedUntil = nextAllowedAt.toISOString(); + if (settings.min_delay_seconds > 0 && lastEvent && lastEvent.created_at) { + const lastEventDate = new Date(lastEvent.created_at); + if (!Number.isNaN(lastEventDate.getTime())) { + addBlockingCandidate( + 'min_delay', + new Date(lastEventDate.getTime() + (settings.min_delay_seconds * 1000)).toISOString() + ); } } - } - if (!blocked && settings.requests_per_minute > 0 && usedMinute >= settings.requests_per_minute) { - const oldest = getAIAutoCommentOldestEventSince(normalizedProfileNumber, minuteWindowStart); - if (oldest && oldest.created_at) { - blocked = true; - blockedReason = 'per_minute'; - blockedUntil = new Date(new Date(oldest.created_at).getTime() + (60 * 1000)).toISOString(); + if (settings.requests_per_minute > 0 && usedMinute >= settings.requests_per_minute) { + const oldest = getAIAutoCommentOldestEventSince(normalizedProfileNumber, minuteWindowStart); + if (oldest && oldest.created_at) { + addBlockingCandidate( + 'per_minute', + new Date(new Date(oldest.created_at).getTime() + (60 * 1000)).toISOString() + ); + } } - } - if (!blocked && settings.burst_limit > 0 && usedBurst >= settings.burst_limit) { - const oldest = getAIAutoCommentOldestEventSince(normalizedProfileNumber, burstWindowStart); - if (oldest && oldest.created_at) { - blocked = true; - blockedReason = 'burst'; - blockedUntil = new Date(new Date(oldest.created_at).getTime() + (settings.burst_window_minutes * 60 * 1000)).toISOString(); + if (settings.burst_limit > 0 && usedBurst >= settings.burst_limit) { + const oldest = getAIAutoCommentOldestEventSince(normalizedProfileNumber, burstWindowStart); + if (oldest && oldest.created_at) { + addBlockingCandidate( + 'burst', + new Date(new Date(oldest.created_at).getTime() + (settings.burst_window_minutes * 60 * 1000)).toISOString() + ); + } } - } - if (!blocked && settings.requests_per_hour > 0 && usedHour >= settings.requests_per_hour) { - const oldest = getAIAutoCommentOldestEventSince(normalizedProfileNumber, hourWindowStart); - if (oldest && oldest.created_at) { - blocked = true; - blockedReason = 'per_hour'; - blockedUntil = new Date(new Date(oldest.created_at).getTime() + (60 * 60 * 1000)).toISOString(); + if (settings.requests_per_hour > 0 && usedHour >= settings.requests_per_hour) { + const oldest = getAIAutoCommentOldestEventSince(normalizedProfileNumber, hourWindowStart); + if (oldest && oldest.created_at) { + addBlockingCandidate( + 'per_hour', + new Date(new Date(oldest.created_at).getTime() + (60 * 60 * 1000)).toISOString() + ); + } } - } - if (!blocked && settings.requests_per_day > 0 && usedDay >= settings.requests_per_day) { - blocked = true; - blockedReason = 'per_day'; - blockedUntil = getNextLocalMidnightIso(now); + if (settings.requests_per_day > 0 && usedDay >= settings.requests_per_day) { + addBlockingCandidate('per_day', getNextLocalMidnightIso(now)); + } + + if (blockingCandidates.length > 0) { + const primaryBlocker = blockingCandidates.reduce((selected, candidate) => ( + !selected || candidate.untilMs > selected.untilMs ? candidate : selected + ), null); + blocked = true; + blockedReason = primaryBlocker.reason; + blockedUntil = primaryBlocker.until; + } } return {