Module: Crm::SettingsHelper

Defined in:
app/helpers/crm/settings_helper.rb

Overview

View helpers for the CRM settings pages (/crm/settings): scope labels and
icons, per-setting icons, human descriptions, and value summaries for the
rails-settings-canvas backed Setting keys.

See Also:

Constant Summary collapse

SCOPE_DISPLAY_NAMES =

Display names for scopes

{
  'transcription' => 'Transcription',
  'video_processing' => 'Video Processing',
  'call_transcription' => 'Call Transcription',
  'phone_system' => 'Phone System Integration',
  'ai_vision' => 'AI / Vision',
  'general' => 'General'
}.freeze
SCOPE_ICONS =

Icons for scopes

{
  'transcription' => 'microphone',
  'video_processing' => 'video',
  'call_transcription' => 'phone',
  'phone_system' => 'phone-office',
  'ai_vision' => 'brain',
  'general' => 'cog'
}.freeze
SETTING_ICONS =

Icons for specific settings

{
  /keyterms/ => 'key',
  /spelling/ => 'spell-check',
  /seo/ => 'search',
  /transcription/ => 'microphone',
  /ai_vision_model/ => 'robot',
  /ai_vision_prompt/ => 'comment-dots',
  /ai_vision/ => 'eye',
  /switchvox/ => 'phone-office',
  /twilio/ => 'cloud',
  /call_recording/ => 'voicemail'
}.freeze

Instance Method Summary collapse

Instance Method Details

#extract_scope(setting_key) ⇒ String

Get the scope for a setting using the gem's native scope feature

Parameters:

  • setting_key (String, Symbol)

    the Setting key

Returns:

  • (String)

    the scope name, 'general' when the key is unknown or unscoped



11
12
13
14
15
16
17
# File 'app/helpers/crm/settings_helper.rb', line 11

def extract_scope(setting_key)
  field = Setting.get_field(setting_key)
  return 'general' unless field

  # The gem returns scope as a symbol, convert to string for consistency
  field[:scope]&.to_s || 'general'
end

#scope_display_name(scope) ⇒ String

Human-readable label for a scope.

Parameters:

  • scope (String, Symbol)

    the scope key

Returns:

  • (String)

    the display name, falling back to a humanized scope



56
57
58
# File 'app/helpers/crm/settings_helper.rb', line 56

def scope_display_name(scope)
  SCOPE_DISPLAY_NAMES[scope.to_s] || scope.to_s.humanize
end

#scope_icon(scope) ⇒ String

Font Awesome icon name for a scope.

Parameters:

  • scope (String, Symbol)

    the scope key

Returns:

  • (String)

    the icon name, 'cog' when unmapped



63
64
65
# File 'app/helpers/crm/settings_helper.rb', line 63

def scope_icon(scope)
  SCOPE_ICONS[scope.to_s] || 'cog'
end

#setting_description(setting_key) ⇒ String

Human-readable description for a known Setting key.

Parameters:

  • setting_key (String, Symbol)

    the Setting key

Returns:

  • (String)

    the description, or a generic fallback



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/helpers/crm/settings_helper.rb', line 80

