69 lines
1.8 KiB
Ruby
69 lines
1.8 KiB
Ruby
class Gateway < ApplicationRecord
|
|
# Normalize metadata to always be a Hash
|
|
attribute :metadata, :jsonb, default: {}
|
|
|
|
has_many :sms_messages, dependent: :nullify
|
|
|
|
before_validation :ensure_metadata_is_hash
|
|
|
|
validates :device_id, presence: true, uniqueness: true
|
|
validates :api_key_digest, presence: true
|
|
validates :status, inclusion: { in: %w[online offline error] }
|
|
|
|
scope :online, -> { where(status: "online") }
|
|
scope :offline, -> { where(status: "offline") }
|
|
scope :active, -> { where(active: true) }
|
|
scope :by_priority, -> { order(priority: :desc, id: :asc) }
|
|
|
|
# Find the best available gateway for sending messages
|
|
def self.available_for_sending
|
|
online.active.by_priority.first
|
|
end
|
|
|
|
# Generate a new API key for the gateway
|
|
def generate_api_key!
|
|
raw_key = "gw_live_#{SecureRandom.hex(32)}"
|
|
self.api_key_digest = Digest::SHA256.hexdigest(raw_key)
|
|
save!
|
|
raw_key
|
|
end
|
|
|
|
# Check if gateway is currently online based on heartbeat
|
|
def online?
|
|
status == "online" && last_heartbeat_at.present? && last_heartbeat_at > 2.minutes.ago
|
|
end
|
|
|
|
# Update heartbeat timestamp and status
|
|
def heartbeat!
|
|
update!(status: "online", last_heartbeat_at: Time.current)
|
|
end
|
|
|
|
# Mark gateway as offline
|
|
def mark_offline!
|
|
update!(status: "offline")
|
|
end
|
|
|
|
# Increment message counters
|
|
def increment_sent_count!
|
|
increment!(:messages_sent_today)
|
|
increment!(:total_messages_sent)
|
|
end
|
|
|
|
def increment_received_count!
|
|
increment!(:messages_received_today)
|
|
increment!(:total_messages_received)
|
|
end
|
|
|
|
# Reset daily counters (called by scheduled job)
|
|
def self.reset_daily_counters!
|
|
update_all(messages_sent_today: 0, messages_received_today: 0)
|
|
end
|
|
|
|
private
|
|
|
|
def ensure_metadata_is_hash
|
|
self.metadata = {} if metadata.nil?
|
|
self.metadata = {} unless metadata.is_a?(Hash)
|
|
end
|
|
end
|