Respect manually selected account type in SimpleFIN liability logic (#1214)

* Fix: don't let inferred liability overrride linked account type

* Update file tests to match new code, fix Ruby linter warning.
This commit is contained in:
Milo
2026-03-17 10:22:07 -07:00
committed by GitHub
parent 872e455213
commit 26aa260fb1
2 changed files with 31 additions and 7 deletions

View File

@@ -64,12 +64,17 @@ class SimplefinAccount::Processor
institution: org[:name]
) rescue nil
is_mapper_liability = inferred && [ "CreditCard", "Loan" ].include?(inferred.accountable_type)
is_liability = is_linked_liability || is_mapper_liability
is_liability =
if account.accountable_type.present?
is_linked_liability
else
is_mapper_liability
end
if is_mapper_liability && !is_linked_liability
Rails.logger.warn(
"SimpleFIN liability normalization: linked account #{account.id} type=#{account.accountable_type} " \
"appears to be liability via mapper (#{inferred.accountable_type}). Normalizing as liability; consider relinking."
"SimpleFIN account type mismatch: linked account #{account.id} type=#{account.accountable_type} " \
"differs from mapper inference (#{inferred.accountable_type}). Using linked account type."
)
end

View File

@@ -158,24 +158,43 @@ class SimplefinAccountProcessorTest < ActiveSupport::TestCase
assert_equal BigDecimal("-25"), acct.reload.balance
end
test "mislinked as asset but mapper infers credit → normalize as liability" do
test "linked depository account type takes precedence over mapper-inferred liability" do
sfin_acct = SimplefinAccount.create!(
simplefin_item: @item,
name: "Visa Signature",
account_id: "cc_mislinked",
account_id: "cc_mislinked_asset",
currency: "USD",
account_type: "credit",
current_balance: BigDecimal("100.00"),
available_balance: BigDecimal("5000.00")
)
# Link to an asset account intentionally
acct = accounts(:depository)
acct.update!(simplefin_account: sfin_acct)
SimplefinAccount::Processor.new(sfin_acct).send(:process_account!)
# Mapper should infer liability from name; final should be negative
# Manual selection as depository; final should be the same
assert_equal BigDecimal("100.00"), acct.reload.balance
end
test "linked credit card account type takes precedence over mapper-inferred liability" do
sfin_acct = SimplefinAccount.create!(
simplefin_item: @item,
name: "Visa Signature",
account_id: "cc_mislinked_liability",
currency: "USD",
account_type: "credit",
current_balance: BigDecimal("100.00"),
available_balance: BigDecimal("5000.00")
)
acct = accounts(:credit_card)
acct.update!(simplefin_account: sfin_acct)
SimplefinAccount::Processor.new(sfin_acct).send(:process_account!)
# Liability has flipped sign; final should be negative
assert_equal BigDecimal("-100.00"), acct.reload.balance
end