gendesign/tradein-mvp/backend/app
Light1YT 99736b6e32
All checks were successful
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
fix(estimator): ghost-anchor — confidence='low' when radius analogs empty (#1871)
#1871 P1 (Ghost-anchor) trust defect: when the same-building anchor
replaces the headline estimate, the code sets confidence = anchor["confidence"]
and overwrites n_analogs = anchor["n"] (>0). With ZERO radius analogs
(listings_clean == []) this yielded confidence='high'/'medium' on an
estimate built only on same-building comps (sometimes a single
yandex_valuation, e.g. median 38.4M) with no comparable nearby listings.

The defensive guard _enforce_zero_analog_low only fires on n_analogs == 0,
but n_analogs was already overwritten to anchor["n"] (>0) — so it never
caught this path. UI rendered "Высокая · 0 объектов" = fabricated confidence.

Fix: inline guard inside the `if anchor is not None:` block, right after
n_analogs = anchor["n"]. When listings_clean is empty and confidence != 'low',
downgrade to 'low', log a warning, and append an honest caveat to explanation.
Sits before _enforce_zero_analog_low and before the result is finalized, so the
downgraded confidence + caveat propagate to the response.

Test: tests/test_estimator_ghost_anchor_radius_empty_1871.py exercises the
full estimate path (via the test_same_building_anchor harness) with a
tight-spread anchor (n=5, would be 'high') and empty radius → asserts
confidence='low' + caveat present; plus a control that a non-empty radius is
not downgraded.
2026-06-26 21:01:34 +05:00
..
api feat(scrapers): live pacing-регулятор (GET/PUT /scraper/pacing) + data-quality coverage endpoint 2026-06-20 12:47:03 +03:00
core feat(tradein-imv): route IMV backfill через BrowserFetcher.fetch_json за dormant-флагом (#915 Stage 3) (#1916) 2026-06-26 09:54:28 +00:00
observability feat(tradein): enrich GlitchTip SDK init — integrations + PII scrub (#396) (#643) 2026-05-29 09:23:17 +00:00
schemas fix(estimator): data-age guards — sber staleness + IMV thin-market (#audit-5) 2026-06-20 15:03:19 +03:00
services fix(estimator): ghost-anchor — confidence='low' when radius analogs empty (#1871) 2026-06-26 21:01:34 +05:00
tasks feat(tradein): бэкфилл координат листингов из ekb_geoportal_buildings (street+house match) 2026-06-20 17:08:46 +03:00
__init__.py feat: add tradein-mvp subproject (Trade-In Estimator под /trade-in) 2026-05-21 00:25:39 +03:00
main.py feat(tradein): systemd timer scheduler — trigger script + units + SCHEDULER_ENABLE flag (#581) 2026-05-31 16:53:38 +00:00
scheduler_main.py feat(tradein): отдельный scraper-контейнер — scheduler вне API-процесса (#1182) 2026-06-12 10:50:50 +03:00