diff --git a/app/models/snaptrade_account.rb b/app/models/snaptrade_account.rb index 467ebe035..ddb7a4b63 100644 --- a/app/models/snaptrade_account.rb +++ b/app/models/snaptrade_account.rb @@ -17,7 +17,6 @@ class SnaptradeAccount < ApplicationRecord has_one :linked_account, through: :account_provider, source: :account validates :name, :currency, presence: true - validates :account_id, uniqueness: { scope: :snaptrade_item_id, allow_nil: true } validates :snaptrade_account_id, uniqueness: { scope: :snaptrade_item_id, allow_nil: true } # Enqueue cleanup job after destruction to avoid blocking transaction with API call diff --git a/db/migrate/20260219200003_scope_snaptrade_account_uniqueness_to_item.rb b/db/migrate/20260219200003_scope_snaptrade_account_uniqueness_to_item.rb index c44e9bfc0..2413e2203 100644 --- a/db/migrate/20260219200003_scope_snaptrade_account_uniqueness_to_item.rb +++ b/db/migrate/20260219200003_scope_snaptrade_account_uniqueness_to_item.rb @@ -4,16 +4,8 @@ # account can be linked in multiple families. See: https://github.com/we-promise/sure/issues/740 class ScopeSnaptradeAccountUniquenessToItem < ActiveRecord::Migration[7.2] def up - remove_index :snaptrade_accounts, name: "index_snaptrade_accounts_on_account_id", if_exists: true remove_index :snaptrade_accounts, name: "index_snaptrade_accounts_on_snaptrade_account_id", if_exists: true - unless index_exists?(:snaptrade_accounts, [ :snaptrade_item_id, :account_id ], unique: true, name: "index_snaptrade_accounts_on_item_and_account_id") - add_index :snaptrade_accounts, - [ :snaptrade_item_id, :account_id ], - unique: true, - name: "index_snaptrade_accounts_on_item_and_account_id", - where: "account_id IS NOT NULL" - end unless index_exists?(:snaptrade_accounts, [ :snaptrade_item_id, :snaptrade_account_id ], unique: true, name: "index_snaptrade_accounts_on_item_and_snaptrade_account_id") add_index :snaptrade_accounts, [ :snaptrade_item_id, :snaptrade_account_id ], @@ -24,20 +16,12 @@ class ScopeSnaptradeAccountUniquenessToItem < ActiveRecord::Migration[7.2] end def down - if execute("SELECT 1 FROM snaptrade_accounts WHERE account_id IS NOT NULL GROUP BY account_id HAVING COUNT(DISTINCT snaptrade_item_id) > 1 LIMIT 1").any? || - execute("SELECT 1 FROM snaptrade_accounts WHERE snaptrade_account_id IS NOT NULL GROUP BY snaptrade_account_id HAVING COUNT(DISTINCT snaptrade_item_id) > 1 LIMIT 1").any? + if execute("SELECT 1 FROM snaptrade_accounts WHERE snaptrade_account_id IS NOT NULL GROUP BY snaptrade_account_id HAVING COUNT(DISTINCT snaptrade_item_id) > 1 LIMIT 1").any? raise ActiveRecord::IrreversibleMigration, "Cannot rollback: cross-item duplicates exist in snaptrade_accounts. Remove duplicates first." end - remove_index :snaptrade_accounts, name: "index_snaptrade_accounts_on_item_and_account_id", if_exists: true remove_index :snaptrade_accounts, name: "index_snaptrade_accounts_on_item_and_snaptrade_account_id", if_exists: true - unless index_exists?(:snaptrade_accounts, :account_id, name: "index_snaptrade_accounts_on_account_id") - add_index :snaptrade_accounts, :account_id, - name: "index_snaptrade_accounts_on_account_id", - unique: true, - where: "account_id IS NOT NULL" - end unless index_exists?(:snaptrade_accounts, :snaptrade_account_id, name: "index_snaptrade_accounts_on_snaptrade_account_id") add_index :snaptrade_accounts, :snaptrade_account_id, name: "index_snaptrade_accounts_on_snaptrade_account_id", diff --git a/db/schema.rb b/db/schema.rb index 2c0572b53..484adc452 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -49,8 +49,6 @@ ActiveRecord::Schema[7.2].define(version: 2026_03_14_131357) do t.string "institution_name" t.string "institution_domain" t.text "notes" - t.jsonb "holdings_snapshot_data" - t.datetime "holdings_snapshot_at" t.index ["accountable_id", "accountable_type"], name: "index_accounts_on_accountable_id_and_accountable_type" t.index ["accountable_type"], name: "index_accounts_on_accountable_type" t.index ["currency"], name: "index_accounts_on_currency" @@ -1243,7 +1241,6 @@ ActiveRecord::Schema[7.2].define(version: 2026_03_14_131357) do create_table "snaptrade_accounts", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t| t.uuid "snaptrade_item_id", null: false t.string "name" - t.string "account_id" t.string "snaptrade_account_id" t.string "snaptrade_authorization_id" t.string "account_number" @@ -1265,7 +1262,6 @@ ActiveRecord::Schema[7.2].define(version: 2026_03_14_131357) do t.datetime "updated_at", null: false t.boolean "activities_fetch_pending", default: false t.date "sync_start_date" - t.index ["snaptrade_item_id", "account_id"], name: "index_snaptrade_accounts_on_item_and_account_id", unique: true, where: "(account_id IS NOT NULL)" t.index ["snaptrade_item_id", "snaptrade_account_id"], name: "index_snaptrade_accounts_on_item_and_snaptrade_account_id", unique: true, where: "(snaptrade_account_id IS NOT NULL)" t.index ["snaptrade_item_id"], name: "index_snaptrade_accounts_on_snaptrade_item_id" end @@ -1403,15 +1399,8 @@ ActiveRecord::Schema[7.2].define(version: 2026_03_14_131357) do t.datetime "updated_at", null: false t.string "currency" t.jsonb "locked_attributes", default: {} - t.decimal "realized_gain", precision: 19, scale: 4 - t.decimal "cost_basis_amount", precision: 19, scale: 4 - t.string "cost_basis_currency" - t.integer "holding_period_days" - t.string "realized_gain_confidence" - t.string "realized_gain_currency" t.string "investment_activity_label" t.index ["investment_activity_label"], name: "index_trades_on_investment_activity_label" - t.index ["realized_gain"], name: "index_trades_on_realized_gain_not_null", where: "(realized_gain IS NOT NULL)" t.index ["security_id"], name: "index_trades_on_security_id" end diff --git a/test/models/snaptrade_account_test.rb b/test/models/snaptrade_account_test.rb index c58a49558..48efc0f30 100644 --- a/test/models/snaptrade_account_test.rb +++ b/test/models/snaptrade_account_test.rb @@ -22,32 +22,9 @@ class SnaptradeAccountTest < ActiveSupport::TestCase ) end - test "same account_id can be linked under different snaptrade_items" do - SnaptradeAccount.create!( - snaptrade_item: @item_a, - account_id: "shared_snap_acc_1", - snaptrade_account_id: "snap_uuid_a_1", - name: "Brokerage", - currency: "USD", - current_balance: 10_000 - ) - - assert_difference "SnaptradeAccount.count", 1 do - SnaptradeAccount.create!( - snaptrade_item: @item_b, - account_id: "shared_snap_acc_1", - snaptrade_account_id: "snap_uuid_b_1", - name: "Brokerage", - currency: "USD", - current_balance: 10_000 - ) - end - end - test "same snaptrade_account_id can be linked under different snaptrade_items" do SnaptradeAccount.create!( snaptrade_item: @item_a, - account_id: "acc_a", snaptrade_account_id: "shared_snap_uuid_1", name: "IRA", currency: "USD", @@ -57,7 +34,6 @@ class SnaptradeAccountTest < ActiveSupport::TestCase assert_difference "SnaptradeAccount.count", 1 do SnaptradeAccount.create!( snaptrade_item: @item_b, - account_id: "acc_b", snaptrade_account_id: "shared_snap_uuid_1", name: "IRA", currency: "USD", @@ -66,43 +42,9 @@ class SnaptradeAccountTest < ActiveSupport::TestCase end end - test "same account_id cannot appear twice under the same snaptrade_item" do - SnaptradeAccount.create!( - snaptrade_item: @item_a, - account_id: "dup_acc", - snaptrade_account_id: "snap_1", - name: "Brokerage", - currency: "USD", - current_balance: 1000 - ) - - duplicate = SnaptradeAccount.new( - snaptrade_item: @item_a, - account_id: "dup_acc", - snaptrade_account_id: "snap_2", - name: "Brokerage", - currency: "USD", - current_balance: 1000 - ) - refute duplicate.valid? - assert_includes duplicate.errors[:account_id], "has already been taken" - - assert_raises(ActiveRecord::RecordInvalid) do - SnaptradeAccount.create!( - snaptrade_item: @item_a, - account_id: "dup_acc", - snaptrade_account_id: "snap_2", - name: "Brokerage", - currency: "USD", - current_balance: 1000 - ) - end - end - test "same snaptrade_account_id cannot appear twice under the same snaptrade_item" do SnaptradeAccount.create!( snaptrade_item: @item_a, - account_id: "acc_1", snaptrade_account_id: "dup_snap_uuid", name: "Brokerage", currency: "USD", @@ -111,7 +53,6 @@ class SnaptradeAccountTest < ActiveSupport::TestCase duplicate = SnaptradeAccount.new( snaptrade_item: @item_a, - account_id: "acc_2", snaptrade_account_id: "dup_snap_uuid", name: "Brokerage", currency: "USD", @@ -123,7 +64,6 @@ class SnaptradeAccountTest < ActiveSupport::TestCase assert_raises(ActiveRecord::RecordInvalid) do SnaptradeAccount.create!( snaptrade_item: @item_a, - account_id: "acc_2", snaptrade_account_id: "dup_snap_uuid", name: "Brokerage", currency: "USD",