From 26d9ad76bf394eb6db07493f965b52e2785249da Mon Sep 17 00:00:00 2001 From: Guillem Arias Date: Thu, 14 May 2026 21:23:15 +0200 Subject: [PATCH] fix(goals): exclude pending transactions from pace + mobile-stack funding rows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two audit fixes that pair well. PF audit B20: pace, family velocity, and the funding widget's 30/90-day totals all summed Entry amounts over the linked accounts *including provider-pending transactions*. A pending Plaid/SimpleFIN deposit inflated pace today; the next sync that reversed or dropped it silently shrunk pace tomorrow, with no signal to the user. Worse, the reconciler could match a pending transaction and flip the pledge to "matched" before the underlying entry vanished. `.merge(Transaction.excluding_pending)` on the three Entry queries (Goal#pace, Family#savings_inflow_velocity, the funding widget's `inflow_totals_map`) brings the existing `Transaction::PENDING_PROVIDERS`-aware scope into play. Single-line fix across the three call sites. UX audit: funding-account rows used `grid-cols-[24px_1fr_48px_120px]` at every breakpoint. On a 375pt iPhone viewport that left ~50px for the name column after `p-5` padding + container chrome — name truncated to "Ban…" and the per-row % column squeezed against the weight/totals stack. The percent number is also already encoded in the distribution bar above the rows; on mobile it can disappear without losing signal. Drop the % column at < sm: - mobile grid: `grid-cols-[24px_minmax(0,1fr)_auto]` (avatar / name / totals) - sm+: original 4-column layout with the per-row % - per-row balance subline + accountable label now also drops `.00` cents (consistency with the rest of the page). --- .../funding_accounts_breakdown_component.html.erb | 14 +++++++++----- .../goals/funding_accounts_breakdown_component.rb | 1 + app/models/family.rb | 1 + app/models/goal.rb | 1 + 4 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/components/goals/funding_accounts_breakdown_component.html.erb b/app/components/goals/funding_accounts_breakdown_component.html.erb index 6f9b397f4..fcf167018 100644 --- a/app/components/goals/funding_accounts_breakdown_component.html.erb +++ b/app/components/goals/funding_accounts_breakdown_component.html.erb @@ -25,19 +25,23 @@ <% rows.each_with_index do |row, idx| %> <% account = row[:account] %> <% color = color_for(account) %> -
+
<%= render Goals::AvatarComponent.new(name: account.name, color: color, size: "sm") %>

<%= account.name %>

- <%= accountable_label(account) %> · <%= row[:balance_money].format %> + <%= accountable_label(account) %> · <%= row[:balance_money].format(precision: 0) %>

-

- <%= rows.size > 1 ? "#{percent_for(row[:balance])}%" : "" %> -

+ <% if rows.size > 1 %> + + <% else %> + + <% end %>
diff --git a/app/components/goals/funding_accounts_breakdown_component.rb b/app/components/goals/funding_accounts_breakdown_component.rb index 6acb71518..91e54203e 100644 --- a/app/components/goals/funding_accounts_breakdown_component.rb +++ b/app/components/goals/funding_accounts_breakdown_component.rb @@ -70,6 +70,7 @@ class Goals::FundingAccountsBreakdownComponent < ApplicationComponent .joins("INNER JOIN transactions ON transactions.id = entries.entryable_id AND entries.entryable_type = 'Transaction'") .where(account_id: account_ids, date: TREND_WINDOW_DAYS.days.ago.to_date..Date.current) .where(excluded: false) + .merge(Transaction.excluding_pending) .pluck(:account_id, :date, :amount) result = Hash.new { |h, k| h[k] = { last_30: 0.to_d, last_90: 0.to_d } } diff --git a/app/models/family.rb b/app/models/family.rb index c421b6ef7..a117f6cc8 100644 --- a/app/models/family.rb +++ b/app/models/family.rb @@ -71,6 +71,7 @@ class Family < ApplicationRecord .joins("INNER JOIN transactions ON transactions.id = entries.entryable_id AND entries.entryable_type = 'Transaction'") .where(account_id: account_ids, date: range) .where(excluded: false) + .merge(Transaction.excluding_pending) .sum(:amount) -net.to_d diff --git a/app/models/goal.rb b/app/models/goal.rb index a0b23b946..a8e8beb62 100644 --- a/app/models/goal.rb +++ b/app/models/goal.rb @@ -129,6 +129,7 @@ class Goal < ApplicationRecord .joins("INNER JOIN transactions ON transactions.id = entries.entryable_id AND entries.entryable_type = 'Transaction'") .where(account_id: account_ids, date: 90.days.ago.to_date..Date.current) .where(excluded: false) + .merge(Transaction.excluding_pending) .sum(:amount) (-net.to_d / 3).round(2) end