class Settings::ProvidersController < ApplicationController layout "settings" guard_feature unless: -> { self_hosted? } before_action :ensure_admin, only: [ :show, :update ] def show @breadcrumbs = [ [ "Home", root_path ], [ "Bank Sync Providers", nil ] ] # Load all provider configurations Provider::Factory.ensure_adapters_loaded @provider_configurations = Provider::ConfigurationRegistry.all end def update # Build index of valid configurable fields with their metadata Provider::Factory.ensure_adapters_loaded valid_fields = {} Provider::ConfigurationRegistry.all.each do |config| config.fields.each do |field| valid_fields[field.setting_key.to_s] = field end end updated_fields = [] # Perform all updates within a transaction for consistency Setting.transaction do provider_params.each do |param_key, param_value| # Only process keys that exist in the configuration registry field = valid_fields[param_key.to_s] next unless field # Clean the value and convert blank/empty strings to nil value = param_value.to_s.strip value = nil if value.empty? # For secret fields only, skip placeholder values to prevent accidental overwrite if field.secret && value == "********" next end # Set the value using dynamic hash-style access Setting[field.setting_key] = value updated_fields << param_key end end if updated_fields.any? # Reload provider configurations if needed reload_provider_configs(updated_fields) redirect_to settings_providers_path, notice: "Provider settings updated successfully" else redirect_to settings_providers_path, notice: "No changes were made" end rescue => error Rails.logger.error("Failed to update provider settings: #{error.message}") flash.now[:alert] = "Failed to update provider settings: #{error.message}" render :show, status: :unprocessable_entity end private def provider_params # Dynamically permit all provider configuration fields Provider::Factory.ensure_adapters_loaded permitted_fields = [] Provider::ConfigurationRegistry.all.each do |config| config.fields.each do |field| permitted_fields << field.setting_key end end params.require(:setting).permit(*permitted_fields) end def ensure_admin redirect_to settings_providers_path, alert: "Not authorized" unless Current.user.admin? end # Reload provider configurations after settings update def reload_provider_configs(updated_fields) # Build a set of provider keys that had fields updated updated_provider_keys = Set.new # Look up the provider key directly from the configuration registry updated_fields.each do |field_key| Provider::ConfigurationRegistry.all.each do |config| field = config.fields.find { |f| f.setting_key.to_s == field_key.to_s } if field updated_provider_keys.add(field.provider_key) break end end end # Reload configuration for each updated provider updated_provider_keys.each do |provider_key| adapter_class = Provider::ConfigurationRegistry.get_adapter_class(provider_key) adapter_class&.reload_configuration end end end