diff --git a/app/controllers/settings/hostings_controller.rb b/app/controllers/settings/hostings_controller.rb index 20e848ab4..e3bf49850 100644 --- a/app/controllers/settings/hostings_controller.rb +++ b/app/controllers/settings/hostings_controller.rb @@ -62,6 +62,16 @@ class Settings::HostingsController < ApplicationController Setting.syncs_include_pending = hosting_params[:syncs_include_pending] == "1" end + if hosting_params.key?(:auto_sync_enabled) + Setting.auto_sync_enabled = hosting_params[:auto_sync_enabled] == "1" + AutoSyncScheduler.sync! + end + + if hosting_params.key?(:auto_sync_time) + Setting.auto_sync_time = hosting_params[:auto_sync_time] + AutoSyncScheduler.sync! + end + if hosting_params.key?(:openai_access_token) token_param = hosting_params[:openai_access_token].to_s.strip # Ignore blanks and redaction placeholders to prevent accidental overwrite @@ -103,7 +113,7 @@ class Settings::HostingsController < ApplicationController private def hosting_params - params.require(:setting).permit(:onboarding_state, :require_email_confirmation, :brand_fetch_client_id, :twelve_data_api_key, :openai_access_token, :openai_uri_base, :openai_model, :openai_json_mode, :exchange_rate_provider, :securities_provider, :syncs_include_pending) + params.require(:setting).permit(:onboarding_state, :require_email_confirmation, :brand_fetch_client_id, :twelve_data_api_key, :openai_access_token, :openai_uri_base, :openai_model, :openai_json_mode, :exchange_rate_provider, :securities_provider, :syncs_include_pending, :auto_sync_enabled, :auto_sync_time) end def ensure_admin diff --git a/app/models/setting.rb b/app/models/setting.rb index e54817911..c28c611f3 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -24,6 +24,8 @@ class Setting < RailsSettings::Base simplefin && plaid end field :syncs_include_pending, type: :boolean, default: SYNCS_INCLUDE_PENDING_DEFAULT + field :auto_sync_enabled, type: :boolean, default: ENV.fetch("AUTO_SYNC_ENABLED", "1") == "1" + field :auto_sync_time, type: :string, default: ENV.fetch("AUTO_SYNC_TIME", "02:22") # Dynamic fields are now stored as individual entries with "dynamic:" prefix # This prevents race conditions and ensures each field is independently managed diff --git a/app/views/settings/hostings/_sync_settings.html.erb b/app/views/settings/hostings/_sync_settings.html.erb index 0846e039d..82cfb86ef 100644 --- a/app/views/settings/hostings/_sync_settings.html.erb +++ b/app/views/settings/hostings/_sync_settings.html.erb @@ -17,6 +17,40 @@ <% end %> +
+
+

<%= t(".auto_sync_label") %>

+

<%= t(".auto_sync_description") %>

+
+ + <%= styled_form_with model: Setting.new, + url: settings_hosting_path, + method: :patch, + data: { controller: "auto-submit-form", auto_submit_form_trigger_event_value: "change" } do |form| %> + <%= form.toggle :auto_sync_enabled, + checked: Setting.auto_sync_enabled, + data: { auto_submit_form_target: "auto" } %> + <% end %> +
+ +
+
+

<%= t(".auto_sync_time_label") %>

+

<%= t(".auto_sync_time_description") %>

+
+ + <%= form_with model: Setting.new, + url: settings_hosting_path, + method: :patch, + data: { controller: "auto-submit-form", auto_submit_form_trigger_event_value: "change" } do |form| %> + <%= form.time_field :auto_sync_time, + value: Setting.auto_sync_time, + disabled: !Setting.auto_sync_enabled, + class: "rounded-lg border border-primary px-3 py-2 text-sm bg-container text-primary w-full", + data: { auto_submit_form_target: "auto" } %> + <% end %> +
+ <% if env_configured %>