[PR #7243] [MERGED] Fix balance_current not syncing to API clients after bank sync #32958

Closed
opened 2026-04-18 08:54:52 -05:00 by GiteaMirror · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/actualbudget/actual/pull/7243
Author: @lwarrenthompson
Created: 3/20/2026
Status: Merged
Merged: 3/27/2026
Merged by: @matt-fidd

Base: masterHead: fix/account-balance-sync


📝 Commits (3)

  • f14ebaa [AI] Fix balance_current not syncing to API clients after bank sync
  • 2c9fc3d [AI] Add release notes for PR #7243
  • 5df88a3 Address review feedback: remove verbose comment and simplify release note

📊 Changes

2 files changed (+7 additions, -4 deletions)

View changed files

📝 packages/loot-core/src/server/accounts/sync.ts (+1 -4)
upcoming-release-notes/7243.md (+6 -0)

📄 Description

Summary

When SimpleFIN or GoCardless updates an account's bank balance on the server, the updateAccountBalance() function in accounts/sync.ts writes balance_current using raw SQL (db.runQuery), which bypasses the CRDT sync layer entirely. This means API clients calling api.sync() never receive the updated bank balance — balance_current stays null or stale in their local database.

Root cause: updateAccountBalance() uses db.runQuery('UPDATE accounts SET balance_current = ?...') instead of db.update('accounts', { id, balance_current: balance }). The db.update() function goes through sendMessages() which creates CRDT messages with timestamps that propagate to all synced clients. The raw SQL only updates the local database.

Fix: Replace db.runQuery() with db.update() so that balance_current changes go through the CRDT sync protocol, just like other account fields (name, closed, etc.).

Impact: This affects any API consumer (MCP servers, automation scripts, CLI tools) that uses @actual-app/api and needs to read current bank-reported balances. The web UI is unaffected because it reads directly from the server's database.

Note: balance_current is already a valid syncable column in the accounts table schema and is used in the CRDT sync property tests.


Bundle Stats

Bundle Files count Total bundle size % Changed
desktop-client 27 12.09 MB 0%
loot-core 1 4.83 MB → 4.83 MB (-13 B) -0.00%
api 4 4.06 MB → 4.06 MB (-18 B) -0.00%
cli 1 7.88 MB 0%
View detailed bundle stats

desktop-client

Total

Files count Total bundle size % Changed
27 12.09 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
static/js/index.js 3.23 MB 0%
static/js/BackgroundImage.js 119.98 kB 0%
static/js/FormulaEditor.js 846.44 kB 0%
static/js/ReportRouter.js 1.02 MB 0%
static/js/TransactionList.js 81.29 kB 0%
static/js/ca.js 182.91 kB 0%
static/js/da.js 104.66 kB 0%
static/js/de.js 174.79 kB 0%
static/js/en-GB.js 7.16 kB 0%
static/js/en.js 170.76 kB 0%
static/js/es.js 182.09 kB 0%
static/js/fr.js 177.47 kB 0%
static/js/indexeddb-main-thread-worker-e59fee74.js 13.46 kB 0%
static/js/it.js 166.25 kB 0%
static/js/narrow.js 354.27 kB 0%
static/js/nb-NO.js 152.2 kB 0%
static/js/nl.js 108.93 kB 0%
static/js/pl.js 88.34 kB 0%
static/js/pt-BR.js 177.84 kB 0%
static/js/resize-observer.js 18.03 kB 0%
static/js/sv.js 80.58 kB 0%
static/js/th.js 179.94 kB 0%
static/js/theme.js 30.68 kB 0%
static/js/uk.js 213.14 kB 0%
static/js/useTransactionBatchActions.js 4.29 MB 0%
static/js/wide.js 418 B 0%
static/js/workbox-window.prod.es5.js 7.28 kB 0%

loot-core

Total

Files count Total bundle size % Changed
1 4.83 MB → 4.83 MB (-13 B) -0.00%
Changeset
File Δ Size
home/runner/work/actual/actual/packages/loot-core/src/server/accounts/sync.ts 📉 -13 B (-0.06%) 22.43 kB → 22.42 kB
View detailed bundle breakdown

Added

Asset File Size % Changed
kcab.worker.CwpE34S5.js 0 B → 4.83 MB (+4.83 MB) -

Removed

Asset File Size % Changed
kcab.worker.B6yxrEsJ.js 4.83 MB → 0 B (-4.83 MB) -100%

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged
No assets were unchanged


api

Total

Files count Total bundle size % Changed
4 4.06 MB → 4.06 MB (-18 B) -0.00%
Changeset
File Δ Size
home/runner/work/actual/actual/packages/loot-core/src/server/accounts/sync.ts 📉 -18 B (-0.08%) 22.06 kB → 22.04 kB
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller

Asset File Size % Changed
index.js 3.84 MB → 3.84 MB (-18 B) -0.00%

Unchanged

Asset File Size % Changed
from-Bl-Hslp4.js 167.73 kB 0%
multipart-parser-BnDysoMr.js 8.1 kB 0%
src-iMkUmuwR.js 43.64 kB 0%

cli

Total

Files count Total bundle size % Changed
1 7.88 MB 0%
View detailed bundle breakdown

Added
No assets were added

Removed
No assets were removed

Bigger
No assets were bigger

Smaller
No assets were smaller

Unchanged

Asset File Size % Changed
cli.js 7.88 MB 0%

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/actualbudget/actual/pull/7243 **Author:** [@lwarrenthompson](https://github.com/lwarrenthompson) **Created:** 3/20/2026 **Status:** ✅ Merged **Merged:** 3/27/2026 **Merged by:** [@matt-fidd](https://github.com/matt-fidd) **Base:** `master` ← **Head:** `fix/account-balance-sync` --- ### 📝 Commits (3) - [`f14ebaa`](https://github.com/actualbudget/actual/commit/f14ebaadeededa62b95f3523afa4928bbd741335) [AI] Fix balance_current not syncing to API clients after bank sync - [`2c9fc3d`](https://github.com/actualbudget/actual/commit/2c9fc3d0ddc741d0cf7009c331e2896109eae9f2) [AI] Add release notes for PR #7243 - [`5df88a3`](https://github.com/actualbudget/actual/commit/5df88a3d647f6c9ce3c298720f3c5a6ffd87a62f) Address review feedback: remove verbose comment and simplify release note ### 📊 Changes **2 files changed** (+7 additions, -4 deletions) <details> <summary>View changed files</summary> 📝 `packages/loot-core/src/server/accounts/sync.ts` (+1 -4) ➕ `upcoming-release-notes/7243.md` (+6 -0) </details> ### 📄 Description ## Summary When SimpleFIN or GoCardless updates an account's bank balance on the server, the `updateAccountBalance()` function in `accounts/sync.ts` writes `balance_current` using raw SQL (`db.runQuery`), which bypasses the CRDT sync layer entirely. This means API clients calling `api.sync()` never receive the updated bank balance — `balance_current` stays `null` or stale in their local database. **Root cause:** `updateAccountBalance()` uses `db.runQuery('UPDATE accounts SET balance_current = ?...')` instead of `db.update('accounts', { id, balance_current: balance })`. The `db.update()` function goes through `sendMessages()` which creates CRDT messages with timestamps that propagate to all synced clients. The raw SQL only updates the local database. **Fix:** Replace `db.runQuery()` with `db.update()` so that `balance_current` changes go through the CRDT sync protocol, just like other account fields (`name`, `closed`, etc.). **Impact:** This affects any API consumer (MCP servers, automation scripts, CLI tools) that uses `@actual-app/api` and needs to read current bank-reported balances. The web UI is unaffected because it reads directly from the server's database. Note: `balance_current` is already a valid syncable column in the accounts table schema and is used in the CRDT sync property tests. <!--- actual-bot-sections ---> <hr /> <!--- bundlestats-action-comment key:combined start ---> ### Bundle Stats Bundle | Files count | Total bundle size | % Changed ------ | ----------- | ----------------- | --------- desktop-client | 27 | 12.09 MB | 0% loot-core | 1 | 4.83 MB → 4.83 MB (-13 B) | -0.00% api | 4 | 4.06 MB → 4.06 MB (-18 B) | -0.00% cli | 1 | 7.88 MB | 0% <details> <summary>View detailed bundle stats</summary> #### desktop-client **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 27 | 12.09 MB | 0% <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- static/js/index.js | 3.23 MB | 0% static/js/BackgroundImage.js | 119.98 kB | 0% static/js/FormulaEditor.js | 846.44 kB | 0% static/js/ReportRouter.js | 1.02 MB | 0% static/js/TransactionList.js | 81.29 kB | 0% static/js/ca.js | 182.91 kB | 0% static/js/da.js | 104.66 kB | 0% static/js/de.js | 174.79 kB | 0% static/js/en-GB.js | 7.16 kB | 0% static/js/en.js | 170.76 kB | 0% static/js/es.js | 182.09 kB | 0% static/js/fr.js | 177.47 kB | 0% static/js/indexeddb-main-thread-worker-e59fee74.js | 13.46 kB | 0% static/js/it.js | 166.25 kB | 0% static/js/narrow.js | 354.27 kB | 0% static/js/nb-NO.js | 152.2 kB | 0% static/js/nl.js | 108.93 kB | 0% static/js/pl.js | 88.34 kB | 0% static/js/pt-BR.js | 177.84 kB | 0% static/js/resize-observer.js | 18.03 kB | 0% static/js/sv.js | 80.58 kB | 0% static/js/th.js | 179.94 kB | 0% static/js/theme.js | 30.68 kB | 0% static/js/uk.js | 213.14 kB | 0% static/js/useTransactionBatchActions.js | 4.29 MB | 0% static/js/wide.js | 418 B | 0% static/js/workbox-window.prod.es5.js | 7.28 kB | 0% </div> </details> --- #### loot-core **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 1 | 4.83 MB → 4.83 MB (-13 B) | -0.00% <details> <summary>Changeset</summary> File | Δ | Size ---- | - | ---- `home/runner/work/actual/actual/packages/loot-core/src/server/accounts/sync.ts` | 📉 -13 B (-0.06%) | 22.43 kB → 22.42 kB </details> <details> <summary>View detailed bundle breakdown</summary> <div> **Added** Asset | File Size | % Changed ----- | --------- | --------- kcab.worker.CwpE34S5.js | 0 B → 4.83 MB (+4.83 MB) | - **Removed** Asset | File Size | % Changed ----- | --------- | --------- kcab.worker.B6yxrEsJ.js | 4.83 MB → 0 B (-4.83 MB) | -100% **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** No assets were unchanged </div> </details> --- #### api **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 4 | 4.06 MB → 4.06 MB (-18 B) | -0.00% <details> <summary>Changeset</summary> File | Δ | Size ---- | - | ---- `home/runner/work/actual/actual/packages/loot-core/src/server/accounts/sync.ts` | 📉 -18 B (-0.08%) | 22.06 kB → 22.04 kB </details> <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** Asset | File Size | % Changed ----- | --------- | --------- index.js | 3.84 MB → 3.84 MB (-18 B) | -0.00% **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- from-Bl-Hslp4.js | 167.73 kB | 0% multipart-parser-BnDysoMr.js | 8.1 kB | 0% src-iMkUmuwR.js | 43.64 kB | 0% </div> </details> --- #### cli **Total** Files count | Total bundle size | % Changed ----------- | ----------------- | --------- 1 | 7.88 MB | 0% <details> <summary>View detailed bundle breakdown</summary> <div> **Added** No assets were added **Removed** No assets were removed **Bigger** No assets were bigger **Smaller** No assets were smaller **Unchanged** Asset | File Size | % Changed ----- | --------- | --------- cli.js | 7.88 MB | 0% </div> </details> </details> <!--- bundlestats-action-comment key:combined end ---> --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
GiteaMirror added the pull-request label 2026-04-18 08:54:52 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/actual#32958