Please Ignore#2479
Conversation
Allows users to correct provider-reported balances for linked accounts where the bank omits certain liabilities (e.g. BNPL balances not reflected in the reported cash balance). The adjustment is stored on the account, applied during EnableBanking sync, and re-applied on save when changed via the account form. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add upstream-sync.yml: daily merge from we-promise/sure into fork main using a PAT so the push triggers downstream workflows; opens a deduped GitHub issue on conflict - publish.yml: tag main-branch pushes with `latest` so production deployments can pin to a stable tag; guard helm/mobile/release/version-bump jobs behind github.repository == 'we-promise/sure' to skip them silently in the fork Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tment The previous commit added the migration but did not update schema.rb. CI uses db:schema:load and was failing with a pending migration error. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Allow linked accounts to use the reconciliation ("Add Balance") flow so
users can anchor historical balances against bank statements. Manual
transactions and trades remain hidden for linked accounts to avoid
conflicts with provider sync.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The active view component (UI::Account::ActivityFeed) still had the original guard hiding Add Balance from linked accounts. Remove it so linked accounts can add reconciliation waypoints for historical balance correction. Transaction/trade items remain hidden for linked accounts to avoid conflicts with provider sync. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each push to main now: - Tags the Docker image with the current .sure-version (e.g. 0.7.2-alpha.4) in addition to the existing sha/latest tags - After a successful build, bumps the pre-release number for the next commit (0.7.2-alpha.4 -> 0.7.2-alpha.5) via a [skip ci] commit to avoid triggering a redundant workflow run Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a new "All" entry to the per-page dropdown so users can view every item in an account's activity feed without paging. Page navigation controls are hidden automatically when all entries fit on a single page. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Auto-submit forms inside the drawer frame were being submitted as frame navigations. Adding turbo_frame: "_top" decouples them from the drawer context so the dialog stays open across multiple field changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ubmit forms The exclude, activity type, and one-time toggle forms in the Settings section were missing turbo_frame: "_top", causing them to submit within the drawer frame and close the edit dialog on auto-submit. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds an Activity card year+month picker that filters entries to the selected calendar period and re-scopes the balance chart to the same range. Year-only selection covers Jan 1 - Dec 31; selecting a month narrows to that month. Cleared via a Clear link in the picker. The chart's PeriodPicker is hidden when a custom (keyless) period is active and replaced with a read-only date-range pill, so the active filter is unambiguous. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Restructure the shared pagination partial so the prev/numbers/next group grows to fill the available width and the page-number links distribute across it, with the per-page select pinned right. Widen Pagy's series window (size 9) so more page buttons are generated. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Picker links lived inside the entries Turbo Frame, so clicks only swapped that frame — the chart stayed stale and the URL never advanced. Targeting _top makes each pick a full Turbo Drive visit, so chart and activity update together and the params show up in the address bar. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Detects card-change transaction trios: an original purchase, a later charge on a different account, and a reimbursement back to the original account (the pattern produced by services that let you switch the card used for a purchase after the fact, up to ~180 days later). A new Settings > Card Changes review page surfaces each trio. Confirming keeps the original purchase as the single real expense and links the new-card charge and the reimbursement as a confirmed card_change transfer (forced to funds_movement) so they net to zero and drop out of spending and income analytics. Dismissing records a RejectedTransfer so the trio is not suggested again. - transfers.kind column + relaxed date-range validation for card_change - Family::CardChangeMatchable detection (same-currency, exact-amount) - CardChangeReimbursementsController (index/confirm/dismiss) + routes - review page, settings nav entry, i18n - model + controller tests Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Excluded transactions vanished from the account page because the activity query hardcoded `where(excluded: false)`, with no UI to reveal them. They still appeared (greyed-out) on the global Transactions page, and their amounts still counted toward the running balance — so the balance appeared to jump with no visible cause. Swap the filter for `excluding_split_parents`, matching the global transaction search and the balance materializer. Excluded entries now render greyed-out via the existing `entry.excluded` styling, while split parents stay hidden. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Clicking the eye button on a statement rendered 'Content missing' because the link is scoped to the statements_tab Turbo Frame but show returned a full settings-layout page with no matching frame. Make show/update frame-aware (mirroring AccountsController) so the statement detail renders inside the statements_tab frame with a Back to statements link, and redirect unlink back to the account statements list when invoked from that frame. Standalone Statement Vault pages still render the full page. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
When a transaction is matched as a transfer, the transfer drawer only exposed category/notes, so the name could not be changed. Add a shared name field that writes to both linked transactions, and show each side's transaction name in the From/To overview. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Extracts the dashboard cashflow sankey-building logic from PagesController into a shared IncomeStatement::SankeyBuilder PORO, exposed via IncomeStatement#cashflow_sankey_data(period:). Both the dashboard and the reports page now use the same code. Adds the cashflow widget as the top collapsible/reorderable section on the reports page, driven by the existing reports period filter so users can view cashflow for a specific month or custom range. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove pull_request/push triggers from Mobile CI and Chart CI, leaving only workflow_dispatch for manual runs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Note Currently processing new changes in this PR. This may take a few minutes, please wait... ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (59)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Accidental. Please ignore |
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 88c9bee4be
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
|
|
||
| if (new_name = transfer_update_params[:name]).present? | ||
| @transfer.outflow_transaction.entry.update!(name: new_name) | ||
| @transfer.inflow_transaction.entry.update!(name: new_name) |
There was a problem hiding this comment.
Require permission before renaming the inflow entry
When a transfer is between an account the user can write to and an inflow account they can only read, update authorizes only the outflow account before this new write, while set_transfer only requires the inflow transaction to be accessible. In that shared-account scenario, submitting a transfer name now mutates the read-only inflow entry, bypassing the destination account's permissions; require write access to the inflow account before updating its entry name.
Useful? React with 👍 / 👎.
| before_action :set_pair, only: %i[confirm dismiss] | ||
|
|
||
| def index | ||
| @candidates = Current.family.card_change_reimbursement_candidates |
There was a problem hiding this comment.
Scope card-change candidates to accessible accounts
This page is linked from settings for regular users, but the new query starts from Current.family and later loads all matching transactions for the family, not Current.user.accessible_accounts. In families with account sharing, a user with access to only some accounts can open this page and see candidate transaction names, amounts, dates, and account names from accounts they cannot access; build candidates from accessible account ids or gate the page to an authorized role.
Useful? React with 👍 / 👎.
| transaction: original, | ||
| label: t(".roles.original"), | ||
| badge: t(".badges.kept"), | ||
| badge_class: "bg-green-50 text-success theme-dark:bg-green-tint-10" %> |
There was a problem hiding this comment.
Use design tokens for the reimbursement badge
The repository UI guidelines in AGENTS.md require functional design tokens rather than raw Tailwind palette classes for ERB changes. This new badge introduces bg-green-50/theme-dark:bg-green-tint-10, so it will be inconsistent with the design system and should use the existing success/container tokens instead.
Useful? React with 👍 / 👎.
|
Caution Failed to replace (edit) comment. This is likely due to insufficient permissions or the comment being deleted. Error details |
There was a problem hiding this comment.
Pull request overview
This PR makes several functional additions across reporting, transfers, and account UX (cashflow Sankey chart, card-change reimbursement matching/confirmation flows, account activity date filtering, and linked-account balance adjustments), while also changing multiple GitHub Actions workflows (disabling some CI jobs/triggers and adding an upstream sync workflow).
Changes:
- Add cashflow Sankey data generation (
IncomeStatement::SankeyBuilder) and surface it on dashboard/reports, including a new default reports section order. - Introduce “card change reimbursement” detection + settings UI to confirm/dismiss candidates (creating
card_changetransfers and marking the pair asfunds_movement). - Add account activity year/month filtering (including UI component), pagination “all” option wiring, and linked-account
balance_adjustmentapplied during provider syncs.
Reviewed changes
Copilot reviewed 59 out of 59 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| test/models/user_test.rb | Updates expectation for new default reports section order. |
| test/models/transfer_test.rb | Adds coverage for extended date window on card_change transfers. |
| test/models/income_statement_test.rb | Adds tests for cashflow_sankey_data. |
| test/models/family/card_change_matchable_test.rb | Adds tests for card-change trio detection logic. |
| test/controllers/transfers_controller_test.rb | Adds coverage for renaming transfer-linked transaction entries. |
| test/controllers/card_change_reimbursements_controller_test.rb | Adds controller coverage for index/confirm/dismiss flows. |
| test/controllers/accounts_controller_test.rb | Adds coverage for activity period filtering and split/excluded behavior. |
| test/controllers/account_statements_controller_test.rb | Adds coverage for Turbo-frame vs full-page statement rendering/unlink behavior. |
| db/schema.rb | Updates schema for new columns and schema dump changes. |
| db/migrate/20260616120000_add_kind_to_transfers.rb | Adds transfers.kind with default standard. |
| db/migrate/20260614120000_add_balance_adjustment_to_accounts.rb | Adds accounts.balance_adjustment. |
| config/routes.rb | Adds card_change_reimbursements resource routes. |
| config/locales/views/transfers/en.yml | Adds i18n strings for transfer name/transaction name UI. |
| config/locales/views/shared/en.yml | Adds i18n for pagination “All”. |
| config/locales/views/settings/en.yml | Adds settings nav label for card changes. |
| config/locales/views/reports/en.yml | Adds cashflow section title. |
| config/locales/views/card_change_reimbursements/en.yml | Adds i18n for the new card-change reimbursements UI. |
| config/locales/views/accounts/en.yml | Adds i18n for balance adjustment + activity filter period UI. |
| config/locales/views/account_statements/en.yml | Adds i18n for “Back to statements”. |
| config/initializers/pagy.rb | Adjusts Pagy default nav size. |
| app/views/transfers/update.turbo_stream.erb | Updates Turbo Stream to refresh transaction-name fields on transfer update. |
| app/views/transfers/show.html.erb | Displays per-transaction names and adds editable name field. |
| app/views/transactions/show.html.erb | Forces auto-submit forms to target _top frame. |
| app/views/shared/_pagination.html.erb | Updates pagination layout and adds per-page “All” option. |
| app/views/settings/_settings_nav.html.erb | Adds settings nav link to card change reimbursements. |
| app/views/card_change_reimbursements/index.html.erb | Adds the card-change reimbursements index UI. |
| app/views/card_change_reimbursements/_leg.html.erb | Adds shared partial for displaying each leg of a candidate trio. |
| app/views/accounts/show/_activity.html.erb | Adjusts activity menu gating and actions. |
| app/views/accounts/show.html.erb | Passes activity-filter state into AccountPage activity feed and uses @chart_period. |
| app/views/accounts/_form.html.erb | Adds balance_adjustment field for linked accounts. |
| app/views/account_statements/show.html.erb | Supports Turbo-frame rendering when viewed within statements tab. |
| app/models/user.rb | Updates default reports section order to include cashflow. |
| app/models/transfer.rb | Adds transfer kind enum + extended date window for card-change transfers. |
| app/models/income_statement/sankey_builder.rb | New builder object for Sankey chart nodes/links payload. |
| app/models/income_statement.rb | Adds cashflow_sankey_data API. |
| app/models/family/card_change_matchable.rb | Adds SQL-based detector for card-change reimbursement trios. |
| app/models/family.rb | Includes new CardChangeMatchable concern. |
| app/models/enable_banking_account/processor.rb | Applies balance_adjustment when syncing effective balance. |
| app/controllers/transfers_controller.rb | Permits name in transfer updates and applies it to both entries. |
| app/controllers/reports_controller.rb | Adds cashflow section + uses cashflow_sankey_data; adjusts section ordering logic. |
| app/controllers/pages_controller.rb | Switches dashboard Sankey generation to IncomeStatement#cashflow_sankey_data. |
| app/controllers/concerns/safe_pagination.rb | Adds per_page=all handling. |
| app/controllers/concerns/accountable_resource.rb | Permits balance_adjustment and recalculates anchor on adjustment changes. |
| app/controllers/card_change_reimbursements_controller.rb | New controller for listing/confirming/dismissing card-change candidates. |
| app/controllers/accounts_controller.rb | Adds year/month activity filtering and uses @chart_period. |
| app/controllers/account_statements_controller.rb | Adds Turbo-frame detection + conditional layout/redirect behavior. |
| app/components/UI/account/chart.html.erb | Shows a fixed date range label when period has no key. |
| app/components/UI/account/activity_feed.rb | Plumbs selected year/month into activity feed component. |
| app/components/UI/account/activity_feed.html.erb | Adds activity date filter UI + preserves date params in search. |
| app/components/UI/account/activity_date_filter.rb | New component for year/month filtering links. |
| app/components/UI/account/activity_date_filter.html.erb | New popover UI for year/month selection + clear action. |
| app/components/UI/account_page.rb | Extends activity feed slot API to accept selected year/month. |
| .sure-version | Bumps app version. |
| .github/workflows/upstream-sync.yml | Adds scheduled workflow to merge upstream into main and file a conflict issue. |
| .github/workflows/publish.yml | Adds tagging tweaks and auto-bump step; gates some jobs to upstream repo only. |
| .github/workflows/preview-cleanup.yml | Disables preview cleanup jobs. |
| .github/workflows/mobile-ci.yml | Removes automatic triggers; manual only. |
| .github/workflows/ci.yml | Disables unit/system test jobs. |
| .github/workflows/chart-ci.yml | Removes automatic triggers; manual only. |
| def dismiss | ||
| RejectedTransfer.find_or_create_by!( | ||
| inflow_transaction_id: @inflow.id, | ||
| outflow_transaction_id: @outflow.id | ||
| ) | ||
|
|
||
| redirect_to card_change_reimbursements_path, notice: t(".dismissed") | ||
| end |
| rescue ActiveRecord::RecordInvalid | ||
| false |
| if @account.linked? && @account.saved_change_to_balance_adjustment? | ||
| old_adj, new_adj = @account.saved_change_to_balance_adjustment | ||
| raw_anchor = @account.current_anchor_balance.to_d - old_adj.to_d | ||
| @account.set_current_balance(raw_anchor + new_adj.to_d) | ||
| end |
| def safe_per_page(default = 10) | ||
| return 10_000 if params[:per_page] == "all" | ||
|
|
||
| allowed_values = [ 10, 20, 30, 50, 100 ] |
| <% per_page_selected = pagy.limit > 100 ? "all" : pagy.limit.to_s %> | ||
| <%= select_tag :per_page, | ||
| options_for_select(["10", "20", "30", "50", "100"], pagy.limit), | ||
| options_for_select([["10", "10"], ["20", "20"], ["30", "30"], ["50", "50"], ["100", "100"], [t(".all"), "all"]], per_page_selected), | ||
| data: { controller: "selectable-link" }, | ||
| class: "py-1.5 pr-8 text-sm text-primary font-medium bg-container-inset border border-secondary rounded-lg focus:border-secondary focus:ring-secondary focus-visible:ring-secondary" %> |
| test_unit: | ||
| if: false | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
|
|
| cleanup-on-close: | ||
| name: Cleanup closed PR preview | ||
| if: github.event_name == 'pull_request' && (github.event.action == 'closed' || (github.event.action == 'unlabeled' && github.event.label.name == 'preview-cf')) | ||
| if: false | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 |
| test_unit: | ||
| if: false | ||
| runs-on: ubuntu-latest | ||
| timeout-minutes: 10 | ||
|
|
No description provided.