Honor per-currency decimal places across app#6954
Honor per-currency decimal places across app#6954StephenBrown2 wants to merge 2 commits intoactualbudget:masterfrom
Conversation
✅ Deploy Preview for actualbudget ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
👋 Hello contributor! We would love to review your PR! Before we can do that, please make sure:
We do this to reduce the TOIL the core contributor team has to go through for each PR and to allow for speedy reviews and merges. For more information, please see our Contributing Guide. |
139524f to
762e987
Compare
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughAdds data-driven Playwright e2e tests for currency formatting/precision, a currency-precision helper and Settings page helpers to toggle/select currency, and updates the VRT workflow to reduce noisy PNG snapshot commits. Changes
Sequence Diagram(s)sequenceDiagram
participant Test as Playwright Test
participant Nav as Navigation (page-model)
participant Settings as Settings Page
participant App as App UI (Accounts/Budget)
Test->>Nav: goToSettingsPage()
Nav->>Settings: open Settings
Test->>Settings: setDefaultCurrency(code)
Settings-->>Test: confirm currency selected / experimental toggled
Test->>App: navigate to target page (accounts or budget)
App-->>Test: render with selected currency
Test->>App: create account / open modal / assert formatted balances
App-->>Test: return displayed values (expectedDisplay)
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Poem
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ 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 |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/sync-server/src/app-pluggyai/app-pluggyai.js (1)
132-140:⚠️ Potential issue | 🟡 MinorMinor inconsistency: rounding uses fallback currency but
transactionAmount.currencydoes not.Line 134 falls back to
account.currencyCodewhentrans.currencyCodeis falsy, but line 139 storescurrency: trans.currencyCodewithout the same fallback. Iftrans.currencyCodeis undefined, the amount is rounded using the account's currency precision but tagged with an undefined currency.Proposed fix
+ const effectiveCurrency = trans.currencyCode || account.currencyCode; amountInCurrency = roundToCurrencyDecimals( amountInCurrency, - trans.currencyCode || account.currencyCode, + effectiveCurrency, ); newTrans.transactionAmount = { amount: amountInCurrency, - currency: trans.currencyCode, + currency: effectiveCurrency, };
🤖 Fix all issues with AI agents
In `@packages/sync-server/src/app-gocardless/banks/abnamro_abnanl2a.js`:
- Line 1: Rename this adapter file from .js to .ts and convert its module shape
to TypeScript: change any CommonJS exports to ES module syntax (use export or
export default), add explicit types for all function parameters and return
values (e.g., annotate the adapter entry function, any helpers, and imported
values like amountToInteger usage), import any types you need from surrounding
packages (e.g., types for transactions, bank records, or amount
representations), and fix any implicit any or dynamic property access by
declaring appropriate interfaces or type aliases; finally run type-checking and
adjust any runtime-specific code (global/require usage) to be
TypeScript-compatible.
In `@packages/sync-server/src/app-gocardless/banks/american_express_aesudef1.js`:
- Around line 36-50: The reduce call currently passes currency code strings into
amountToInteger (in the sortedTransactions.reduce and the initial amount for
currentBalance.balanceAmount), causing NaN; fix by resolving the currency to its
decimalPlaces via getCurrency(...) and pass that number as the second arg to
amountToInteger (e.g., const dp =
getCurrency(trans.transactionAmount.currency).decimalPlaces and use
amountToInteger(trans.transactionAmount.amount, dp)), and do the same for
currentBalance.balanceAmount before the reduce; ensure getCurrency is
imported/available in this module and use the same symbol names
(amountToInteger, sortedTransactions.reduce, currentBalance.balanceAmount) so
both call sites pass a numeric decimalPlaces value instead of the currency
string.
In `@packages/sync-server/src/app-gocardless/banks/nbg_ethngraaxxx.js`:
- Around line 47-61: The reduce currently passes a currency code string into
amountToInteger, causing NaN; change calls so you resolve the currency to its
decimalPlaces first (e.g., use
getCurrency(trans.transactionAmount.currency).decimalPlaces and
getCurrency(currentBalance.balanceAmount.currency).decimalPlaces) and pass that
number as the second argument to amountToInteger for both the per-transaction
conversion and the initial balance in the reduce; update every occurrence in the
GoCardless bank files (e.g., nbg_ethngraaxxx.js) that references amountToInteger
with transactionAmount.currency or currentBalance.balanceAmount.currency.
🧹 Nitpick comments (1)
packages/sync-server/src/app-simplefin/app-simplefin.js (1)
232-235: Minor inconsistency in currency fallback:''vs'USD'.Line 182 falls back to
getCurrency(account.currency || '')(resolving to the "None" currency with 2 decimal places), while line 234 falls back to'USD'. Both happen to yield 2 decimal places, but the intent differs. Consider using a consistent fallback (e.g.,'USD'in both places, or extracting the resolved currency once).
There was a problem hiding this comment.
Actionable comments posted: 10
🤖 Fix all issues with AI agents
In `@packages/sync-server/src/app-gocardless/banks/abnamro_abnanl2a.js`:
- Around line 42-56: The code is passing a currency code string into
amountToInteger instead of the numeric decimalPlaces; find the calls to
amountToInteger in this module (e.g., where oldestKnownBalance and balance are
computed using oldestTransaction.balanceAfterTransaction.balanceAmount.currency
and balance.balanceAmount.currency) and replace the currency string with
getCurrency(<currencyCode>).decimalPlaces (e.g., const currency =
getCurrency(...); then pass currency.decimalPlaces to amountToInteger) so
Math.pow receives a number and balance calculations work correctly.
In `@packages/sync-server/src/app-gocardless/banks/danskebank_privat.js`:
- Around line 37-51: The reduction is passing a currency code string into
amountToInteger where a decimalPlaces number is required, causing NaN; update
the calls inside the reducer and the initial value to use
getCurrency(...).decimalPlaces instead of the raw currency string — i.e., for
trans.transactionAmount.currency and currentBalance.balanceAmount.currency call
getCurrency(currency).decimalPlaces and pass that number into amountToInteger
(affecting the sortedTransactions reducer and the initial amountToInteger call).
In `@packages/sync-server/src/app-gocardless/banks/entercard_swednokk.js`:
- Around line 35-46: The bug is passing a currency code string into
amountToInteger's second parameter (decimalPlaces); update the code to import
and use getCurrency to derive decimal places and pass that number instead.
Specifically, where amountToInteger(...) is called with
trans.transactionAmount.currency or balances[0]?.balanceAmount?.currency as the
second arg, replace that argument with getCurrency(<currencyCode>).decimalPlaces
(e.g., getCurrency(trans.transactionAmount.currency).decimalPlaces and
getCurrency(balances[0]?.balanceAmount?.currency).decimalPlaces) and add the
import for getCurrency from 'loot-core/shared/currencies'; keep amountToInteger
usage otherwise unchanged.
In `@packages/sync-server/src/app-gocardless/banks/ing_ingddeff.js`:
- Around line 43-57: The reduce currently calls amountToInteger(...,
trans.transactionAmount.currency) and amountToInteger(...,
currentBalance.balanceAmount.currency) passing currency codes (strings) instead
of numeric decimal places; update those calls to pass
getCurrency(trans.transactionAmount.currency).decimalPlaces and
getCurrency(currentBalance.balanceAmount.currency).decimalPlaces respectively so
amountToInteger receives a number; keep the rest of the reduce logic and use the
existing getCurrency helper like other integrations.
In `@packages/sync-server/src/app-gocardless/banks/ing_pl_ingbplpw.js`:
- Around line 31-45: The bug is that amountToInteger is being called with a
currency string (e.g.,
oldestTransaction.balanceAfterTransaction.balanceAmount.currency or
balance.currency) where it expects decimalPlaces (a number), causing NaN; fix by
resolving the currency to its decimal places before calling amountToInteger
(e.g., add or reuse a helper like
currencyToDecimalPlaces/getCurrencyDecimalPlaces and pass its numeric result
into amountToInteger for both calls that compute
oldestKnownBalance/oldestTransactionAmount and the interimBooked balance),
ensuring all references to amountToInteger(...) use the decimalPlaces number
rather than the currency string.
In `@packages/sync-server/src/app-gocardless/banks/integration-bank.js`:
- Around line 89-103: The reduce that computes the balance uses a broken import
and passes a currency string to amountToInteger; replace the broken import of
amountToInteger with the correct utility from loot-core/shared/util (or the
module that currently exports amountToInteger) and change callers to resolve
decimal places via getCurrency(currencyCode). Specifically, in the file
referencing amountToInteger, import getCurrency and the correct amountToInteger
export, then in the reduce over sortedTransactions (and the initial
currentBalance call) call amountToInteger(trans.transactionAmount.amount,
getCurrency(trans.transactionAmount.currency).decimalPlaces) and
amountToInteger(currentBalance?.balanceAmount?.amount || 0,
getCurrency(currentBalance?.balanceAmount?.currency).decimalPlaces) so the
second arg is a number not a string.
In `@packages/sync-server/src/app-gocardless/banks/norwegian_xx_norwnok1.js`:
- Line 1: Rename the adapter file norwegian_xx_norwnok1.js to
norwegian_xx_norwnok1.ts and convert its exports and functions to TypeScript:
change any CommonJS exports to ES module exports (export default / named
exports), add explicit type annotations for function parameters and return
values (e.g., transaction/amount types used by the adapter), and import
amountToInteger with proper types (import { amountToInteger } from
'loot-core/shared/util';). Ensure any JSON or external data parsed by the
adapter is typed (use interfaces for parsed records) and fix any TypeScript
compile errors (missing types, implicit any) so the module builds cleanly under
the repo TypeScript rules.
In `@packages/sync-server/src/app-gocardless/banks/seb_kort_bank_ab.js`:
- Around line 71-89: The three calls to amountToInteger are passing a currency
string where a decimalPlaces number is expected (in the reduce over
sortedTransactions and the initial accumulator using currentBalance and
nonInvoiced), causing NaN; update each call to pass
getCurrency(<currency>).decimalPlaces instead of the raw currency
string—specifically change the amountToInteger invocations that reference
trans.transactionAmount.currency, currentBalance.balanceAmount.currency, and
nonInvoiced.balanceAmount.currency to use getCurrency(...).decimalPlaces so
amountToInteger receives the numeric decimalPlaces parameter.
In `@packages/sync-server/src/app-gocardless/banks/seb_privat.js`:
- Around line 25-39: The reduction currently calls amountToInteger(...,
trans.transactionAmount.currency) and amountToInteger(...,
currentBalance.balanceAmount.currency) passing currency strings (causing NaN);
update both calls to pass the numeric decimalPlaces from the currency object
instead, e.g. call getCurrency(trans.transactionAmount.currency).decimalPlaces
and getCurrency(currentBalance.balanceAmount.currency).decimalPlaces so
amountToInteger receives a number; adjust the two locations inside the
sortedTransactions.reduce and the initial accumulator accordingly.
In `@packages/sync-server/src/app-simplefin/app-simplefin.js`:
- Around line 180-183: The code uses inconsistent fallbacks for missing
account.currency (getCurrency(account.currency || '') in the startingBalance
calculation vs getCurrency(account.currency || 'USD') elsewhere); update both
places that call getCurrency with account.currency to use the same explicit
fallback (e.g., 'USD') so decimalPlaces are computed consistently—search for
calls around startingBalance and the later balance parsing (the
amountToInteger(parseFloat(account.balance), getCurrency(...).decimalPlaces)
patterns) and replace the '' fallback with 'USD' (or a single chosen constant)
across both occurrences.
🧹 Nitpick comments (2)
upcoming-release-notes/6954.md (1)
6-6: Make the release note a complete, user-facing sentence.This is concise but reads like a fragment. Consider a short sentence like “Fixes amounts for currencies with non‑standard decimal places across the app.”
As per coding guidelines, keep upcoming-release-notes entries concise and non-technical.packages/loot-core/src/shared/currencies.ts (1)
64-64: Add support for three-decimal currencies (KWD, BHD) to complete PR objectives.The VND change to
decimalPlaces: 0is safe—sync adapters already properly pass currency-specific decimal places viagetCurrencyDecimalPlaces(). However, the PR objectives mention adding three-decimal currency support (KWD, BHD, etc.), and these entries are missing from currencies.ts. Add them to fully deliver on the stated goals.
762e987 to
f841f35
Compare
✅ Deploy Preview for actualbudget-website ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Fix all issues with AI agents
In `@packages/sync-server/src/app-gocardless/bank-factory.js`:
- Around line 13-18: The filename filter in
packages/sync-server/src/app-gocardless/bank-factory.js incorrectly accepts
TypeScript files by checking filename.endsWith('.ts'); remove the .ts branch
from the .filter callback so it only accepts files ending with '.js' (and still
requires '_' in the name), ensuring runtime only loads compiled JavaScript
modules; update the filter expression that currently checks
filename.includes('_') && (filename.endsWith('.js') || (filename.endsWith('.ts')
&& !filename.endsWith('.d.ts'))) to only allow filename.endsWith('.js')
alongside the underscore check.
In `@packages/sync-server/src/app-gocardless/banks/abnamro_abnanl2a.ts`:
- Around line 53-57: sortTransactions currently assumes every transaction has
valueDateTime, which can produce NaN and break sorting; update sortTransactions
to guard against missing valueDateTime by using a fallback date (e.g.,
bookingDate or epoch) when valueDateTime is falsy, convert the chosen date to a
timestamp safely, and use that timestamp for comparisons in the comparator so
transactions without valueDateTime sort deterministically; locate the logic in
the sortTransactions method in abnamro_abnanl2a.ts and apply the fallback there.
In `@packages/sync-server/src/app-gocardless/banks/ing_pl_ingbplpw.js`:
- Around line 46-48: The direct access to .balanceAmount after
balances.find(...) can throw if no 'interimBooked' entry exists; change the
inline extraction to first store the found item (e.g., const interim =
balances.find(b => b.balanceType === 'interimBooked')), then safely read its
amount using optional chaining or a fallback (e.g., const balance =
interim?.balanceAmount ?? null or 0) to avoid a TypeError when interim is
undefined.
In `@packages/sync-server/src/app-gocardless/banks/norwegian_xx_norwnok1.js`:
- Around line 71-85: The reducer mixes integer amounts converted with differing
decimalPlaces (transaction currency vs balance currency), producing incorrect
arithmetic; change it so all conversions use the account/balance currency's
decimalPlaces: compute balanceCurrencyDecimals once from
currentBalance.balanceAmount.currency (fallback if missing) and call
amountToInteger(..., balanceCurrencyDecimals) for the initial total and for
every trans in sortedTransactions (instead of passing
getCurrency(trans.transactionAmount.currency).decimalPlaces); keep using
sortedTransactions.reduce and amountToInteger but normalize every value to the
balance currency scale.
- Around line 75-78: The amount passed to amountToInteger is a string from the
GoCardless API; update the call site so trans.transactionAmount.amount is
explicitly converted to a number (e.g., via Number()) before passing to
amountToInteger, keeping the getCurrency(trans.transactionAmount.currency ||
'').decimalPlaces usage unchanged to ensure correct decimalPlaces lookup.
In `@packages/sync-server/src/app-gocardless/banks/sandboxfinance_sfin0000.js`:
- Around line 25-39: The reduce and initial balance calls pass GoCardless string
amounts into amountToInteger (which expects a numeric Amount), so convert those
string amount values to numbers before calling amountToInteger; update the
reducer to call amountToInteger(Number(trans.transactionAmount.amount),
getCurrency(...).decimalPlaces) and the initial value to
amountToInteger(Number(currentBalance.balanceAmount.amount),
getCurrency(...).decimalPlaces), ensuring you use Number(...) or parseFloat(...)
to match the pattern used in abnamro_abnanl2a.ts and respect the
amountToInteger(amount: Amount, decimalPlaces) contract.
In `@packages/sync-server/src/app-pluggyai/app-pluggyai.js`:
- Around line 131-140: The code uses effectiveCurrency (trans.currencyCode ||
account.currencyCode) for both rounding and labeling even when amountInCurrency
comes from trans.amountInAccountCurrency, causing mismatched currency/precision;
change the logic in the block that computes amountInCurrency/amount rounding and
newTrans.transactionAmount so that the currency used for roundToCurrencyDecimals
and for the resulting transactionAmount.currency is tied to the actual amount
source: if trans.amountInAccountCurrency is non-null/defined, set the
roundingCurrency and label to account.currencyCode and round
trans.amountInAccountCurrency, otherwise use trans.amount and use
trans.currencyCode (falling back to account.currencyCode as currently done);
update variables effectiveCurrency/amountInCurrency accordingly and ensure
newTrans.transactionAmount.amount matches the chosen amount value and currency.
🧹 Nitpick comments (1)
packages/sync-server/src/app-gocardless/banks/integration-bank.js (1)
90-101:trans.transactionAmount.amountis a string from the GoCardless API — implicit coercion is fragile.The GoCardless API returns
transactionAmount.amountas a string (e.g.,"123.45"), andamountToIntegerinloot-core/shared/utilis typed to accept a numericAmount. JavaScript's*operator coerces the string to a number at runtime, so this won't break, but it silently depends on implicit coercion and would fail TypeScript type-checking if this file is ever migrated.Consider wrapping with
Number(...)for clarity:Suggested improvement
return ( total - amountToInteger( - trans.transactionAmount.amount, + Number(trans.transactionAmount.amount), getCurrency(trans.transactionAmount.currency || '').decimalPlaces, ) ); }, amountToInteger( - currentBalance?.balanceAmount?.amount || 0, + Number(currentBalance?.balanceAmount?.amount || 0), getCurrency(currentBalance?.balanceAmount?.currency || '').decimalPlaces, ),
98c1281 to
df3c0fb
Compare
There was a problem hiding this comment.
Actionable comments posted: 11
🤖 Fix all issues with AI agents
In `@packages/loot-core/src/server/accounts/sync.ts`:
- Around line 448-451: trans.amount can be a string (e.g. GoCardless
transactionAmount.amount) but is passed into amountToInteger which expects a
numeric Amount; update normalizeBankSyncTransactions so trans.amount is
explicitly coerced to a Number when assigned from trans.transactionAmount.amount
and also ensure the call site that uses trans.amount (the amountToInteger(...)
invocation with getCurrencyDecimalPlaces) wraps the value with Number(...) or
parseFloat(...) and handles NaN (e.g., treat as 0 or throw an explicit error).
Target the assignment where trans.amount is set from transactionAmount.amount
and the call using amountToInteger to ensure type-safe numeric conversion.
In `@packages/loot-core/src/shared/currencies.ts`:
- Line 64: The VND mapping change (code 'VND' in currencies.ts) from
decimalPlaces:2 to decimalPlaces:0 will re-interpret existing stored integer
amounts and cause a 100x inflation, so either revert to decimalPlaces:2 until a
migration exists or implement a data migration/versioned conversion: detect rows
where currency == 'VND' and convert stored integer amounts by dividing by 100
(or otherwise rescaling values to match new zero-decimal semantics), record a
schema/data version flag, update any import/export/seed logic and unit tests
that rely on VND handling, and only then change the currencies.ts entry to
decimalPlaces:0.
In `@packages/loot-core/src/shared/util.ts`:
- Around line 458-483: The divisible-by-divisor branch of
integerToCurrencyWithDecimal currently always forces decimalPlaces and ignores
the configured hideFraction setting; update the second getNumberFormat call
inside integerToCurrencyWithDecimal to pass hideFraction:
numberFormatConfig.hideFraction (or otherwise derive hideFraction from your
numberFormatConfig) so that when there are no fractional digits the formatter
respects the hideFraction setting; keep the first branch using hideFraction:
false for the case where fractional digits exist.
In `@packages/sync-server/src/app-gocardless/banks/abnamro_abnanl2a.js`:
- Around line 62-75: The code converts
oldestTransaction.balanceAfterTransaction.balanceAmount and
oldestTransaction.transactionAmount using potentially different currency scales
(decimalPlaces), causing mixed-scale subtraction; update the conversion so both
amountToInteger calls use the balance currency's decimalPlaces (retrieve once
from oldestTransaction.balanceAfterTransaction.balanceAmount.currency via
getCurrency) and use that same decimalPlaces for oldestKnownBalance and
oldestTransactionAmount to ensure both integers share the same scale (refer to
amountToInteger, getCurrency, oldestKnownBalance, oldestTransactionAmount).
In `@packages/sync-server/src/app-gocardless/banks/entercard_swednokk.js`:
- Around line 36-47: Convert string amounts to numbers and use a single balance
currency scale when computing integer amounts: ensure calls to amountToInteger
wrap trans.transactionAmount.amount and balances[0]?.balanceAmount?.amount with
Number(...), and compute a single balanceCurrencyDecimals once by calling
getCurrency(...) on balances[0]?.balanceAmount?.currency (or fallback) then pass
that balanceCurrencyDecimals into every amountToInteger invocation (instead of
using each transaction's own getCurrency(...).decimalPlaces) so all integers
share the same scale.
In `@packages/sync-server/src/app-gocardless/banks/ing_ingddeff.js`:
- Around line 44-58: The reduce block subtracts transaction amounts but assumes
string-to-number conversion and that currentBalance exists; update the logic in
the sortedTransactions.reduce call to wrap amount strings with Number(...)
before passing into amountToInteger (e.g., trans.transactionAmount.amount and
currentBalance.balanceAmount.amount) and defensively handle a potentially
undefined currentBalance (from the prior find()) by defaulting the starting
balance to 0 (or "0") so amountToInteger always receives a valid amount; keep
using getCurrency(...).decimalPlaces for precision.
In `@packages/sync-server/src/app-gocardless/banks/ing_pl_ingbplpw.js`:
- Around line 32-43: oldestKnownBalance and oldestTransactionAmount are passing
GoCardless string amounts directly into amountToInteger; convert the string
amounts to numbers (use Number(...) with a fallback like 0) before calling
amountToInteger so getCurrency(...).decimalPlaces stays correct. Update the
calls that use oldestTransaction.balanceAfterTransaction.balanceAmount.amount
and oldestTransaction.transactionAmount.amount to wrap them in Number(... || 0)
while keeping the existing getCurrency(...) usage.
In `@packages/sync-server/src/app-gocardless/banks/sandboxfinance_sfin0000.js`:
- Around line 25-39: The reduce currently assumes currentBalance (result of the
earlier find stored in variable currentBalance) is always present and will throw
if undefined; guard against that by checking for undefined before using
currentBalance.balanceAmount (or provide a default zero balance object), e.g.
compute a safe starting value for the reduce by using optional chaining or a
fallback amount derived from
amountToInteger(Number(currentBalance?.balanceAmount?.amount || 0),
getCurrency(currentBalance?.balanceAmount?.currency || '').decimalPlaces) so the
call sites in sortedTransactions.reduce, amountToInteger, and getCurrency are
safe when currentBalance is missing.
In `@packages/sync-server/src/app-gocardless/banks/seb_privat.js`:
- Around line 26-40: The reduce block is passing string amounts into
amountToInteger and can crash when currentBalance is undefined; convert
transactionAmount.amount and currentBalance.balanceAmount.amount via Number(...)
before calling amountToInteger (e.g., wrap trans.transactionAmount.amount and
currentBalance.balanceAmount.amount with Number) and guard against missing
currentBalance by defaulting the starting amount to 0 (or returning 0) when
currentBalance is falsy; update references in this file to use Number(...) and
check currentBalance before accessing .balanceAmount to prevent runtime errors
in the reduce calculation.
In `@packages/sync-server/src/app-gocardless/banks/spk_karlsruhe_karsde66.js`:
- Around line 58-72: The reduce callback in sortedTransactions.reduce subtracts
transaction amounts and initializes total using currentBalance without
converting string amounts to numbers and without guarding currentBalance; wrap
trans.transactionAmount.amount and currentBalance.balanceAmount.amount with
Number(...) before passing to amountToInteger, and add a guard so if
currentBalance is undefined use 0 (e.g. default to 0 for the initializer) —
update usages around sortedTransactions.reduce, amountToInteger,
trans.transactionAmount.amount, currentBalance.balanceAmount.amount, and
getCurrency to reflect these changes.
In `@packages/sync-server/src/app-gocardless/banks/ssk_munchen.js`:
- Around line 50-64: The reducer currently passes string amounts to
amountToInteger (via trans.transactionAmount.amount and
currentBalance.balanceAmount.amount) and doesn't guard currentBalance; wrap both
trans.transactionAmount.amount and currentBalance.balanceAmount.amount with
Number(...) before calling amountToInteger, and add a null/undefined guard for
currentBalance (or default to "0") so sortedTransactions.reduce starts from a
numeric initial balance; update references in the sortedTransactions.reduce
block and where currentBalance is read so getCurrency/currentBalance usage
remains safe.
🧹 Nitpick comments (4)
packages/sync-server/package.json (1)
18-21: Published package ships duplicate build artifacts.After
normalize-build-layoutcopies files frombuild/sync-server/intobuild/bin/,build/src/, andbuild/app.js, the originalbuild/sync-server/tree is never removed. Combined with"files": ["build"], the published package will contain both the nested and flattened layouts — roughly doubling the build artifact size.Similarly,
copy-static-assetsduplicates SQL files into bothbuild/src/sqlandbuild/sync-server/src/sql, which can silently diverge if one path is updated but not the other.Consider adding
rm -rf build/sync-serverat the end ofnormalize-build-layout, and then only copying SQL assets tobuild/src/sql.packages/sync-server/src/app-gocardless/banks/seb_kort_bank_ab.js (1)
1-2: Convert this sync-server module to TypeScript.
This file lives underpackages/and remains JS; the repo guideline calls for TS. Consider a follow-up conversion if it’s not in scope here.As per coding guidelines:
**/{packages,src}/**/*.{js,jsx}: Use TypeScript for all code.packages/sync-server/src/app-simplefin/app-simplefin.js (1)
1-7: Convert this sync-server module to TypeScript.
This file lives underpackages/and remains JS; the repo guideline calls for TS. Consider a follow-up conversion if it’s not in scope here.As per coding guidelines:
**/{packages,src}/**/*.{js,jsx}: Use TypeScript for all code.packages/desktop-client/src/components/mobile/transactions/TransactionEdit.tsx (1)
451-477: Double conversion oftransaction.amount— correct but worth noting.The amount is converted from integer → float (in
serializeTransaction) and then back to integer (line 457) just to pass toAmountInput. The round-trip is mathematically sound with matchingdecimalPlaces, but it's an unnecessary hop compared to passing the original integer directly. Not blocking — just a minor observation.
df3c0fb to
4f81b50
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/desktop-client/src/components/transactions/TransactionsTable.tsx (1)
1616-1676:⚠️ Potential issue | 🟠 MajorDebit/credit cell formatters use
amountToCurrencywithout currency-specific decimal place handling.The debit and credit
InputCellformatters (lines 1624–1627, 1655–1658) callamountToCurrency(...)which lacks adecimalPlacesparameter, causing it to default to 2 decimal places. This contradicts the PR's goal of eliminating the 2-decimal assumption and will reformat user input incorrectly for zero- and three-decimal currencies (e.g.,100→1.00for JPY).The component already has access to
decimalPlacesfromuseFormat()(line 936) and correctly passes it tointegerToCurrencyelsewhere (line 1685). TheamountToCurrencyfunction should either accept adecimalPlacesparameter likeintegerToCurrencydoes, or the formatters should use an alternative that respects currency decimal places.
🤖 Fix all issues with AI agents
In `@packages/loot-core/src/server/accounts/sync.ts`:
- Around line 409-420: The falsy check if (!trans.amount) incorrectly treats a
valid zero amount as missing; change it to a nullish check (trans.amount ==
null) so only null/undefined are replaced from trans.transactionAmount?.amount,
then keep coercion via Number(trans.amount) into normalizedAmount and retain the
NaN guard and the mapping lookup (mappings.get(normalizedAmount <= 0 ? 'payment'
: 'deposit')) unchanged.
- Around line 954-975: The initial-sync balance calculations use
transactions.reduce calling amountToInteger(trans.transactionAmount.amount,
getCurrencyDecimalPlaces(...)) on raw responses where
trans.transactionAmount.amount can be a string; update both reduce usages (the
SimpleFIN branch computing previousBalance and the pluggyai branch computing
previousBalance) to explicitly coerce the amount to a Number (wrap
trans.transactionAmount.amount with Number(...)) before passing to
amountToInteger so behavior matches normalizeBankSyncTransactions.
🧹 Nitpick comments (1)
packages/sync-server/src/app-pluggyai/app-pluggyai.js (1)
17-21:roundToCurrencyDecimalsduplicates logic already available in the shared utility layer.This helper is equivalent to
integerToAmount(amountToInteger(amount, dp), dp). Consider reusing those functions to avoid divergence:Suggested refactor
-function roundToCurrencyDecimals(amount, currencyCode) { - const decimalPlaces = getCurrency(currencyCode || '').decimalPlaces; - const multiplier = Math.pow(10, decimalPlaces); - return Math.round(amount * multiplier) / multiplier; -} +function roundToCurrencyDecimals(amount, currencyCode) { + const decimalPlaces = getCurrency(currencyCode || '').decimalPlaces; + return integerToAmount(amountToInteger(amount, decimalPlaces), decimalPlaces); +}This requires importing
integerToAmountfromloot-core/shared/utilalongsideamountToInteger.
bef38ef to
15468a8
Compare
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (3)
packages/desktop-client/src/components/mobile/transactions/TransactionEdit.tsx (1)
280-300:⚠️ Potential issue | 🔴 CriticalRemove
undefinedas the second argument; theformatterparameter has a default and passingundefinedexplicitly will cause a runtime error.The
integerToCurrencyfunction signature is:export function integerToCurrency( integerAmount: IntegerAmount, formatter = getNumberFormat().formatter, decimalPlaces: number = 2, )While the second parameter has a default value, passing
undefinedexplicitly does not trigger it—the default only applies when the argument is omitted. The function then callsformatter.format(amount)on line 455, which fails at runtime ifformatterisundefined.Either omit the second argument entirely (
integerToCurrency(value, decimalPlaces)) or provide the actual formatter value.packages/desktop-client/src/components/mobile/transactions/FocusableAmountInput.tsx (1)
85-93:⚠️ Potential issue | 🟡 Minor
onTotalAmountUpdatein TransactionEdit.tsx does not applyamountToInteger— conversion happens downstream indeserializeTransaction.The callback receives a decimal amount from
FocusableAmountInputand passes it directly toonUpdateInnerwithout callingamountToInteger. The actual conversion occurs later whenonUpdatecallsdeserializeTransaction(serializedTransaction, null, dateFormat, decimalPlaces), which appliesamountToInteger(amount || 0, decimalPlaces)at that point.This differs from
TrackingBudgetMenuModalandEnvelopeBudgetMenuModal, where_onUpdateBudgetappliesamountToIntegerimmediately within the callback before passing to the parent. While the TransactionEdit approach works because the conversion happens before persistence, the inconsistent pattern across consumers could introduce bugs if the downstream conversion step is ever missed or bypassed.packages/sync-server/src/app-gocardless/banks/berliner_sparkasse_beladebexxx.js (1)
45-52:⚠️ Potential issue | 🟡 MinorStale JSDoc references
SANDBOXFINANCE_SFIN0000instead ofBERLINER_SPARKASSE_BELADEBEXXX.The comment on line 46 mentions "SANDBOXFINANCE_SFIN0000" but this adapter is for
BERLINER_SPARKASSE_BELADEBEXXX. This is a pre-existing copy-paste issue but worth fixing while touching this code.Proposed fix
/** - * For SANDBOXFINANCE_SFIN0000 we don't know what balance was + * For BERLINER_SPARKASSE_BELADEBEXXX we don't know what balance was * after each transaction so we have to calculate it by getting * current balance from the account and subtract all the transactions
🤖 Fix all issues with AI agents
In `@packages/sync-server/src/app-gocardless/banks/abnamro_abnanl2a.js`:
- Around line 51-60: The current branch in the code checks
hasBalanceAfterTransaction on sortedTransactions[0] and then, if the
oldestTransaction (sortedTransactions[sortedTransactions.length - 1]) lacks
balanceAfterTransaction, returns 0; instead remove that early return and let
execution fall through to the interimBooked balance path so partial
balanceAfterTransaction data doesn’t force a zero starting balance. Update the
block around sortedTransactions, hasBalanceAfterTransaction, and
oldestTransaction to skip the return 0 case and allow the later interimBooked
handling (the logic that reads interimBooked on lines ~79-89) to execute when
the oldest transaction has no balanceAfterTransaction.
In `@packages/sync-server/src/app-gocardless/banks/american_express_aesudef1.js`:
- Around line 1-2: This file was converted to JavaScript in isolation but must
remain part of the coordinated sync-server TypeScript migration; revert any
isolated type-only changes and add a clear top-of-file comment (e.g.,
"TODO/MIGRATION: Do not convert in isolation — migrate as part of sync-server
package-wide TS effort per AGENTS.md") so reviewers know this file intentionally
remains JS for now, and ensure existing imports (getCurrency, amountToInteger)
are left unchanged and continue to work in the current JS build until the
package-wide migration is performed.
In `@packages/sync-server/src/app-gocardless/banks/ing_ingddeff.js`:
- Around line 1-2: This file is a JavaScript adapter that must be migrated to
TypeScript: rename the file to .ts, update the module to use TypeScript syntax,
and add appropriate type annotations for the adapter's public API and any
variables that consume getCurrency and amountToInteger; ensure imports remain as
`import { getCurrency }` and `import { amountToInteger }` but annotate their
usages (e.g., currency codes as string, amounts as number, and the adapter's
exported handler return type) so the compiler can validate it, update any
default/exported object to use typed interfaces, and run the typechecker/linter
to fix any remaining type errors.
🧹 Nitpick comments (6)
packages/sync-server/src/app-gocardless/banks/integration-bank.js (1)
88-106: Per-transaction currency lookup would be more robust than using the balance currency for all transactions.
currentBalanceDecimalsis derived from the balance object's currency and then applied to every transaction's amount. If a transaction'stransactionAmount.currencydiffers from the balance currency (e.g., a foreign-currency posting), the wrongdecimalPlaceswould be used for scaling, silently producing an incorrect integer.Consider resolving decimal places per transaction:
♻️ Suggested change
return sortedTransactions.reduce( (total, trans) => { + const txDecimals = getCurrency( + trans.transactionAmount.currency || '', + ).decimalPlaces; return ( total - amountToInteger( Number(trans.transactionAmount.amount || 0), - currentBalanceDecimals, + txDecimals, ) ); },That said, for single-currency accounts this is a non-issue, and GoCardless typically returns amounts in the account currency. Up to you whether this edge case warrants the change.
packages/sync-server/src/app-gocardless/banks/ssk_munchen.js (1)
38-45: Nit: stale JSDoc comment references the wrong bank.The comment says "For SANDBOXFINANCE_SFIN0000" but this is the
SSK_MUNCHENintegration. This is a pre-existing copy-paste artifact — consider updating it while you're here.upcoming-release-notes/6954.md (1)
1-6: Consider timing of release notes for WIP PR.This PR is currently marked as "[WIP]" (Work In Progress). Release notes are typically added when the PR is ready for merge, not during development, since the implementation may still change. Consider adding or updating this file once the PR is finalized.
packages/desktop-client/src/components/mobile/transactions/TransactionEdit.tsx (1)
235-235: Consider destructuring or extractingdecimalPlacesonce at a higher level.
useFormat().currency.decimalPlacesis called independently in four components in this tree (Footer,ChildTransactionEdit,TransactionEditInner,TransactionEditUnconnected). Since they all read the same global currency preference, you could passdecimalPlacesas a prop fromTransactionEditUnconnecteddown through the component tree to avoid redundant hook invocations and make the data flow more explicit. That said, the current approach is idiomatic React and works correctly.Also applies to: 408-408, 587-587, 1325-1325
packages/loot-core/src/shared/util.ts (1)
241-267:appendDecimalsre-parses its own output — fragile round-trip.The function builds a decimal string manually (lines 252–260), then immediately parses it back to a number via
currencyToAmountjust to re-format it withIntl.NumberFormat. This parse→format round-trip relies oncurrencyToAmountcorrectly handling the string that was just constructed, which is fragile if locale separators change or edge-case amounts arise.That said, this appears to be the existing pattern extended to support
decimalPlaces, so it's not a regression. Just worth noting for a future simplification pass.packages/desktop-client/src/components/transactions/TransactionsTable.tsx (1)
1738-1777: Apply tabular number styling for the split error amount.This is a standalone financial value; add
styles.tnum(orFinancialText) for consistent numeric alignment.♻️ Suggested tweak
- <Text style={{ fontWeight: 500 }}> + <Text style={{ fontWeight: 500, ...styles.tnum }}> {integerToCurrency( isDeposit ? error.difference : -error.difference, undefined, decimalPlaces, )} </Text>Based on learnings: Applies to packages/desktop-client/src/**/*.{tsx} : Wrap standalone financial numbers with
FinancialTextor applystyles.tnumdirectly if wrapping is not possible.
15468a8 to
4ed6ca4
Compare
This comment has been minimized.
This comment has been minimized.
|
FYI: the sync-server is currency agnostic and should remain that way. Besides that - it should not import from @coderabbitai please create a ticket - we should not allow |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 47 🏁 Script executed: Length of output: 50
The changes in this PR that added loot-core imports to sync-server (particularly for currency-aware amount conversions) violate this architectural principle and will need to be refactored. ✏️ Learnings added
🧠 Learnings used |
|
/update-vrt @coderabbitai review |
|
🧠 Learnings used✅ Actions performedReview triggered.
|
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
packages/loot-core/src/server/importers/ynab5.ts (1)
1189-1218:⚠️ Potential issue | 🔴 CriticalSet the imported budget's default currency from
data.currency_format.iso_code.The code now stores integer amounts using the correct decimal precision from the YNAB budget, but it never persists
data.currency_format.iso_codeto thedefaultCurrencyCodepreference. After a JPY/VND/KWD import completes, the app will render and edit transactions at the wrong scale becausedefaultCurrencyCoderemains unset (empty). Add a call to set the currency before import completion:await send('preferences/save', { id: 'defaultCurrencyCode', value: data.currency_format?.iso_code ?? '', });Place this in
doImport()after importing budgets or in the "Setting up..." section.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/loot-core/src/server/importers/ynab5.ts` around lines 1189 - 1218, The import flow never persists the YNAB budget currency, so defaultCurrencyCode stays empty; update doImport to save data.currency_format.iso_code into preferences by calling send('preferences/save', { id: 'defaultCurrencyCode', value: data.currency_format?.iso_code ?? '' }) after importBudgets completes (or in the "Setting up..." section) so the app uses the correct default currency for amounts; locate doImport and place the preference save call after importBudgets (using the existing send function and the defaultCurrencyCode preference id).
♻️ Duplicate comments (1)
packages/loot-core/src/server/importers/ynab5.ts (1)
77-90:⚠️ Potential issue | 🟠 MajorFail fast when the YNAB currency metadata can't be resolved.
getCurrency(cf?.iso_code ?? '')returns the default currency entry on a miss, so malformed or newly added YNAB ISO codes still silently fall back to 2 decimals here. That recreates the same wrong-scale persistence path this PR is trying to remove. Please validate the ISO lookup and throw if neitherdecimal_digitsnor a recognizediso_codeis available.Based on learnings: In `packages/loot-core/src/shared/currencies.ts`, using `decimalPlaces: 2` for VND caused a 100x multiplication bug when zero-decimal currencies were treated as 2-decimal values.Suggested fix
function getYnab5DecimalPlaces(data: Budget): number { const cf = data.currency_format; // Prefer API decimal_digits (including 0 for zero-decimal currencies); fall back to ISO code. const decimalPlaces = cf?.decimal_digits; if ( typeof decimalPlaces === 'number' && Number.isInteger(decimalPlaces) && decimalPlaces >= 0 && decimalPlaces <= 10 ) { return decimalPlaces; } - return getCurrency(cf?.iso_code ?? '').decimalPlaces; + if (cf?.iso_code) { + const currency = getCurrency(cf.iso_code); + if (currency.code === cf.iso_code) { + return currency.decimalPlaces; + } + } + throw new Error( + `Unsupported YNAB currency metadata: iso_code=${String(cf?.iso_code)}, decimal_digits=${String(cf?.decimal_digits)}`, + ); }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/loot-core/src/server/importers/ynab5.ts` around lines 77 - 90, The getYnab5DecimalPlaces function currently falls back to getCurrency(cf?.iso_code ?? '').decimalPlaces which silently returns a default and can mis-scale amounts; change getYnab5DecimalPlaces to first check cf?.decimal_digits as now, then if absent/invalid validate that cf?.iso_code is non-empty and that getCurrency(cf.iso_code) returns a known currency (not the default/miss) and throw an error if the ISO lookup fails so we fail-fast on unknown YNAB ISO codes instead of silently using a default decimalPlaces; reference getYnab5DecimalPlaces, cf?.decimal_digits, cf?.iso_code, and getCurrency in the fix.
🧹 Nitpick comments (2)
packages/desktop-client/src/components/transactions/table/utils.test.ts (1)
17-61: Reduce duplicated round-trip tests with a table-driven pattern.The 0/2/3 decimal tests repeat the same structure; using
test.eachwill make future currency precision additions easier and less error-prone.♻️ Suggested refactor
describe('transaction table utils decimal places', () => { - test('serializes and deserializes zero-decimal currencies', () => { - const original = makeTransaction(1000000); - - const serialized = serializeTransaction(original, 0, false); - expect(serialized.credit).toBe('1,000,000'); - expect(serialized.debit).toBe(''); - - const deserialized = deserializeTransaction(serialized, original, 0); - expect(deserialized.amount).toBe(1000000); - }); - - test('serializes and deserializes two-decimal currencies', () => { - const original = makeTransaction(1000000); - - const serialized = serializeTransaction(original, 2, false); - expect(serialized.credit).toBe('10,000.00'); - expect(serialized.debit).toBe(''); - - const deserialized = deserializeTransaction(serialized, original, 2); - expect(deserialized.amount).toBe(1000000); - }); - - test('serializes and deserializes three-decimal currencies', () => { - const original = makeTransaction(1000000); - - const serialized = serializeTransaction(original, 3, false); - expect(serialized.credit).toBe('1,000.000'); - expect(serialized.debit).toBe(''); - - const deserialized = deserializeTransaction(serialized, original, 3); - expect(deserialized.amount).toBe(1000000); - }); + type CreditCase = { + name: string; + decimalPlaces: number; + expectedCredit: string; + }; + + const creditCases: CreditCase[] = [ + { + name: 'serializes and deserializes zero-decimal currencies', + decimalPlaces: 0, + expectedCredit: '1,000,000', + }, + { + name: 'serializes and deserializes two-decimal currencies', + decimalPlaces: 2, + expectedCredit: '10,000.00', + }, + { + name: 'serializes and deserializes three-decimal currencies', + decimalPlaces: 3, + expectedCredit: '1,000.000', + }, + ]; + + test.each(creditCases)('$name', ({ decimalPlaces, expectedCredit }) => { + const original = makeTransaction(1000000); + const serialized = serializeTransaction(original, decimalPlaces, false); + expect(serialized.credit).toBe(expectedCredit); + expect(serialized.debit).toBe(''); + + const deserialized = deserializeTransaction( + serialized, + original, + decimalPlaces, + ); + expect(deserialized.amount).toBe(1000000); + });As per coding guidelines: "Prefer iteration and modularization over code duplication".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/desktop-client/src/components/transactions/table/utils.test.ts` around lines 17 - 61, Replace the three near-identical decimal-precision tests with a table-driven parameterized test using test.each: create a table of cases with columns for decimals (0,2,3), input amount (1000000), and the expected serialized credit string ('1,000,000', '10,000.00', '1,000.000'), then inside the test call makeTransaction, serializeTransaction(decimals), assert serialized.credit and serialized.debit, and round-trip using deserializeTransaction to assert deserialized.amount; keep the negative/debit scenario either as a separate test or add a row with amount -1000000 and expected debit string ('10,000.00') to the same table. Ensure you reference the existing helpers serializeTransaction, deserializeTransaction, and makeTransaction so the refactor only changes the test scaffolding, not the logic.packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx (1)
172-185: MakedecimalPlacesrequired instead of silently defaulting to 2.The prop is already threaded from
CategoryList, so keepingdecimalPlaces?: numberplus?? 2just leaves a quiet path back to the regression this PR is fixing. Prefer a required prop and let TypeScript catch any missed wiring.♻️ Suggested tightening
type CategoryItemProps = { item: CategoryAutocompleteItem; className?: string; style?: CSSProperties; highlighted?: boolean; embedded?: boolean; showBalances?: boolean; - decimalPlaces?: number; + decimalPlaces: number; }; @@ - {integerToCurrency(toBudget || 0, decimalPlaces ?? 2)} + {integerToCurrency(toBudget || 0, decimalPlaces)} @@ - {integerToCurrency(balance || 0, decimalPlaces ?? 2)} + {integerToCurrency(balance || 0, decimalPlaces)}Also applies to: 434-445, 512-525
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx` around lines 172 - 185, The code currently silently defaults decimalPlaces to 2 which hides wiring errors; make decimalPlaces a required prop and remove any fallback defaults (the `?? 2` usage) so TypeScript will surface missing props. Update the prop/type definitions that pass decimalPlaces (e.g., the CategoryList/CategoryAutocomplete props and any interfaces referencing decimalPlaces) to require number, and remove the `?? 2` in call sites such as the renderCategoryItem invocation (and the other occurrences around the file where decimalPlaces is defaulted) so callers must provide decimalPlaces explicitly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@packages/desktop-client/e2e/page-models/settings-page.ts`:
- Around line 103-118: In selectCurrency, guard against empty or whitespace-only
currencyCode before building the locator (which currently produces name: ' -'
and causes long timeouts); trim currencyCode and if it's empty throw a clear
synchronous Error (or return early) so callers get immediate feedback; update
the validation near the start of selectCurrency (before using
dropdownTrigger/currencyMenu/currencyOption) to ensure a non-empty ISO code is
provided.
In
`@packages/desktop-client/src/components/mobile/transactions/FocusableAmountInput.tsx`:
- Around line 112-117: The input currently only flashes and sets
showFractionError when too many decimals are entered (see applyText and
flashFractionError in FocusableAmountInput), so add a visible, accessible error
message element (e.g., a small inline text node tied to an aria-live="assertive"
region) and a piece of state like fractionErrorMessage to hold the message;
update flashFractionError (and any other places that set showFractionError
around lines 149-153 and 177-187) to set fractionErrorMessage to a user-facing
string and showFractionError true, render the message next to the input so it’s
visible on touch, and ensure it is announced by assistive tech via aria-live and
cleared/reset when the value changes or the error resolves.
---
Outside diff comments:
In `@packages/loot-core/src/server/importers/ynab5.ts`:
- Around line 1189-1218: The import flow never persists the YNAB budget
currency, so defaultCurrencyCode stays empty; update doImport to save
data.currency_format.iso_code into preferences by calling
send('preferences/save', { id: 'defaultCurrencyCode', value:
data.currency_format?.iso_code ?? '' }) after importBudgets completes (or in the
"Setting up..." section) so the app uses the correct default currency for
amounts; locate doImport and place the preference save call after importBudgets
(using the existing send function and the defaultCurrencyCode preference id).
---
Duplicate comments:
In `@packages/loot-core/src/server/importers/ynab5.ts`:
- Around line 77-90: The getYnab5DecimalPlaces function currently falls back to
getCurrency(cf?.iso_code ?? '').decimalPlaces which silently returns a default
and can mis-scale amounts; change getYnab5DecimalPlaces to first check
cf?.decimal_digits as now, then if absent/invalid validate that cf?.iso_code is
non-empty and that getCurrency(cf.iso_code) returns a known currency (not the
default/miss) and throw an error if the ISO lookup fails so we fail-fast on
unknown YNAB ISO codes instead of silently using a default decimalPlaces;
reference getYnab5DecimalPlaces, cf?.decimal_digits, cf?.iso_code, and
getCurrency in the fix.
---
Nitpick comments:
In
`@packages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsx`:
- Around line 172-185: The code currently silently defaults decimalPlaces to 2
which hides wiring errors; make decimalPlaces a required prop and remove any
fallback defaults (the `?? 2` usage) so TypeScript will surface missing props.
Update the prop/type definitions that pass decimalPlaces (e.g., the
CategoryList/CategoryAutocomplete props and any interfaces referencing
decimalPlaces) to require number, and remove the `?? 2` in call sites such as
the renderCategoryItem invocation (and the other occurrences around the file
where decimalPlaces is defaulted) so callers must provide decimalPlaces
explicitly.
In `@packages/desktop-client/src/components/transactions/table/utils.test.ts`:
- Around line 17-61: Replace the three near-identical decimal-precision tests
with a table-driven parameterized test using test.each: create a table of cases
with columns for decimals (0,2,3), input amount (1000000), and the expected
serialized credit string ('1,000,000', '10,000.00', '1,000.000'), then inside
the test call makeTransaction, serializeTransaction(decimals), assert
serialized.credit and serialized.debit, and round-trip using
deserializeTransaction to assert deserialized.amount; keep the negative/debit
scenario either as a separate test or add a row with amount -1000000 and
expected debit string ('10,000.00') to the same table. Ensure you reference the
existing helpers serializeTransaction, deserializeTransaction, and
makeTransaction so the refactor only changes the test scaffolding, not the
logic.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 856a3c64-b280-4fe9-ad86-bae2332878fd
📒 Files selected for processing (52)
packages/desktop-client/e2e/accounts.test.tspackages/desktop-client/e2e/budget.test.tspackages/desktop-client/e2e/currency-precision.tspackages/desktop-client/e2e/page-models/settings-page.tspackages/desktop-client/e2e/transactions.test.tspackages/desktop-client/src/accounts/mutations.tspackages/desktop-client/src/components/accounts/Account.tsxpackages/desktop-client/src/components/accounts/BalanceHistoryGraph.tsxpackages/desktop-client/src/components/autocomplete/CategoryAutocomplete.tsxpackages/desktop-client/src/components/budget/BalanceWithCarryover.tsxpackages/desktop-client/src/components/budget/envelope/CoverMenu.tsxpackages/desktop-client/src/components/budget/util.tspackages/desktop-client/src/components/mobile/transactions/FocusableAmountInput.tsxpackages/desktop-client/src/components/mobile/transactions/TransactionEdit.tsxpackages/desktop-client/src/components/mobile/transactions/TransactionList.tsxpackages/desktop-client/src/components/mobile/transactions/TransactionListItem.tsxpackages/desktop-client/src/components/modals/CloseAccountModal.tsxpackages/desktop-client/src/components/modals/CreateLocalAccountModal.tsxpackages/desktop-client/src/components/modals/EditFieldModal.tsxpackages/desktop-client/src/components/modals/EnvelopeBudgetMenuModal.tsxpackages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.tsxpackages/desktop-client/src/components/modals/TrackingBudgetMenuModal.tsxpackages/desktop-client/src/components/settings/Currency.tsxpackages/desktop-client/src/components/transactions/TransactionsTable.test.tsxpackages/desktop-client/src/components/transactions/TransactionsTable.tsxpackages/desktop-client/src/components/transactions/table/utils.test.tspackages/desktop-client/src/components/transactions/table/utils.tspackages/desktop-client/src/hooks/useFormat.tspackages/desktop-client/src/hooks/useFormulaExecution.tspackages/desktop-client/src/hooks/useTransactionsSearch.tspackages/desktop-client/src/queries/index.tspackages/loot-core/src/server/accounts/app.tspackages/loot-core/src/server/accounts/sync.tspackages/loot-core/src/server/api.tspackages/loot-core/src/server/budget/actions.tspackages/loot-core/src/server/budget/category-template-context.test.tspackages/loot-core/src/server/budget/category-template-context.tspackages/loot-core/src/server/budget/schedule-template.tspackages/loot-core/src/server/importers/ynab4.tspackages/loot-core/src/server/importers/ynab5.tspackages/loot-core/src/server/rules/action.tspackages/loot-core/src/server/rules/customFunctions.tspackages/loot-core/src/server/rules/index.test.tspackages/loot-core/src/server/transactions/export/export-to-csv.tspackages/loot-core/src/server/transactions/import/parse-file.test.tspackages/loot-core/src/server/transactions/transaction-rules.tspackages/loot-core/src/shared/currencies.tspackages/loot-core/src/shared/util.test.tspackages/loot-core/src/shared/util.tspackages/loot-core/src/types/models/bank-sync.tsupcoming-release-notes/6902.mdupcoming-release-notes/6954.md
✅ Files skipped from review due to trivial changes (13)
- packages/desktop-client/src/components/settings/Currency.tsx
- upcoming-release-notes/6902.md
- packages/desktop-client/e2e/budget.test.ts
- upcoming-release-notes/6954.md
- packages/desktop-client/src/components/modals/CloseAccountModal.tsx
- packages/loot-core/src/server/budget/schedule-template.ts
- packages/desktop-client/src/components/modals/TrackingBudgetMenuModal.tsx
- packages/loot-core/src/shared/currencies.ts
- packages/desktop-client/src/components/mobile/transactions/TransactionList.tsx
- packages/loot-core/src/types/models/bank-sync.ts
- packages/desktop-client/e2e/transactions.test.ts
- packages/desktop-client/src/components/mobile/transactions/TransactionEdit.tsx
- packages/desktop-client/src/components/budget/BalanceWithCarryover.tsx
🚧 Files skipped from review as they are similar to previous changes (24)
- packages/loot-core/src/server/rules/customFunctions.ts
- packages/desktop-client/src/accounts/mutations.ts
- packages/desktop-client/src/components/accounts/BalanceHistoryGraph.tsx
- packages/desktop-client/src/hooks/useTransactionsSearch.ts
- packages/loot-core/src/server/rules/index.test.ts
- packages/loot-core/src/server/transactions/import/parse-file.test.ts
- packages/loot-core/src/server/importers/ynab4.ts
- packages/loot-core/src/server/accounts/app.ts
- packages/loot-core/src/server/budget/category-template-context.ts
- packages/desktop-client/src/queries/index.ts
- packages/desktop-client/src/components/modals/CreateLocalAccountModal.tsx
- packages/desktop-client/src/components/accounts/Account.tsx
- packages/desktop-client/src/components/modals/ImportTransactionsModal/ImportTransactionsModal.tsx
- packages/desktop-client/e2e/accounts.test.ts
- packages/desktop-client/src/components/transactions/table/utils.ts
- packages/loot-core/src/server/transactions/transaction-rules.ts
- packages/loot-core/src/server/budget/actions.ts
- packages/desktop-client/src/components/transactions/TransactionsTable.test.tsx
- packages/loot-core/src/shared/util.test.ts
- packages/desktop-client/e2e/currency-precision.ts
- packages/desktop-client/src/hooks/useFormat.ts
- packages/desktop-client/src/components/transactions/TransactionsTable.tsx
- packages/loot-core/src/server/transactions/export/export-to-csv.ts
- packages/desktop-client/src/components/modals/EditFieldModal.tsx
|
/update-vrt |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/desktop-client/e2e/page-models/settings-page.ts (1)
45-77: Consider adding an explicit return type annotation.The private helper correctly centralizes the expand/collapse logic and visibility handling. For consistency with the public methods and improved maintainability, consider adding the explicit return type.
- private async getExperimentalFeatureCheckbox(featureName: string) { + private async getExperimentalFeatureCheckbox(featureName: string): Promise<Locator> {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/desktop-client/e2e/page-models/settings-page.ts` around lines 45 - 77, The method getExperimentalFeatureCheckbox lacks an explicit return type; update its signature to include the proper Promise return type (e.g., add ": Promise<Locator>") so callers and maintainers see the expected Playwright Locator result, and if Locator isn't already imported in this file add the import from Playwright (for example from '@playwright/test').
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/desktop-client/e2e/page-models/settings-page.ts`:
- Around line 45-77: The method getExperimentalFeatureCheckbox lacks an explicit
return type; update its signature to include the proper Promise return type
(e.g., add ": Promise<Locator>") so callers and maintainers see the expected
Playwright Locator result, and if Locator isn't already imported in this file
add the import from Playwright (for example from '@playwright/test').
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 6069e086-1516-47c0-bd64-f33f2c2d9848
⛔ Files ignored due to path filters (296)
packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-7-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-8-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-9-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-the-accounts-page-and-asserts-on-balances-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-import-csv-file-twice-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-import-csv-file-twice-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-import-csv-file-twice-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-imports-transactions-from-a-CSV-file-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-imports-transactions-from-a-CSV-file-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Import-Transactions-imports-transactions-from-a-CSV-file-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-creates-a-new-account-and-views-the-initial-balance-transaction-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-creates-a-new-account-and-views-the-initial-balance-transaction-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-creates-a-new-account-and-views-the-initial-balance-transaction-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-page-handles-empty-state-gracefully-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-page-handles-empty-state-gracefully-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-page-handles-empty-state-gracefully-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-searches-for-accounts-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-searches-for-accounts-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.mobile.test.ts-snapshots/Mobile-Bank-Sync-searches-for-accounts-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.test.ts-snapshots/Bank-Sync-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.test.ts-snapshots/Bank-Sync-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/bank-sync.test.ts-snapshots/Bank-Sync-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-applies-budget-template-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-applies-budget-template-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-applies-budget-template-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--14404-in-the-page-header-opens-the-month-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--321fd-ed-amount-opens-the-budget-summary-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--4bb70-ed-amount-opens-the-budget-summary-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--589a6-the-page-header-shows-the-next-month-s-budget-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6ab37-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--6dbdb-page-header-shows-the-previous-month-s-budget-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--7bd8f-the-page-header-shows-the-next-month-s-budget-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--884ac-the-page-header-shows-the-next-month-s-budget-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a79-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--94a85-ed-amount-opens-the-budget-summary-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--96ebb-page-header-shows-the-previous-month-s-budget-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--9e6aa-in-the-page-header-opens-the-budget-page-menu-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bbde3-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--bed18-in-the-page-header-opens-the-month-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--c18ad-l-redirects-to-the-category-transactions-page-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--ceb3a-in-the-page-header-opens-the-month-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--d270d-in-the-page-header-opens-the-budget-page-menu-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--d7184-page-header-shows-the-previous-month-s-budget-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--e995e-l-redirects-to-the-category-transactions-page-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--fdd57-in-the-page-header-opens-the-budget-page-menu-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking--ff568-l-redirects-to-the-category-transactions-page-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-checks-that-clicking-the-category-name-opens-the-category-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-copies-last-month-s-budget-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-copies-last-month-s-budget-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-copies-last-month-s-budget-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-12-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-12-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-12-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-3-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-3-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-3-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-6-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-6-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-set-budget-to-6-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Envelope-updates-the-budgeted-amount-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-applies-budget-template-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-applies-budget-template-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-applies-budget-template-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--0ba04-nt-amount-opens-the-budget-summary-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--0dfe7-page-header-shows-the-previous-month-s-budget-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--11290-l-redirects-to-the-category-transactions-page-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--1ce6d-nt-amount-opens-the-budget-summary-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--42062-in-the-page-header-opens-the-month-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--49fb6-in-the-page-header-opens-the-month-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--57d88-l-redirects-to-the-category-transactions-page-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5d90c-l-redirects-to-the-category-transactions-page-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--5f098-roup-name-opens-the-category-group-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--7c353-the-page-header-shows-the-next-month-s-budget-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--929be-roup-name-opens-the-category-group-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--a3783-in-the-page-header-opens-the-budget-page-menu-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--a8b5e-in-the-page-header-opens-the-budget-page-menu-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--b1562-in-the-page-header-opens-the-month-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--cfb69-page-header-shows-the-previous-month-s-budget-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--d5af6-the-page-header-shows-the-next-month-s-budget-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--dc927-roup-name-opens-the-category-group-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f2198-the-page-header-shows-the-next-month-s-budget-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f224f-nt-amount-opens-the-budget-summary-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f7fa3-page-header-shows-the-previous-month-s-budget-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking--f8a19-in-the-page-header-opens-the-budget-page-menu-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-balance-cell-opens-the-balance-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-budgeted-cell-opens-the-budget-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-checks-that-clicking-the-category-name-opens-the-category-menu-modal-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-copies-last-month-s-budget-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-copies-last-month-s-budget-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-copies-last-month-s-budget-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-loads-the-budget-page-with-budgeted-amounts-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-12-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-12-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-12-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-3-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-3-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-3-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-6-month-average-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-6-month-average-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-set-budget-to-6-month-average-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.mobile.test.ts-snapshots/Mobile-Budget-Tracking-updates-the-budgeted-amount-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-renders-the-summary-information-available-funds-overspent-budgeted-and-for-next-month-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-transfer-funds-to-another-category-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-transfer-funds-to-another-category-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-transfer-funds-to-another-category-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-search-works-correctly-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-search-works-correctly-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-search-works-correctly-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/command-bar.test.ts-snapshots/Command-bar-Check-the-command-bar-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-help-menu-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-7-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-8-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/help-menu.test.ts-snapshots/Help-menu-Check-the-keyboard-shortcuts-modal-visuals-9-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/onboarding.test.ts-snapshots/Onboarding-checks-the-page-visuals-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-payee-edit-page-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-payee-edit-page-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-payee-edit-page-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-rule-creation-form-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-rule-creation-form-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-clicking-on-a-payee-opens-rule-creation-form-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-filters-out-unrelated-payees-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-filters-out-unrelated-payees-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-filters-out-unrelated-payees-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-page-handles-empty-state-gracefully-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-page-handles-empty-state-gracefully-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-page-handles-empty-state-gracefully-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.mobile.test.ts-snapshots/Mobile-Payees-search-functionality-works-correctly-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/payees.test.ts-snapshots/Payees-checks-the-payees-page-visuals-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Area-Graph-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Area-Graph-and-checks-the-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Area-Graph-and-checks-the-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Bar-Graph-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Bar-Graph-and-checks-the-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Bar-Graph-and-checks-the-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Data-Table-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Data-Table-and-checks-the-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Data-Table-and-checks-the-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Donut-Graph-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Donut-Graph-and-checks-the-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Donut-Graph-and-checks-the-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Line-Graph-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Line-Graph-and-checks-the-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Line-Graph-and-checks-the-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-labels-button-shows-the-labels-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-labels-button-shows-the-labels-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-labels-button-shows-the-labels-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-legend-button-shows-the-legend-side-bar-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-legend-button-shows-the-legend-side-bar-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-legend-button-shows-the-legend-side-bar-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-summary-button-shows-the-summary-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-cash-flow-graph-and-checks-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-cash-flow-graph-and-checks-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-cash-flow-graph-and-checks-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-and-cash-flow-reports-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-and-cash-flow-reports-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-and-cash-flow-reports-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-graph-and-checks-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-graph-and-checks-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-loads-net-worth-graph-and-checks-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-add-button-opens-rule-creation-form-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-add-button-opens-rule-creation-form-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-add-button-opens-rule-creation-form-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-on-a-rule-opens-edit-form-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-on-a-rule-opens-edit-form-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-clicking-on-a-rule-opens-edit-form-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-displays-the-rules-page-with-proper-header-and-search-bar-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-displays-the-rules-page-with-proper-header-and-search-bar-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-displays-the-rules-page-with-proper-header-and-search-bar-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-page-handles-empty-state-gracefully-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-page-handles-empty-state-gracefully-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-page-handles-empty-state-gracefully-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-search-functionality-filters-rules-correctly-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-search-functionality-filters-rules-correctly-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.mobile.test.ts-snapshots/Mobile-Rules-search-functionality-filters-rules-correctly-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/rules.test.ts-snapshots/Rules-creates-a-split-transaction-rule-and-makes-sure-it-is-applied-when-creating-a-transaction-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-clicking-on-a-schedule-opens-edit-form-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-clicking-on-a-schedule-opens-edit-form-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-clicking-on-a-schedule-opens-edit-form-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-displays-schedule-details-correctly-in-list-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-displays-schedule-details-correctly-in-list-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-displays-schedule-details-correctly-in-list-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-page-handles-empty-state-gracefully-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-page-handles-empty-state-gracefully-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-page-handles-empty-state-gracefully-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-searches-and-filters-schedules-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-searches-and-filters-schedules-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-searches-and-filters-schedules-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-searches-and-filters-schedules-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-searches-and-filters-schedules-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.mobile.test.ts-snapshots/Mobile-Schedules-searches-and-filters-schedules-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-checks-the-page-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-checks-the-page-visuals-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-checks-the-page-visuals-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-full-list-of-schedules-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-full-list-of-schedules-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-full-list-of-schedules-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-10-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-11-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-12-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-7-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/schedules.test.ts-snapshots/Schedules-creates-a-new-schedule-posts-the-transaction-and-later-completes-it-8-chromium-linux.pngis excluded by!**/*.png
📒 Files selected for processing (4)
packages/desktop-client/e2e/accounts.test.tspackages/desktop-client/e2e/budget.test.tspackages/desktop-client/e2e/currency-precision.tspackages/desktop-client/e2e/page-models/settings-page.ts
🚧 Files skipped from review as they are similar to previous changes (2)
- packages/desktop-client/e2e/budget.test.ts
- packages/desktop-client/e2e/accounts.test.ts
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
/update-vrt |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In @.github/workflows/vrt-update-generate.yml:
- Around line 108-125: The current loop applies the ±2KB filter to new or
deleted PNGs and then runs git restore --source=HEAD --staged --worktree --
"$f", which fails for files that don't exist in HEAD; modify the logic in the
png_paths loop (variables old, new, net, abs_net and the git restore invocation)
to only perform the byte-delta check and call git restore for files that exist
in both HEAD and the index (e.g., test git cat-file -e HEAD:"$f" && git cat-file
-e ":$f" or require old -gt 0 and new -gt 0 before computing net and executing
git restore) so new or deleted PNGs are skipped by the noise filter.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5d9284e4-7412-4925-8732-95f4f5aa0753
⛔ Files ignored due to path filters (45)
packages/desktop-client/e2e/accounts.mobile.test.ts-snapshots/Mobile-Accounts-opens-individual-account-page-and-checks-that-filtering-is-working-7-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-Default-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-Default-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-Default-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-JPY-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-JPY-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-JPY-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-KWD-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-KWD-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-KWD-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-USD-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-USD-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-close-account-shows-correct-balance-for-USD-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-Default-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-Default-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-Default-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-JPY-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-JPY-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-JPY-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-KWD-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-KWD-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-KWD-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-USD-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-USD-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-Currency-Precision-starting-balance-displayed-correctly-for-USD-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-with-transfer-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-with-transfer-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-with-transfer-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-with-transfer-4-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-with-transfer-5-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/accounts.test.ts-snapshots/Accounts-closes-an-account-with-transfer-6-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-Default-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-Default-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-Default-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-JPY-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-JPY-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-JPY-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-KWD-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-KWD-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-KWD-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-USD-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-USD-2-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/budget.test.ts-snapshots/Budget-Currency-Precision-budget-page-displays-for-USD-3-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Switches-to-Donut-Graph-and-checks-the-visuals-1-chromium-linux.pngis excluded by!**/*.pngpackages/desktop-client/e2e/reports.test.ts-snapshots/Reports-custom-reports-Validates-that-show-legend-button-shows-the-legend-side-bar-1-chromium-linux.pngis excluded by!**/*.png
📒 Files selected for processing (2)
.github/workflows/vrt-update-generate.ymlpackages/desktop-client/e2e/page-models/settings-page.ts
This comment has been minimized.
This comment has been minimized.
|
/update-vrt |
This comment has been minimized.
This comment has been minimized.
|
❌ Failed to apply VRT updates: Patch conflicts with current branch state Please check the workflow logs for details. |
This comment has been minimized.
This comment has been minimized.
|
/update-vrt |
|
Hey @StephenBrown2 , just wanting to let you know it's highly unlikely that any of the maintainers are going to feel comfortable reviewing any pr this big. There's just too much in this PR. To move anything forward for this you'd need to close this and open smaller PRs. |
This comment has been minimized.
This comment has been minimized.
|
Hey @MikesGlitch thanks for the update. Are you looking at the VRT changes primarily? I'm currently trying to work out a method to only retain used screenshots, and delete orphaned ones, since I renamed a VRT test and therefore some pngs should be renamed as well. Sorry for the churn on this PR while I work on reducing that blast effect. If it's for the wide code changes, the sprawl is probably not easily containable, since adding decimalPlaces to every formatting function will require every call to be updated. How would you recommend the changes be divided up for easier review? |
This comment has been minimized.
This comment has been minimized.
|
/update-vrt |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
…d UI Propagate decimalPlaces through shared amount utilities (including KWD), desktop and mobile UI, transactions, budgeting, search, importers, rules, and server account APIs. Add shared e2e currency-precision helpers and refactor related tests. Record attribution in upcoming release notes.
|
/update-vrt |
This comment has been minimized.
This comment has been minimized.
|
/update-vrt |
|
VRT tests ❌ failed. View the test report. To update the VRT screenshots, comment |
Sorry for yet another PR, but I noticed that Vietnamese Dong got added with the wrong decimal places, due to the longstanding issue with not handling other than 2 decimal places.
I originally included sync-server adapter work here, but that was decided to be out of scope, so this PR now focuses on desktop-client + loot-core currency precision only.
Summary
This PR fixes the "everything assumes 2 decimal places" problem.
Amounts now use each currency's
decimalPlacesacross account creation, transaction editing/table flows, search/formula paths, and budget-related UI code. This avoids the x10/x100/x1000 inflation issues when using zero-decimal or three-decimal currencies.I also corrected VND metadata to use
decimalPlaces: 0.IMPORTANT: If this is merged and released at the same time as #6902, there will be no db migration needed. If after, a DB migration MAY be needed to fix the 100x issue on existing values.
Tests added/updated
packages/desktop-client/src/components/transactions/table/utils.test.ts)integerToCurrencyWithDecimalappendDecimals(packages/loot-core/src/shared/util.test.ts)JPY,VND):packages/desktop-client/e2e/accounts.test.ts)Issues addressed
This PR is aimed at the non-2-decimal currency requests:
Test plan
yarn testyarn typecheckJPY/VND)AI assistance
This change was made with the help of GPT-5.3 Codex.
Bundle Stats
View detailed bundle stats
desktop-client
Total
Changeset
src/components/mobile/transactions/FocusableAmountInput.tsxsrc/components/transactions/table/utils.tshome/runner/work/actual/actual/packages/loot-core/src/shared/util.tssrc/queries/index.tssrc/hooks/useTransactionsSearch.tshome/runner/work/actual/actual/packages/loot-core/src/shared/currencies.tssrc/components/budget/envelope/CoverMenu.tsxsrc/components/modals/EditFieldModal.tsxsrc/components/modals/TrackingBudgetMenuModal.tsxsrc/components/modals/EnvelopeBudgetMenuModal.tsxsrc/components/modals/CreateLocalAccountModal.tsxsrc/components/autocomplete/CategoryAutocomplete.tsxpackage.jsonsrc/components/mobile/transactions/TransactionListItem.tsxsrc/components/settings/Currency.tsxsrc/components/budget/BalanceWithCarryover.tsxsrc/components/mobile/transactions/TransactionEdit.tsxsrc/components/accounts/BalanceHistoryGraph.tsxsrc/components/modals/CloseAccountModal.tsxsrc/hooks/useFormulaExecution.tssrc/components/accounts/Account.tsxsrc/components/transactions/TransactionsTable.tsxhome/runner/work/actual/actual/packages/loot-core/src/server/rules/customFunctions.tssrc/components/mobile/transactions/TransactionList.tsxsrc/components/modals/ImportTransactionsModal/ImportTransactionsModal.tsxsrc/components/budget/util.tssrc/accounts/mutations.tsView detailed bundle breakdown
Added
No assets were added
Removed
No assets were removed
Bigger
Smaller
No assets were smaller
Unchanged
loot-core
Total
Changeset
home/runner/work/actual/actual/packages/loot-core/src/server/transactions/export/export-to-csv.tshome/runner/work/actual/actual/packages/loot-core/src/server/importers/ynab5.tshome/runner/work/actual/actual/packages/loot-core/src/shared/currencies.tshome/runner/work/actual/actual/packages/loot-core/src/shared/util.tshome/runner/work/actual/actual/packages/loot-core/src/server/transactions/transaction-rules.tshome/runner/work/actual/actual/packages/loot-core/src/server/importers/ynab4.tshome/runner/work/actual/actual/packages/loot-core/src/server/accounts/app.tshome/runner/work/actual/actual/packages/loot-core/src/server/api.tshome/runner/work/actual/actual/packages/loot-core/src/server/budget/schedule-template.tshome/runner/work/actual/actual/packages/loot-core/src/server/rules/customFunctions.tshome/runner/work/actual/actual/packages/loot-core/src/server/budget/category-template-context.tshome/runner/work/actual/actual/packages/loot-core/src/server/rules/action.tshome/runner/work/actual/actual/packages/loot-core/src/server/accounts/sync.tshome/runner/work/actual/actual/packages/loot-core/src/server/budget/actions.tsView detailed bundle breakdown
Added
Removed
Bigger
No assets were bigger
Smaller
No assets were smaller
Unchanged
No assets were unchanged
api
Total
Changeset
home/runner/work/actual/actual/packages/loot-core/src/server/transactions/export/export-to-csv.tshome/runner/work/actual/actual/packages/loot-core/src/server/importers/ynab5.tshome/runner/work/actual/actual/packages/loot-core/src/shared/currencies.tshome/runner/work/actual/actual/packages/loot-core/src/shared/util.tshome/runner/work/actual/actual/packages/loot-core/src/server/transactions/transaction-rules.tshome/runner/work/actual/actual/packages/loot-core/src/server/importers/ynab4.tshome/runner/work/actual/actual/packages/loot-core/src/server/accounts/app.tshome/runner/work/actual/actual/packages/loot-core/src/server/api.tshome/runner/work/actual/actual/packages/loot-core/src/server/budget/schedule-template.tshome/runner/work/actual/actual/packages/loot-core/src/server/rules/customFunctions.tshome/runner/work/actual/actual/packages/loot-core/src/server/budget/category-template-context.tshome/runner/work/actual/actual/packages/loot-core/src/server/rules/action.tshome/runner/work/actual/actual/packages/loot-core/src/server/accounts/sync.tshome/runner/work/actual/actual/packages/loot-core/src/server/budget/actions.tsView detailed bundle breakdown
Added
No assets were added
Removed
No assets were removed
Bigger
Smaller
No assets were smaller
Unchanged
cli
Total
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