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. |
||
|---|---|---|
| .. | ||
| __init__.py | ||
| admin_cadastre.py | ||
| admin_etl.py | ||
| admin_jobs.py | ||
| admin_leads.py | ||
| admin_scrape.py | ||
| admin_weight_profiles.py | ||
| analytics.py | ||
| concepts.py | ||
| custom_pois.py | ||
| landing.py | ||
| me.py | ||
| parcels.py | ||
| photos.py | ||
| pilot.py | ||
| ping.py | ||
| trade_in.py | ||
| users.py | ||