Persist each successful POST /analyze into analysis_runs (migration 127): best-effort SAVEPOINT-wrapped INSERT in a thin analysis_runs repository, then explicit db.commit() (get_db has no commit-on-success; SAVEPOINT RELEASE alone does not persist — without the commit the row rolls back on request teardown, a silent no-op caught in code review). A persist failure never breaks the response or poisons the session. Result serialized via jsonable_encoder→ json.dumps (handles embedded Pydantic models/dates); confidence/status normalized to satisfy the 127 CHECK constraints (unknown→NULL/'complete'). Populate by-bbox last_analysis_date from v_analysis_runs_latest via a single batch query (no N+1), replacing the #307 placeholder. The read is best-effort wrapped too — a view-missing deploy window or future drift must not 500 the map (falls back to last_analysis_date=None). Additive only — analyze response shape unchanged. Tests: by-bbox suite patches latest_run_dates (mock-db returns same rows for any query) + new test asserts ISO last_analysis_date from a latest run. Analyze mock-suite unaffected (graceful side_effect overflow + best-effort persist absorb the extra INSERT). Incidental: ruff-format fixed one pre-existing f-string spacing (line ~2391) the format hook flags on touch. Closes #994. Refs #961.
5 lines
335 B
Python
5 lines
335 B
Python
"""analysis_runs — durable persist/read слой анализ-ранов Site Finder (#994, ТЗ §22).
|
||
|
||
Тонкий data-access поверх таблицы `analysis_runs` + view `v_analysis_runs_latest`
|
||
(миграция 127, #993). Endpoint'ы (parcels.py) держим тонкими — вся SQL-логика здесь.
|
||
"""
|