fix(usage): coalesce account-switch refreshes and harden malformed config values

* fix(usage): coalesce account-switch refreshes and harden malformed config values

selectAccount queued Qt.callLater(refreshNow) after writing selectedAccounts,
whose commandSource binding already fired scheduleUsageRefresh in
single-provider mode. Qt.callLater coalesces only identical function
references, so every account switch started one usage command and retired it
immediately in favour of a second. Both paths now use scheduleUsageRefresh,
which coalesces through the scheduled flag and still refreshes in
multi-provider mode where the command does not change.

Two untrusted-input guards relied on Number() coercion at their boundaries:
ProviderDescriptor.normalize accepted schemaVersion values that merely coerce
to 1 (true, "1", [1]), and QuotaThresholds.numericPercent turned whitespace,
arrays, and Infinity into a 1% warning threshold or a clamped maximum - the
exact corruption its comment says it prevents. Both now accept only the
documented shapes, matching the descriptor contract's unknown-schema rule.

Documentation impact: CHANGELOG Unreleased gained Fixed entries. Docs already
describe both contracts correctly; no README, usage guide, or TODO change is
needed, and no user-facing strings changed.

* test(usage): verify account-switch refresh coalescing

Exercise production account-selection functions and command bindings in the Qt event loop. The parent commit triggers two refreshes for single-provider selections; the fixed paths trigger one for cached and uncached accounts in both modes. Narrow threshold validation claims to unexpected helper inputs. Development and changelog agree; config, translations, CLI contracts, and TODO scope are unchanged.
76d6e828a7Simone committed on 9/9/2026, 12:16:41 PM· committed by GitHubparent9764a78
9 files changedLine totals unavailable