Class: Setting

Inherits:
RailsSettings::Base
  • Object
show all
Includes:
Models::Auditable
Defined in:
app/models/setting.rb

Overview

== Schema Information

Table name: settings
Database name: primary

id :bigint not null, primary key
value :text
var :string not null
created_at :datetime not null
updated_at :datetime not null

Indexes

index_settings_on_var (var) UNIQUE

Defined Under Namespace

Classes: SettingPermission

Constant Summary

Constants included from Models::Auditable

Models::Auditable::ALWAYS_IGNORED

Class Method Summary collapse

Methods included from Models::Auditable

#all_skipped_columns, #audit_reference_data, #creator, #should_not_save_version, #stamp_record, #updater

Class Method Details

.ad_conversion_valuesActiveRecord::Relation<Setting>

A relation of Settings that are ad conversion values. Active Record Scope

Returns:

  • (ActiveRecord::Relation<Setting>)

See Also:



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'app/models/setting.rb', line 94

scope :ad_conversion_values do
  # Expected value of a captured lead (`generate_lead`). Measured at $395–479
  # gross; $200 is the agency's conservative pick while `CRM Invoiced Revenue`
  # is also a primary conversion action and would report the in-window portion
  # separately. Google Ads currently forces this value account-side, so this
  # setting drives GA4, Facebook, Pinterest and OpenAI Ads.
  field :ad_conversion_lead_value, type: :integer, default: 200

  # Expected value of a quote-builder completion (`instant_quote_complete_fh`
  # / `_sm`). NEVER the quoted job total — that is inversely correlated with
  # the chance of closing.
  field :ad_conversion_quote_value, type: :integer, default: 100

  # Fraction of an opportunity's value we report as its expected conversion
  # value, used by the server-side offline reporters (Google, Microsoft,
  # Pinterest, Facebook, OpenAI). Validated for lead-form opportunities by a
  # measured 21.1% close rate; NOT calibrated for quote-builder opportunities,
  # where big quotes close far worse than small ones.
  field :ad_conversion_opportunity_rate, type: :float, default: 0.2
end

.ai_visionActiveRecord::Relation<Setting>

A relation of Settings that are ai vision. Active Record Scope

Returns:

  • (ActiveRecord::Relation<Setting>)

See Also:



78
79
80
81
82
# File 'app/models/setting.rb', line 78

scope :ai_vision do
  field :ai_vision_model, type: :string
  field :ai_vision_max_tokens, type: :integer
  field :ai_vision_prompt, type: :string
end

.brand_voiceActiveRecord::Relation<Setting>

A relation of Settings that are brand voice. Active Record Scope

Returns:

  • (ActiveRecord::Relation<Setting>)

See Also:



132
133
134
135
136
137
# File 'app/models/setting.rb', line 132

scope :brand_voice do
  field :brand_voice_guidelines, type: :string
  field :brand_voice_examples, type: :string
  field :brand_voice_phrases_to_use, type: :array
  field :brand_voice_phrases_to_avoid, type: :array
end

.call_transcriptionActiveRecord::Relation<Setting>

A relation of Settings that are call transcription. Active Record Scope

Returns:

  • (ActiveRecord::Relation<Setting>)

See Also:



56
57
58
59
60
61
62
63
64
# File 'app/models/setting.rb', line 56

scope :call_transcription do
  field :call_transcription_lemur_system_prompt, type: :string
  field :call_transcription_lemur_analysis_prompt, type: :string
  field :call_transcription_lemur_model, type: :string
  field :call_transcription_lemur_max_tokens, type: :integer
  field :call_transcription_lemur_temperature, type: :float
  field :call_transcription_speech_model, type: :string
  field :call_transcription_keyterms, type: :array
end

.ip_in_switchvox_whitelist?(remote_ip) ⇒ Boolean

Check if an IP matches the whitelist (supports CIDR)
Returns true if whitelist is empty (no IP restriction configured)

Parameters:

  • remote_ip (String, nil)

    IP address to check

Returns:

  • (Boolean)


167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'app/models/setting.rb', line 167

def self.ip_in_switchvox_whitelist?(remote_ip)
  whitelist = Array(switchvox_webhook_ips).compact_blank

  # Empty whitelist = no IP restriction, allow all
  return true if whitelist.empty?
  return false if remote_ip.blank?

  begin
    remote = IPAddr.new(remote_ip)
    whitelist.any? do |allowed|
      IPAddr.new(allowed.to_s.strip).include?(remote)
    rescue IPAddr::InvalidAddressError
      false
    end
  rescue IPAddr::InvalidAddressError
    false
  end
end

