1
0
Fork 0
mirror of https://github.com/maybe-finance/maybe.git synced 2025-07-19 13:19:39 +02:00

Prevent account deletions when account is linked to a Plaid Item (#2218)

* Prevent account deletions when account is linked to a Plaid Item

* Only guard deletions in UI and controller, not at model level
This commit is contained in:
Zach Gollwitzer 2025-05-07 13:56:20 -04:00 committed by GitHub
parent 628d266980
commit a67f36bf64
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 39 additions and 25 deletions

View file

@ -50,9 +50,13 @@ module AccountableResource
end
def destroy
if @account.linked?
redirect_to account_path(@account), alert: "Cannot delete a linked account"
else
@account.destroy_later
redirect_to accounts_path, notice: t("accounts.destroy.success", type: accountable_type.name.underscore.humanize)
end
end
private
def set_link_token

View file

@ -45,10 +45,6 @@ module ApplicationHelper
content_for(:header_description) { page_description }
end
def family_stream
turbo_stream_from Current.family if Current.family
end
def page_active?(path)
current_page?(path) || (request.path.start_with?(path) && path != "/")
end

View file

@ -15,13 +15,20 @@ class PlaidAccount < ApplicationRecord
class << self
def find_or_create_from_plaid_data!(plaid_data, family)
find_or_create_by!(plaid_id: plaid_data.account_id) do |a|
a.account = family.accounts.new(
name: plaid_data.name,
balance: plaid_data.balances.current || plaid_data.balances.available,
currency: plaid_data.balances.iso_currency_code,
accountable: TYPE_MAPPING[plaid_data.type].new
)
PlaidAccount.transaction do
plaid_account = find_or_create_by!(plaid_id: plaid_data.account_id)
internal_account = family.accounts.find_or_initialize_by(plaid_account_id: plaid_account.id)
internal_account.name = plaid_data.name
internal_account.balance = plaid_data.balances.current || plaid_data.balances.available
internal_account.currency = plaid_data.balances.iso_currency_code
internal_account.accountable = TYPE_MAPPING[plaid_data.type].new
internal_account.save!
plaid_account.save!
plaid_account
end
end
end

View file

@ -6,7 +6,10 @@
<%= form.hidden_field :return_to, value: params[:return_to] %>
<%= form.text_field :name, placeholder: t(".name_placeholder"), required: "required", label: t(".name_label") %>
<% unless account.linked? %>
<%= form.money_field :balance, label: t(".balance"), required: true, default_currency: Current.family.currency %>
<% end %>
<%= yield form %>
</div>

View file

@ -13,6 +13,7 @@
) %>
<% end %>
<% unless account.linked? %>
<% menu.with_item(
variant: "button",
text: "Delete account",
@ -23,3 +24,4 @@
data: { turbo_frame: :_top }
) %>
<% end %>
<% end %>

View file

@ -30,7 +30,9 @@
</div>
</div>
<%= family_stream %>
<% if Current.family %>
<%= turbo_stream_from Current.family %>
<% end %>
<%= turbo_frame_tag "modal" %>
<%= turbo_frame_tag "drawer" %>

View file

@ -1,6 +1,6 @@
<%# locals: (message:) %>
<%= tag.div class: "flex gap-3 rounded-lg bg-container-inset p-4 group w-full md:max-w-80 shadow-border-lg",
<%= tag.div class: "flex gap-3 rounded-lg bg-container p-4 group w-full md:max-w-80 shadow-border-lg",
data: { controller: "element-removal" } do %>
<div class="h-5 w-5 shrink-0 p-px text-primary">
<div class="flex h-full items-center justify-center rounded-full bg-destructive">