Salva telemetria client (OS, app, device, operatore) sulle sessioni per il debug admin.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Sessions
|
||||
# Normalizza e applica fingerprint del client (OS, app, device, operatore)
|
||||
# sulla sessione, a create e/o a ogni telemetry.
|
||||
class ApplyClientInfo
|
||||
OS_VALUES = %w[android ios].freeze
|
||||
MAX_LEN = 80
|
||||
|
||||
ATTRS = %i[
|
||||
client_os app_version app_build device_manufacturer device_model os_version carrier
|
||||
].freeze
|
||||
|
||||
def self.call(session, raw)
|
||||
new(session, raw).call
|
||||
end
|
||||
|
||||
def initialize(session, raw)
|
||||
@session = session
|
||||
@raw = normalize_hash(raw)
|
||||
end
|
||||
|
||||
def call
|
||||
attrs = extract_attrs
|
||||
return @session if attrs.empty?
|
||||
|
||||
@session.assign_attributes(attrs)
|
||||
@session.save! if @session.persisted? && @session.changed?
|
||||
@session
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def normalize_hash(raw)
|
||||
return {} if raw.blank?
|
||||
|
||||
data = raw.respond_to?(:to_unsafe_h) ? raw.to_unsafe_h : raw
|
||||
data = data.to_h if data.respond_to?(:to_h)
|
||||
data.with_indifferent_access
|
||||
rescue StandardError
|
||||
{}
|
||||
end
|
||||
|
||||
def extract_attrs
|
||||
attrs = {}
|
||||
|
||||
os = @raw[:os].presence || @raw[:client_os].presence
|
||||
os = os.to_s.downcase.strip
|
||||
attrs[:client_os] = os if OS_VALUES.include?(os)
|
||||
|
||||
{
|
||||
app_version: %i[app_version version],
|
||||
app_build: %i[app_build build build_number],
|
||||
device_manufacturer: %i[device_manufacturer manufacturer],
|
||||
device_model: %i[device_model model],
|
||||
os_version: %i[os_version system_version],
|
||||
carrier: %i[carrier network_operator operator]
|
||||
}.each do |column, keys|
|
||||
value = keys.map { |k| @raw[k] }.find(&:present?)
|
||||
next if value.blank?
|
||||
|
||||
attrs[column] = truncate(value.to_s.strip)
|
||||
end
|
||||
|
||||
attrs
|
||||
end
|
||||
|
||||
def truncate(value)
|
||||
value.bytesize <= MAX_LEN ? value : value.byteslice(0, MAX_LEN)
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user