diff --git a/codebase-review/PROGRESS.md b/codebase-review/PROGRESS.md index 341dc98..197a0c6 100644 --- a/codebase-review/PROGRESS.md +++ b/codebase-review/PROGRESS.md @@ -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