def setting_description(setting_key)
  case setting_key
  when 'transcription_spelling_corrections'
    'Shared spelling corrections for both video and call transcriptions. Format: "incorrect: correct".'
  when 'video_processing_transcription_keyterms_prompt'
    'Default keyterms used for AssemblyAI transcriptions to improve accuracy with domain-specific terminology.'
  when 'video_processing_transcription_spelling_corrections'
    'Legacy. Use transcription_spelling_corrections instead.'
  when 'video_processing_seo_prompt'
    'AI prompt instructions used to generate SEO metadata (meta title, description, sub header, expanded description) from video transcripts.'
  when 'video_processing_paragraph_system_prompt'
    'System prompt for generating natural paragraphs from video transcripts via AssemblyAI LLM Gateway.'
  when 'video_processing_paragraph_user_prompt'
    'User prompt template for paragraph generation. Use {{transcript}} as placeholder for the transcript text.'
  when 'video_processing_paragraph_model'
    "Deprecated — model is now controlled by LlmDefaults::DEFAULT_SONNET_MODEL in code. This setting is no longer read."
  when 'video_processing_paragraph_max_tokens'
    'Maximum tokens for paragraph generation response.'
  when 'video_processing_paragraph_temperature'
    'Temperature for paragraph generation (0.0-1.0). Lower = more deterministic.'
  when 'video_processing_polish_system_prompt'
    'System prompt for LeMUR caption polishing. Sets context for fixing terminology and grammar.'
  when 'video_processing_polish_user_prompt'
    'User prompt template for caption polishing. Use {{captions}} as placeholder.'
  when 'video_processing_translate_system_prompt'
    'System prompt for LeMUR translation. Sets context for translating video captions.'
  when 'video_processing_translate_user_prompt'
    'User prompt template for translation. Use {{language}}, {{variant}}, {{captions}} as placeholders.'
  when 'video_processing_llm_model'
    "Deprecated — model is now controlled by LlmDefaults::DEFAULT_SONNET_MODEL in code. This setting is no longer read."
  when 'video_processing_llm_max_tokens'
    'Maximum tokens for polishing/translation responses.'
  when 'video_processing_llm_temperature'
    'Temperature for polishing/translation (0.0-1.0). Lower = more deterministic.'
  when 'call_transcription_lemur_system_prompt'
    'System prompt for LeMUR call analysis. Sets the context for the AI analyzing call transcripts.'
  when 'call_transcription_lemur_analysis_prompt'
    'User prompt template for LeMUR analysis. Use {{agent_name}}, {{caller_name}}, {{call_context}}, {{transcript}} as placeholders.'
  when 'call_transcription_lemur_model'
    "Deprecated — model is now controlled by LlmDefaults::DEFAULT_SONNET_MODEL in code. This setting is no longer read."
  when 'call_transcription_lemur_max_tokens'
    'Maximum tokens for LeMUR response.'
  when 'call_transcription_lemur_temperature'
    'Temperature for LeMUR (0.0-1.0). Lower = more deterministic.'
  when 'call_transcription_speech_model'
    'Speech model for transcription. Options: universal-3-pro (recommended, multilingual), universal-2 (legacy).'
  when 'call_transcription_keyterms'
    'Additional key terms for better recognition (beyond spelling corrections).'
  when 'ai_vision_model'
    'Vision AI model for image analysis. Options: gpt-4o, gemini-3.7-flash, gemini-3.1-flash-lite, claude-sonnet-4-6'
  when 'ai_vision_max_tokens'
    'Maximum tokens for vision AI response length.'
  when 'ai_vision_prompt'
    'System prompt for vision AI image analysis. Controls how images are described and what details to focus on.'
  when 'call_recording_twilio_enabled'
    'Enable/disable Twilio SIP trunk recording import. Runs alongside Switchvox importer.'
  when 'call_recording_twilio_trunk_id'
    'Optional filter to specific Twilio SIP trunk ID. Leave blank to import from all trunks.'
  when 'switchvox_webhook_ips'
    'Allowed IP addresses/CIDRs for Switchvox webhooks. Supports CIDR notation (e.g., 10.0.0.0/8). Empty = no IP restriction.'
  else
    'General application setting.'
  end
end

#setting_icon(setting_key) ⇒ String

Font Awesome icon name for a specific setting, matched by key pattern.

Parameters:

  • setting_key (String, Symbol)

    the Setting key

Returns:

  • (String)

    the icon name, 'cog' when no pattern matches



70
71
72
73
74
75
# File 'app/helpers/crm/settings_helper.rb', line 70

def setting_icon(setting_key)
  SETTING_ICONS.each do |pattern, icon|
    return icon if setting_key.to_s.match?(pattern)
  end
  'cog'
end

#setting_value_summary(setting_key, value) ⇒ String

Short human summary of a setting's current value for the settings list.

Parameters:

  • setting_key (String, Symbol)

    the Setting key

  • value (Object)

    the setting's current value (Array, Hash, String, Boolean, or nil)

Returns:

  • (String)

    the summary text



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
# File 'app/helpers/crm/settings_helper.rb', line 149

def setting_value_summary(setting_key, value)
  case setting_key
  when 'video_processing_transcription_keyterms_prompt', 'call_transcription_keyterms'
    value.is_a?(Array) ? "#{value.length} terms defined" : 'No terms defined'
  when 'video_processing_transcription_spelling_corrections', 'transcription_spelling_corrections'
    value.is_a?(Hash) ? "#{value.length} corrections defined" : 'No corrections defined'
  when 'video_processing_seo_prompt', 'ai_vision_prompt',
       'call_transcription_lemur_system_prompt', 'call_transcription_lemur_analysis_prompt',
       'video_processing_paragraph_system_prompt', 'video_processing_paragraph_user_prompt',
       'video_processing_polish_system_prompt', 'video_processing_polish_user_prompt',
       'video_processing_translate_system_prompt', 'video_processing_translate_user_prompt'
    value.present? ? "#{value.length} characters" : 'Using default prompt'
  when 'ai_vision_model', 'call_transcription_lemur_model', 'video_processing_paragraph_model',
       'video_processing_llm_model', 'call_transcription_speech_model'
    value.presence || 'Using default'
  when 'ai_vision_max_tokens', 'call_transcription_lemur_max_tokens', 'video_processing_paragraph_max_tokens',
       'video_processing_llm_max_tokens'
    value.presence || 'Using default'
  when 'call_transcription_lemur_temperature', 'video_processing_paragraph_temperature',
       'video_processing_llm_temperature'
    value.presence || '0.3 (default)'
  when 'call_recording_twilio_enabled'
    value == true ? 'Enabled' : 'Disabled'
  when 'call_recording_twilio_trunk_id'
    value.present? ? value.to_s.truncate(20) : 'All trunks'
  when 'switchvox_webhook_ips'
    value.is_a?(Array) && value.any? ? "#{value.length} IPs configured" : 'No restriction (token auth only)'
  else
    value.present? ? 'Set' : 'Not set'
  end
end