From 749d54dd9689257e19b3cb652c967fa59ab4e0e5 Mon Sep 17 00:00:00 2001 From: BeltaKoda Date: Thu, 11 Jun 2026 14:26:40 -0400 Subject: [PATCH] Fix Plaid sync failure for loan subtypes missing from Loan::SUBTYPES (#2298) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PlaidAccount::TypeMappable maps the Plaid loan subtypes "home equity", "line of credit", and "business" to home_equity, line_of_credit, and business — but Loan::SUBTYPES never defined them. Linking any such account (e.g. a HELOC reported by the institution as loan/"line of credit") makes the item's sync fail with: Validation failed: Accountable subtype is not included in the list and, because Link itself succeeded, the failure is silent in the UI (same UX gap as #1792). Add the three subtypes to Loan::SUBTYPES, and add a regression test asserting every subtype emitted by TYPE_MAPPING is valid for its accountable so the mapper and models can't drift apart again. Co-authored-by: Claude Fable 5 --- app/models/loan.rb | 3 +++ test/models/plaid_account/type_mappable_test.rb | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/app/models/loan.rb b/app/models/loan.rb index 980c19885..4b6b88cca 100644 --- a/app/models/loan.rb +++ b/app/models/loan.rb @@ -5,6 +5,9 @@ class Loan < ApplicationRecord "mortgage" => { short: "Mortgage", long: "Mortgage" }, "student" => { short: "Student Loan", long: "Student Loan" }, "auto" => { short: "Auto Loan", long: "Auto Loan" }, + "home_equity" => { short: "Home Equity", long: "Home Equity Loan" }, + "line_of_credit" => { short: "Line of Credit", long: "Line of Credit" }, + "business" => { short: "Business Loan", long: "Business Loan" }, "other" => { short: "Other Loan", long: "Other Loan" } }.freeze diff --git a/test/models/plaid_account/type_mappable_test.rb b/test/models/plaid_account/type_mappable_test.rb index b3bc67083..ffc530bc2 100644 --- a/test/models/plaid_account/type_mappable_test.rb +++ b/test/models/plaid_account/type_mappable_test.rb @@ -32,4 +32,18 @@ class PlaidAccount::TypeMappableTest < ActiveSupport::TestCase assert_equal "other", @mock_processor.map_subtype("depository", nil) assert_equal "other", @mock_processor.map_subtype("depository", "unknown") end + + test "every mapped subtype is a valid subtype of its accountable" do + PlaidAccount::TypeMappable::TYPE_MAPPING.each do |plaid_type, config| + accountable_class = config[:accountable] + next unless accountable_class.const_defined?(:SUBTYPES) + + config[:subtype_mapping].each do |plaid_subtype, subtype| + assert_includes accountable_class::SUBTYPES.keys, subtype, + "TYPE_MAPPING maps #{plaid_type}/#{plaid_subtype.inspect} to #{subtype.inspect}, " \ + "which is not a valid #{accountable_class} subtype — syncing such an account fails " \ + "with 'Validation failed: Accountable subtype is not included in the list'" + end + end + end end