Back MAF's opt-in AG-UI snapshot persistence with a DB store so the
conversation survives page reloads and restarts:
- ChatThreadSnapshot: one upserted row per (scope, thread_id), JSONB
messages/state/interrupt (migration 794baf50635b)
- PostgresSnapshotStore implements the AGUIThreadSnapshotStore protocol.
It opens its own sessions (MAF saves during SSE streaming, after the
request middleware has closed the ContextVar session) and sanitizes on
save: camelCase toolCalls/toolCallId (the @ag-ui/client Zod schema
strips snake_case, which would lose cards on replay), drop BFF ctx-*
context messages, dedupe MAF's re-recorded multi-run turns, and drop
orphaned tool results
- Endpoint mount gains snapshot_store + a constant scope resolver
(single-user app; auth already enforced by agent_auth_and_session)
- DELETE /api/v1/chat/thread resets the conversation
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
BAC zero-interest financing: an anchor purchase splits into N monthly
cuota transactions (truncate-to-0.10 rule, last cuota absorbs rounding;
one cuota per 18th-cut billing cycle on the 19th). Pinned against real
Financiamientos data.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- FK rules via migration 7884505b16b3 (verified on dev with a rolled-
back probe): transactions/recurring items SET NULL on category delete
(this also fixes the 500 that DELETE /categories raised for in-use
categories), water readings CASCADE with their receipt. Models declare
ondelete to stay in sync. (ARCH-09, BE-11)
- compute_actuals_by_source: 3 grouped queries replace 10 single-
aggregate round-trips; behavior pinned by the existing cycle suite.
(BE-21)
- compute_cc_by_category prefetches category names (ARCH-15); agent
pension latest-per-fund resolved in SQL (BE-04); municipal water
consumption batched into one grouped query (BE-05).
- Deterministic pagination: date DESC, id DESC on all transaction
listings. (ARCH-12)
- New agent-tool tests (session binding, JSON-safe output, batched
queries): 64 tests green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Models use Money = Annotated[Decimal, PlainSerializer(float)] so storage
is exact NUMERIC(15,2) (rates 15,6) while JSON keeps emitting plain
numbers — the frontend contract is unchanged, pinned by
test_models_serialization.py. Service layers coerce to float at their
boundaries (projection math, rate multipliers, agent tool output, the
savings constants become Decimal) so no naive Decimal/float mixing can
raise. Migration 7f567c8bafdb applied to dev: per-row values and the
table sum byte-identical before/after; endpoints verified live on the
new schema. 59/59 tests green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The baseline (c3da001a0eb3) was autogenerated against an empty Postgres
and schema-diffed against the live dev schema until column-identical
(two model fixes fell out: deferred_to_next_cycle now declares its
server_default, usersettings.data is JSONB on Postgres to match the
live type). Startup replaces init_db/run_migrations with
run_alembic_upgrade(): pre-Alembic databases that already match the
baseline are adopted via stamp; fresh databases build from the
migration. The section is serialized with a pg advisory lock because
prod uvicorn runs 2 workers, each executing the lifespan. Verified:
adoption + idempotent re-run on the dev DB, fresh 13-table build on an
empty DB, full container boot, 55/55 tests. (ARCH-02, BE-19)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
All 29 call sites now use app.timeutil.utcnow(), which returns naive
UTC via the non-deprecated API. Semantics are unchanged on purpose:
every datetime column is TIMESTAMP WITHOUT TIME ZONE, so going aware
here would poison naive/aware comparisons. The TIMESTAMPTZ migration
(Phase 2) now has a single place to change. (BE-01)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Ahorro was already deducted from gross salary so displaying it in
budget projections was misleading. This removes the Ahorro card,
summary line, Proyecciones column, and Ahorro Anual card from the UI,
and strips all savings fields from budget API responses.
Adds SALARY TransactionType so salary deposits can be distinguished
from generic DEPOSITO transfers. When a SALARY transaction arrives,
the system auto-increments MEMP and MPAT savings account balances
(+200K CRC each) once per month via an idempotent accrual log.
New CRUD endpoints at /api/v1/savings-accrual/ allow manual correction
of the accrual history. Feb+Mar 2026 are seeded as historical baseline.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Adds deferred_to_next_cycle flag to transactions for billing cycle
bleed-over handling. Overhauls budget projection engine and refreshes
Budget page with improved monthly detail and transaction columns.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Existing account rows reference these values. Enum must stay compatible
with data in production. Only the frontend and seed data were cleaned up.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- New BalanceOverride table for manual balance adjustments per month
- Cumulative balance computation with cross-year carryover
- Three new columns: Acum. Anterior, Neto Mes, Balance Acum.
- Inline editing on Balance Acum. cell (pencil icon for overrides)
- Year navigation clamped to 2026–2030, fresh start at March 2026
- PUT/DELETE /budget/balance-override/{year}/{month} endpoints
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend: parse BAC pension statement PDFs (VOL, ROP, FCL) via
pdftotext, store snapshots with duplicate detection, reject
credit card statements. Endpoints: POST /upload, GET /snapshots,
GET /fund-summary.
Frontend: wire up drag-and-drop upload, load real balances and
rendimientos from API, show upload results with error/duplicate
feedback.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
New TransactionType.DEPOSITO for salary deposits from n8n/Gmail flow.
New /salarios endpoint with summary. New top-level Salarios page with
DataTable and summary cards. Push notifications link to /salarios for
deposits.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Budget: recurring items CRUD, yearly/monthly projections with no-double-count
logic, and full UI (overview, monthly detail, recurring items manager).
Push notifications: Web Push via VAPID keys, triggered on transaction creation
from n8n. Includes service worker handlers, frontend subscription flow, and
a test button on the Dashboard (temporary).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend now stores user settings (dashboard config) in a JSONB column and
exposes CRUD via /settings/. Exchange rate service gains multiple fallback
providers (ExchangeRate-API, currency-api, FloatRates) so USD/CRC rates
stay available when BCCR is down.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Expand Account model with account_type (pension, savings, liability, crypto), new banks/currencies (BTC, XMR, FCL, ROP, VOL, MEMP, MPAT, MORTGAGE), and next_payment field
- Add exchange rate endpoint (BCCR integration), analytics endpoint, paste-import for transactions, and API token management
- Add PWA manifest, service worker, and app icons
- Redesign dashboard, transactions, transfers, and login pages with theme support
- Add billing cycle selector, confirm dialog, and paste import modal components
- One-time DB reset in deploy workflow for schema migration
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend: FastAPI + PostgreSQL with models for accounts, transactions,
and categories. Auto-categorization from merchant patterns, token auth,
CRUD endpoints, and seed data for 16 categories and 4 bank accounts.
Frontend: Login, Dashboard (account balances + recent charges),
Transactions (full CRUD table with search/filter), Cash & Transfers
view. Dark theme with emerald/cyan accents, responsive layout.
Infrastructure: Updated docker-compose for backend + db services,
nginx proxy config for API routing, deploy workflow with secrets.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>