Permette di scegliere 12 ore, 24 ore o la settimana nello storico invii.
CI / scan_ruby (push) Failing after 12m32s
CI / scan_js (push) Successful in 13m28s
CI / lint (push) Failing after 13m58s

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-07 13:00:09 +02:00
co-authored by Cursor
parent 1c6b4bbabe
commit 353ace4d99
5 changed files with 138 additions and 26 deletions
+57 -19
View File
@@ -1,11 +1,28 @@
class Mailings::HourlyThroughput
HOUR = 1.hour
RECENT = 15.minutes
HISTORY_HOURS = 12
DEFAULT_RANGE = "12h"
RANGES = {
"12h" => { grain: :hour, periods: 12, short: "12h", label: "ultime 12 ore" },
"24h" => { grain: :hour, periods: 24, short: "24h", label: "ultime 24 ore" },
"7d" => { grain: :day, periods: 7, short: "7g", label: "ultima settimana" }
}.freeze
def initialize(project, now: Time.current)
def self.normalize_range(value)
key = value.to_s
RANGES.key?(key) ? key : DEFAULT_RANGE
end
def initialize(project, now: Time.current, range: DEFAULT_RANGE)
@project = project
@now = now
@range_key = self.class.normalize_range(range)
end
attr_reader :range_key
def range
RANGES.fetch(@range_key)
end
def sent
@@ -24,33 +41,54 @@ class Mailings::HourlyThroughput
sent + failed
end
def hourly_history
@hourly_history ||= begin
from = (@now - (HISTORY_HOURS - 1).hours).beginning_of_hour
keyed = recipients.sent
.where(sent_at: from..@now)
.pluck(:sent_at)
.each_with_object(Hash.new(0)) do |sent_at, counts|
counts[sent_at.in_time_zone.beginning_of_hour] += 1
end
HISTORY_HOURS.times.map do |index|
at = from + index.hours
{ at: at, count: keyed[at] || 0 }
end
end
def history
@history ||= buckets_for_range
end
def history_total
hourly_history.sum { |bucket| bucket[:count] }
history.sum { |bucket| bucket[:count] }
end
def history_max
[hourly_history.map { |bucket| bucket[:count] }.max, 1].max
[history.map { |bucket| bucket[:count] }.max, 1].max
end
private
def buckets_for_range
from, step = history_origin
keyed = recipients.sent
.where(sent_at: from..@now)
.pluck(:sent_at)
.each_with_object(Hash.new(0)) do |sent_at, counts|
counts[bucket_at(sent_at)] += 1
end
range[:periods].times.map do |index|
at = from + (step * index)
{ at: at, count: keyed[at] || 0, label: bucket_label(at) }
end
end
def history_origin
if range[:grain] == :day
from = (@now.to_date - (range[:periods] - 1)).in_time_zone.beginning_of_day
[from, 1.day]
else
from = (@now - (range[:periods] - 1).hours).beginning_of_hour
[from, 1.hour]
end
end
def bucket_at(sent_at)
time = sent_at.in_time_zone
range[:grain] == :day ? time.beginning_of_day : time.beginning_of_hour
end
def bucket_label(at)
range[:grain] == :day ? at.strftime("%d/%m") : at.strftime("%H:%M")
end
def sent_since(window)
recipients.sent.where(sent_at: (@now - window)..@now).count
end