module Ops class Incident < ApplicationRecord self.table_name = "ops_incidents" KINDS = %w[ disk_space recordings_size service_down http_public sidekiq_stale sidekiq_dead log_pattern garage_storage ].freeze SEVERITIES = %w[critical warning info].freeze STATUSES = %w[open acknowledged resolved].freeze validates :kind, :severity, :status, :title, :fingerprint, presence: true validates :severity, inclusion: { in: SEVERITIES } validates :status, inclusion: { in: STATUSES } validates :occurrence_count, numericality: { greater_than: 0 } scope :open, -> { where(status: %w[open acknowledged]) } scope :unresolved, -> { where.not(status: "resolved") } scope :critical_open, -> { open.where(severity: "critical") } scope :recent, -> { order(last_seen_at: :desc) } scope :since, ->(time) { where("last_seen_at >= ?", time) } def open? status.in?(%w[open acknowledged]) end def muted? muted_until.present? && muted_until.future? end def acknowledge! update!(status: "acknowledged", acknowledged_at: Time.current) end def resolve! update!(status: "resolved") end def mute!(duration: 24.hours) update!(muted_until: duration.from_now) end end end