From 175d3dc753d8f65836305756d58458239ab2f970 Mon Sep 17 00:00:00 2001 From: Cameron Roudebush Date: Fri, 16 May 2025 15:48:18 -0400 Subject: [PATCH] fix: Adding a fix for accounts that are missing subtype information - Updating to add look back days for transactions --- .env.example | 1 + app/controllers/simple_fin_controller.rb | 3 +-- app/models/provider/simple_fin.rb | 5 +++++ app/models/simple_fin_account.rb | 9 ++++----- config/initializers/simple_fin.rb | 6 +++--- sample.simple.fin.json | 17 ----------------- 6 files changed, 14 insertions(+), 27 deletions(-) diff --git a/.env.example b/.env.example index 3db72473..586429d2 100644 --- a/.env.example +++ b/.env.example @@ -53,6 +53,7 @@ APP_DOMAIN= # You'll want to follow the steps here for getting an AccessURL https://beta-bridge.simplefin.org/info/developers SIMPLE_FIN_ACCESS_URL= SIMPLE_FIN_RATE_LIMIT=24 # How many queries we may perform to SimpleFIN a day +SIMPLE_FIN_LOOK_BACK_DAYS=7 # How many days we should look back for transaction content on queries # Disable enforcing SSL connections # DISABLE_SSL=true diff --git a/app/controllers/simple_fin_controller.rb b/app/controllers/simple_fin_controller.rb index 9f6225ed..d7bc5f45 100644 --- a/app/controllers/simple_fin_controller.rb +++ b/app/controllers/simple_fin_controller.rb @@ -65,7 +65,7 @@ class SimpleFinController < ApplicationController next if account_exists(acc_detail) # Get sub type for this account from params - sub_type = params[:account][acc_detail["id"]]["subtype"] + sub_type = params.dig(:account, acc_detail["id"], :subtype) acc_detail["subtype"] = sub_type @@ -74,7 +74,6 @@ class SimpleFinController < ApplicationController acc_detail, simple_fin_item ) - # Trigger an account sync of our data simple_fin_account.sync_account_data!(acc_detail) end diff --git a/app/models/provider/simple_fin.rb b/app/models/provider/simple_fin.rb index 2c6070af..a6ef03a1 100644 --- a/app/models/provider/simple_fin.rb +++ b/app/models/provider/simple_fin.rb @@ -81,6 +81,8 @@ class Provider::SimpleFin ## # Sends a request to get all available accounts from SimpleFIN # + # For more spec information, see: https://www.simplefin.org/protocol.html#setup-token + # # @param [str] accountable_type The name of the account type we're looking for. # @param [int?] trans_start_date A linux epoch of the start date to get transactions of. # @param [int?] trans_end_date A linux epoch of the end date to get transactions between. @@ -161,6 +163,9 @@ class Provider::SimpleFin # Increment the call count for today. This also saves the record if new or updates if existing. rate_limit_record.update!(call_count: rate_limit_record.call_count + 1) + + # Cleanup old records + SimpleFinRateLimit.where("date < ?", today).delete_all end # Returns if this is a supported API of SimpleFIN by the access url in the config. diff --git a/app/models/simple_fin_account.rb b/app/models/simple_fin_account.rb index 5cf6da21..53b37331 100644 --- a/app/models/simple_fin_account.rb +++ b/app/models/simple_fin_account.rb @@ -70,7 +70,6 @@ class SimpleFinAccount < ApplicationRecord ## # Syncs all account data for the given sf_account_data parameter - # sf_account_data is a hash from Provider::SimpleFin#get_available_accounts def sync_account_data!(sf_account_data) accountable_attributes = { id: self.account.accountable_id } self.update!( @@ -107,7 +106,7 @@ class SimpleFinAccount < ApplicationRecord def sync_holdings!(sf_holdings_data) # 'account' here refers to self.account return unless self.account.present? && self.account.investment? && sf_holdings_data.is_a?(Array) - Rails.logger.info "SimpleFinAccount (#{self.account.id}): Entering sync_holdings! with #{sf_holdings_data.length} items." + Rails.logger.info "SimpleFINAccount (#{self.account.id}): Entering sync_holdings! with #{sf_holdings_data.length} items." # Get existing SimpleFIN holding IDs for this account to detect deletions existing_provider_holding_ids = self.account.holdings.where.not(simple_fin_holding_id: nil).pluck(:simple_fin_holding_id) @@ -115,7 +114,7 @@ class SimpleFinAccount < ApplicationRecord # Delete holdings that are no longer present in SimpleFIN's data holdings_to_delete_ids = existing_provider_holding_ids - current_provider_holding_ids - Rails.logger.info "SimpleFinAccount (#{self.account.id}): Will delete SF holding IDs: #{holdings_to_delete_ids}" + Rails.logger.info "SimpleFINAccount (#{self.account.id}): Will delete SF holding IDs: #{holdings_to_delete_ids}" self.account.holdings.where(simple_fin_holding_id: holdings_to_delete_ids).destroy_all sf_holdings_data.each do |holding_data| @@ -123,7 +122,7 @@ class SimpleFinAccount < ApplicationRecord security = find_or_create_security_from_holding_data(holding_data) next unless security # Skip if we can't determine a security - Rails.logger.info "SimpleFinAccount (#{self.account.id}): Processing SF holding ID #{holding_data['id']}" + Rails.logger.info "SimpleFINAccount (#{self.account.id}): Processing SF holding ID #{holding_data['id']}" existing_holding = self.account.holdings.find_or_initialize_by( security: security, date: Date.current, @@ -165,7 +164,7 @@ class SimpleFinAccount < ApplicationRecord if entry.changed? || entry.entryable.changed? # Check if entryable also changed entry.save! else - Rails.logger.info "SimpleFinAccount (#{self.account.id}): Entry for SF transaction ID #{transaction_data['id']} not changed, not saving." + Rails.logger.info "SimpleFINAccount (#{self.account.id}): Entry for SF transaction ID #{transaction_data['id']} not changed, not saving." end end end diff --git a/config/initializers/simple_fin.rb b/config/initializers/simple_fin.rb index 6d34aa98..1fc76d5c 100644 --- a/config/initializers/simple_fin.rb +++ b/config/initializers/simple_fin.rb @@ -1,11 +1,10 @@ class SimpleFinConfig - attr_accessor :access_url, :rate_limit, :max_history_days + attr_accessor :access_url, :rate_limit, :look_back_days def initialize @rate_limit = 24 - # TODO - @max_history_days = 1 # Was a constant, now part of config + @look_back_days = 7 end end @@ -18,6 +17,7 @@ Rails.application.configure do sf_config = SimpleFinConfig.new sf_config.access_url = ENV["SIMPLE_FIN_ACCESS_URL"] sf_config.rate_limit = ENV["SIMPLE_FIN_RATE_LIMIT"].to_i if ENV["SIMPLE_FIN_RATE_LIMIT"].present? + sf_config.look_back_days = ENV["SIMPLE_FIN_LOOK_BACK_DAYS"].to_i if ENV["SIMPLE_FIN_LOOK_BACK_DAYS"].present? config.simple_fin = sf_config end diff --git a/sample.simple.fin.json b/sample.simple.fin.json index 95e4d56d..29f3b2f5 100644 --- a/sample.simple.fin.json +++ b/sample.simple.fin.json @@ -452,23 +452,6 @@ } ], "holdings": [] - }, - { - "org": { - "domain": "www.discover.com", - "name": "Discover Credit Card", - "sfin-url": "https://beta-bridge.simplefin.org/simplefin", - "url": "https://www.discover.com", - "id": "www.discover.com" - }, - "id": "ACT-RANDOM-DISCOVER-CREDIT-CARD", - "name": "Discover Credit Card", - "currency": "USD", - "balance": "-10000", - "available-balance": "0.00", - "balance-date": 1746720778, - "transactions": [], - "holdings": [] } ], "x-api-message": [