- Extract parseUtc (was copy-pasted in 4 files) and settingEnabled (3 copies,
one named settingsBool) into client/lib/utils.ts as the single source.
- Replace all local copies with the shared import.
- Add tracker_show_safe_to_spend to the tracker's local settings defaults so it
matches SettingsPage's list (behavior unchanged; aligns the two sources).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
parseJsonSafe/upload-body → a structured ResponseBody type (typed error
envelope + index sig) instead of any, no cast churn; declineRecommendation
→ Recommendation; snowballPlans endpoint typed so the hook drops its (d: any).
Annotated the Spending settings-load catch as best-effort (Finding #8) —
cosmetic options fall back to defaults, no mount-time nag. Client 0 any's.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Promoted SpendingPage's local shapes into @/types (SpendingCategoryEntry,
SpendingSummary, SpendingTransaction(s), SpendingIncome*, SpendingRule,
CategoryGroup, CopyBudgetsResponse) and wired the /spending/* + category-
groups endpoints with get<T>/post<T>. Hooks return typed data; 6 casts
removed; 2 orphaned type aliases dropped. typecheck/lint/build clean.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
YNAB-style spending view typed: CatEntry (category_id number|'other'|
null) with a RealCatEntry narrowing for the budget-indexed paths,
SpendingSummary/SpendingTx/IncomeTx/SpendingRule/CategoryGroup local
types, budgets as Record<string,number|null>, React Query
setQueryData<T> for optimistic budget/categorize edits, cast-at-boundary
for api.* results. Dropped a pre-existing dead 'total' state.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-04 23:29:39 -05:00
Renamed from client/pages/SpendingPage.jsx (Browse further)