Record Phase 2 completion in PROGRESS.md
All checks were successful
Deploy to VPS / test (push) Successful in 1m40s
Deploy to VPS / deploy (push) Successful in 2m26s

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Carlos Escalante
2026-06-10 15:31:42 -06:00
parent 440da3e394
commit 396c492f27

View File

@@ -59,7 +59,44 @@ Completed 2026-06-09.
---
## Phase 2 — Backend Correctness & Robustness ⏳ NOT STARTED
## Phase 2 — Backend Correctness & Robustness ✅ DONE
Completed 2026-06-10.
| Plan item | Status | Commit |
|---|---|---|
| 2.1 Money → Decimal/NUMERIC (29 columns, BE-02) | ✅ | `74886fb` |
| 2.2 Upload hardening: 10 MB cap, %PDF magic, to_thread (SEC-06, BE-14) | ✅ | (uploads) |
| 2.3 FK delete rules, grouped queries (10→3), N+1 fixes, tiebreakers | ✅ | `3cdd7d9` |
| 2.4 Error visibility: per-source rate logging, freshness, clear agent errors | ✅ | `82f10a5` |
| 2.5 Agent cleanup: real multipliers, year bounds, offsets, read-only policy | ✅ | `82f10a5` |
| 2.6 Consistency: enums, keyword status codes, SimpleCookie, import hygiene | ✅ | `440da3e` |
**Key decisions:**
- **Decimal strategy:** `Money = Annotated[Decimal, PlainSerializer(float, when_used="json")]`
— storage is exact `NUMERIC(15,2)` (rates 15,6) while JSON keeps emitting plain
numbers, so the frontend contract is unchanged (pinned by
`test_models_serialization.py`). Services coerce to float at their computation
boundaries. Migration `7f567c8bafdb` verified on dev: per-row values and table
sums byte-identical across the type change.
- **FK rules** (`7884505b16b3`): transactions/recurring items `SET NULL` on category
delete — this also fixes the 500 that `DELETE /categories` raised for in-use
categories; water readings `CASCADE`. Verified with a rolled-back probe on dev.
- **Agent net worth** no longer guesses (hardcoded 600 CRC / 1.08 EUR removed): it
converts via `get_crc_multipliers` and reports unconvertible accounts explicitly.
- **Read-only tool policy** documented in `agent/tools.py` (SEC-09): ingested email
text is a prompt-injection surface; any future write tool needs UI confirmation.
**Review findings closed as overstated/false during implementation:**
- BE-09 (temp-file leak): parsers already use context-managed temp files.
- BE-10 (per-file commits): the pension batch already commits atomically.
- ARCH-08 (swallowed cancellation): `CancelledError` is a `BaseException` since
Python 3.8 — `except Exception` never caught it.
- ARCH-03 (filter precedence): `if cycle / elif dates` is already explicit.
- BE-22 (upsert race): accepted as-is — single writer (daily n8n cron), batch-
scoped commit; ON CONFLICT complexity not warranted.
Tests: 55 → **69** (new: model serialization, agent tools, upload validation).
## Phase 3 — Frontend Data Layer & Feedback ⏳ NOT STARTED