Analytics gains a 90-day USD/CRC buy/sell chart from the existing
history endpoint (wishlist: rate history). Pensiones gains a
Calculadora de Aporte: fund + target amount + target age → required
monthly contribution via the annuity future-value formula, using the
fund's live balance and configured rate (wishlist: contribution
calculator).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Every dict-returning route the SPA consumes now declares a response
model (auth, bulk, sync-status, notifications). api-types.gen.ts is
generated from app.openapi() via openapi-typescript, and the 22 hand-
written read interfaces in api.ts are now aliases onto the generated
schemas — backend schema drift becomes a typecheck failure, and CI
regenerates the file and fails the deploy if it's stale. The aliasing
immediately caught two real drifts: RecurringItemType was missing
SAVINGS, and raw_charges (untyped JSON column) is now explicitly
shaped at the boundary.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per-fund contribution and annual-rate assumptions are now editable in a
Supuestos dialog on Pensiones and persisted server-side in UserSettings
so projections survive devices and reloads; saldo inicial keeps coming
from the latest snapshot (UX-12). The recurring-item dialog confirms
before discarding unsaved edits, with the dirty baseline computed from
the same values the populate effect sets (UX-06). Empty transaction
lists now offer an inline add button (UX-14).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Transactions gain a checkbox column with select-all; a bulk bar offers
assign-category, defer/restore and delete (confirmed) via the new bulk
endpoint, with toasts and invalidation. The paste-import modal now
lists each skipped duplicate with the matched existing row and offers
'Importar duplicados de todos modos' — re-importing ONLY the skipped
lines so first-pass rows can't double-import (UX-20). Two real fixes
found en route: the mobile list ignored undo-pending deletes and used
en-US dates; the desktop date column also lost its en-US stray. Note:
UX-11 (no mobile layout) was a false positive — a card layout already
existed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The n8n flows fail invisibly from the app's perspective (review UX-17,
the top trust gap). /api/v1/sync-status derives last-received + cadence
thresholds for BAC, salary, municipal, pensions and exchange rate from
existing data — no n8n integration needed. New Sincronización page
shows per-source freshness and a hint to check n8n; the sidebar item
gets an amber dot when any source is stale. Verified live against the
dev DB (correctly flags its stale BAC data at 43 days).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
QueryClientProvider (30s staleTime, 1 retry) + Sonner Toaster at the
root. api.ts gains AbortSignal support and a default 30s timeout
(FE-24); query cancellation kills the stale-response races (FE-01,
FE-03). useBudget is now queries + mutations with targeted ['budget']
invalidation and success/error toasts on every mutation (ARCH-13,
UX-01); month navigation keeps the previous month visible while
fetching. Budget's transaction list is a cancellable query with
placeholder data; deferred-toggle gets feedback (UX-05); both panels
render a shared ErrorState with retry instead of failing silently.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Removes Dashboard / Transactions / Transfers pages, the section
configuration UI, the legacy useSettings hook, and the standalone
PrivacyContext/ThemeContext modules. Privacy/theme contexts now live
under src/contexts/ and the API helper / push-notifications module
move under src/lib/.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>