.outlet_purchase_commissionActiveRecord::Relation<Setting>

A relation of Settings that are outlet purchase commission. Active Record Scope

Returns:

  • (ActiveRecord::Relation<Setting>)

See Also:



118
119
120
121
122
123
124
125
126
127
# File 'app/models/setting.rb', line 118

scope :outlet_purchase_commission do
  # Commission rate on a verified outlet purchase — the customer bought
  # through a retailer instead of ordering direct, and the rep's work led to
  # it. Sales management landed on 1% (they had floated 2%), treating it like
  # an assisted tech call rather than a direct sale.
  #
  # A Setting rather than a constant precisely because it already moved once.
  # See doc/tasks/202608081330_OUTLET_PURCHASE_ATTRIBUTION.md.
  field :outlet_purchase_commission_rate, type: :float, default: 0.01
end

.permission_for(key) ⇒ SettingPermission

Helper method to create a permission check object

Parameters:

  • key (String, Symbol)

    setting key

Returns:



215
216
217
# File 'app/models/setting.rb', line 215

def self.permission_for(key)
  SettingPermission.new(key)
end

.phone_systemActiveRecord::Relation<Setting>

A relation of Settings that are phone system. Active Record Scope

Returns:

  • (ActiveRecord::Relation<Setting>)

See Also:



69
70
71
72
73
# File 'app/models/setting.rb', line 69

scope :phone_system do
  field :call_recording_twilio_enabled, type: :boolean
  field :call_recording_twilio_trunk_id, type: :string
  field :switchvox_webhook_ips, type: :array
end

.ransackable_associations(_auth_object = nil) ⇒ Array<String>

Parameters:

  • _auth_object (Object) (defaults to: nil)

    unused Ransack auth object

Returns:

  • (Array<String>)


197
198
199
# File 'app/models/setting.rb', line 197

def self.ransackable_associations(_auth_object = nil)
  []
end

.ransackable_attributes(_auth_object = nil) ⇒ Array<String>

=============================================================================
Ransack & CanCanCan Configuration

Parameters:

  • _auth_object (Object) (defaults to: nil)

    unused Ransack auth object

Returns:

  • (Array<String>)


191
192
193
# File 'app/models/setting.rb', line 191

def self.ransackable_attributes(_auth_object = nil)
  %w[created_at id updated_at value var]
end

.transcriptionActiveRecord::Relation<Setting>

A relation of Settings that are transcription. Active Record Scope

Returns:

  • (ActiveRecord::Relation<Setting>)

See Also:



25
26
27
# File 'app/models/setting.rb', line 25

scope :transcription do
  field :transcription_spelling_corrections, type: :hash
end

.validate_switchvox_webhook_ips(ip_list) ⇒ Array<String>

Validate IP/CIDR format when setting switchvox_webhook_ips
Returns array of invalid entries, empty if all valid

Parameters:

  • ip_list (Array<String>, String, nil)

    IP addresses or CIDR ranges to validate

Returns:

  • (Array<String>)


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'app/models/setting.rb', line 147

def self.validate_switchvox_webhook_ips(ip_list)
  return [] if ip_list.blank?

  invalid = []
  Array(ip_list).each do |ip|
    next if ip.blank?

    begin
      IPAddr.new(ip.to_s.strip)
    rescue IPAddr::InvalidAddressError, IPAddr::AddressFamilyError
      invalid << ip
    end
  end
  invalid
end

.video_processingActiveRecord::Relation<Setting>

A relation of Settings that are video processing. Active Record Scope

Returns:

  • (ActiveRecord::Relation<Setting>)

See Also:



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'app/models/setting.rb', line 32

scope :video_processing do
  field :video_processing_transcription_keyterms_prompt, type: :array
  field :video_processing_transcription_spelling_corrections, type: :hash
  field :video_processing_seo_prompt, type: :string
  field :video_processing_seo_model, type: :string
  field :video_processing_seo_max_tokens, type: :integer
  field :video_processing_seo_temperature, type: :float
  field :video_processing_paragraph_system_prompt, type: :string
  field :video_processing_paragraph_user_prompt, type: :string
  field :video_processing_paragraph_model, type: :string
  field :video_processing_paragraph_max_tokens, type: :integer
  field :video_processing_paragraph_temperature, type: :float
  field :video_processing_polish_system_prompt, type: :string
  field :video_processing_polish_user_prompt, type: :string
  field :video_processing_translate_system_prompt, type: :string
  field :video_processing_translate_user_prompt, type: :string
  field :video_processing_llm_model, type: :string
  field :video_processing_llm_max_tokens, type: :integer
  field :video_processing_llm_temperature, type: :float
end