whatif: live data refresh, inflation-adjusted spending, legend fix
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
Three follow-ups to the actualbudget integration: **Always-fresh autofill.** Drop the one-shot `*AutoFilled` boolean gates; replace with `nwUserEdited` / `spendingUserEdited` flags. Until the user types into either field, every refetch (mount, window focus) updates the form value. Once they edit, we leave it alone. A small ↻ button next to each anchor input flips the edited flag back off so the user can re-snap to live data on demand. React Query configured with staleTime=0 + refetchOnMount='always' + refetchOnWindowFocus=true so the cache never serves stale numbers. NW provenance shows the snapshot date. **Inflation-adjusted spending.** Backend now revalues each trailing month's nominal pence forward to today's £ using monthly compounding of `inflation_pct` (default 0.03 ≈ UK CPI 2024-26). Headline `total_gbp` is the real-£ figure — matches the simulator's real-GBP convention. Response also includes `nominal_total_gbp` and `inflation_pct` for transparency. New /spending/annual?inflation_pct= override param. 10/10 actualbudget tests pass. **FanChart legend.** The bottom-anchored legend was overlapping the x-axis label. Moved to top: 8 with itemGap=18 + type=scroll for narrow viewports; bumped grid top→48 / bottom→56 + xAxis nameGap→28 so nothing collides. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
3bfa46ad4f
commit
e12e8f9290
8 changed files with 263 additions and 68 deletions
|
|
@ -41,6 +41,15 @@ async def annual_spending(
|
|||
f"from the headline total. Defaults to: {','.join(DEFAULT_EXCLUDE_GROUPS)}."
|
||||
),
|
||||
),
|
||||
inflation_pct: float = Query(
|
||||
default=0.03, ge=0.0, le=0.30,
|
||||
description=(
|
||||
"Annual inflation rate used to revalue past months' spending "
|
||||
"into today's £. The simulator runs in real GBP, so the headline "
|
||||
"`total_gbp` is the inflation-adjusted (real) figure. Default ≈ "
|
||||
"UK CPI 2024-26."
|
||||
),
|
||||
),
|
||||
) -> AnnualSpending:
|
||||
excluded = (
|
||||
[g.strip() for g in exclude.split(",") if g.strip()]
|
||||
|
|
@ -48,9 +57,10 @@ async def annual_spending(
|
|||
else list(DEFAULT_EXCLUDE_GROUPS)
|
||||
)
|
||||
try:
|
||||
spends, total_gbp = await fetch_trailing_spending(
|
||||
spends, nominal_gbp, real_gbp = await fetch_trailing_spending(
|
||||
months=months,
|
||||
exclude_groups=frozenset(excluded),
|
||||
annual_inflation_pct=inflation_pct,
|
||||
)
|
||||
except Exception as e:
|
||||
log.exception("actualbudget unreachable")
|
||||
|
|
@ -93,8 +103,10 @@ async def annual_spending(
|
|||
window_start=monthly[0].month,
|
||||
window_end=monthly[-1].month,
|
||||
excluded_groups=excluded,
|
||||
total_gbp=total_gbp,
|
||||
total_gbp=real_gbp,
|
||||
nominal_total_gbp=nominal_gbp,
|
||||
raw_total_gbp=raw_total_gbp,
|
||||
inflation_pct=Decimal(str(inflation_pct)),
|
||||
by_group_total_gbp=by_group_gbp,
|
||||
monthly=monthly,
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue