diff --git a/lib/generators/provider/family/templates/activities_fetch_job.rb.tt b/lib/generators/provider/family/templates/activities_fetch_job.rb.tt index a37362bf0..a9b9f96c7 100644 --- a/lib/generators/provider/family/templates/activities_fetch_job.rb.tt +++ b/lib/generators/provider/family/templates/activities_fetch_job.rb.tt @@ -70,7 +70,11 @@ class <%= class_name %>ActivitiesFetchJob < ApplicationJob # **credentials # ) [] + rescue Provider::<%= class_name %>::AuthenticationError + # Re-raise auth errors - they need immediate attention + raise rescue => e + # Transient errors trigger retry via blank response Rails.logger.error("<%= class_name %>ActivitiesFetchJob - API error: #{e.message}") [] end diff --git a/lib/generators/provider/family/templates/activities_processor.rb.tt b/lib/generators/provider/family/templates/activities_processor.rb.tt index d55fc5ba5..956ff5ced 100644 --- a/lib/generators/provider/family/templates/activities_processor.rb.tt +++ b/lib/generators/provider/family/templates/activities_processor.rb.tt @@ -160,7 +160,8 @@ class <%= class_name %>Account::ActivitiesProcessor # TODO: Customize amount field names amount = parse_decimal(data[:amount]) || parse_decimal(data[:net_amount]) - return if amount.nil? || amount.zero? + return if amount.nil? + # Note: Zero-amount transactions (splits, free shares) are allowed # Get the activity date # TODO: Customize date field names diff --git a/lib/generators/provider/family/templates/controller.rb.tt b/lib/generators/provider/family/templates/controller.rb.tt index fb3d29e5e..788800aea 100644 --- a/lib/generators/provider/family/templates/controller.rb.tt +++ b/lib/generators/provider/family/templates/controller.rb.tt @@ -1,6 +1,8 @@ # frozen_string_literal: true class <%= class_name %>ItemsController < ApplicationController + ALLOWED_ACCOUNTABLE_TYPES = %w[Depository CreditCard Investment Loan OtherAsset OtherLiability Crypto Property Vehicle].freeze + before_action :set_<%= file_name %>_item, only: [ :show, :edit, :update, :destroy, :sync, :setup_accounts, :complete_account_setup ] def index @@ -277,11 +279,13 @@ class <%= class_name %>ItemsController < ApplicationController end def link_<%= file_name %>_account(<%= file_name %>_account, accountable_type) + accountable_class = validated_accountable_class(accountable_type) + account = Current.family.accounts.create!( name: <%= file_name %>_account.name, balance: <%= file_name %>_account.current_balance || 0, currency: <%= file_name %>_account.currency || "USD", - accountable: accountable_type.constantize.new + accountable: accountable_class.new ) <%= file_name %>_account.ensure_account_provider!(account) @@ -289,7 +293,7 @@ class <%= class_name %>ItemsController < ApplicationController end def create_account_from_<%= file_name %>(<%= file_name %>_account, accountable_type, config) - accountable_class = accountable_type.constantize + accountable_class = validated_accountable_class(accountable_type) accountable_attrs = {} # Set subtype if the accountable supports it @@ -321,4 +325,12 @@ class <%= class_name %>ItemsController < ApplicationController "Depository" end end + + def validated_accountable_class(accountable_type) + unless ALLOWED_ACCOUNTABLE_TYPES.include?(accountable_type) + raise ArgumentError, "Invalid accountable type: #{accountable_type}" + end + + accountable_type.constantize + end end diff --git a/lib/generators/provider/family/templates/item_partial.html.erb.tt b/lib/generators/provider/family/templates/item_partial.html.erb.tt index 1c9878997..5c2f4dd94 100644 --- a/lib/generators/provider/family/templates/item_partial.html.erb.tt +++ b/lib/generators/provider/family/templates/item_partial.html.erb.tt @@ -95,7 +95,7 @@ ) <%%= "%" + ">" %> <%%= "<" + "%# Compute unlinked accounts (no AccountProvider link) %" + ">" %> - <%%= "<" + "% unlinked_count = #{file_name}_item.unlinked_#{file_name}_accounts.count rescue 0 %" + ">" %> + <%%= "<" + "% unlinked_count = #{file_name}_item.unlinked_#{file_name}_accounts&.count || 0 %" + ">" %> <%%= "<" + "% if unlinked_count.to_i > 0 && #{file_name}_item.accounts.empty? %" + ">" %> <%%= "<" + "%# No accounts imported yet - show prominent setup prompt %" + ">" %> diff --git a/lib/generators/provider/family/templates/provided_concern.rb.tt b/lib/generators/provider/family/templates/provided_concern.rb.tt index c0d25f790..689f45c4b 100644 --- a/lib/generators/provider/family/templates/provided_concern.rb.tt +++ b/lib/generators/provider/family/templates/provided_concern.rb.tt @@ -7,13 +7,14 @@ module <%= class_name %>Item::Provided return nil unless credentials_configured? Provider::<%= class_name %>.new( -<% parsed_fields.select { |f| f[:secret] }.each_with_index do |field, index| -%> - <%= field[:name] %>: <%= field[:name] %><%= index < parsed_fields.select { |f| f[:secret] }.size - 1 ? ',' : '' %> -<% end -%> -<% if parsed_fields.select { |f| f[:default] }.any? -%> -<% parsed_fields.select { |f| f[:default] }.each_with_index do |field, index| -%> - <%= field[:name] %>: effective_<%= field[:name] %><%= index < parsed_fields.select { |f| f[:default] }.size - 1 ? ',' : '' %> +<% secret_fields = parsed_fields.select { |f| f[:secret] } -%> +<% default_fields = parsed_fields.select { |f| f[:default] } -%> +<% secret_fields.each_with_index do |field, index| -%> +<% needs_comma = index < secret_fields.size - 1 || default_fields.any? -%> + <%= field[:name] %>: <%= field[:name] %><%= needs_comma ? ',' : '' %> <% end -%> +<% default_fields.each_with_index do |field, index| -%> + <%= field[:name] %>: effective_<%= field[:name] %><%= index < default_fields.size - 1 ? ',' : '' %> <% end -%> ) end diff --git a/lib/generators/provider/family/templates/setup_accounts.html.erb.tt b/lib/generators/provider/family/templates/setup_accounts.html.erb.tt index c76b25ef6..d52c4282e 100644 --- a/lib/generators/provider/family/templates/setup_accounts.html.erb.tt +++ b/lib/generators/provider/family/templates/setup_accounts.html.erb.tt @@ -55,13 +55,8 @@
<%%= "<" + "% @unlinked_accounts.each do |#{file_name}_account| %" + ">" %> - + <%%= "<" + "% end %" + ">" %> <%%= "<" + "% end %" + ">" %>