fix(tradein): sync n_analogs to anchor count when anchor drives headline (#695) #739
2 changed files with 28 additions and 0 deletions
|
|
@ -1818,6 +1818,14 @@ async def estimate_quality(
|
||||||
f"Оценка построена по {anchor['n']} аналогам из {tier_label}"
|
f"Оценка построена по {anchor['n']} аналогам из {tier_label}"
|
||||||
f"{' (топ-уровень в доме)' if anchor['used_uplift'] else ''}."
|
f"{' (топ-уровень в доме)' if anchor['used_uplift'] else ''}."
|
||||||
) + repair_note
|
) + repair_note
|
||||||
|
# #695 (QA fixup): когда якорь подменяет headline и список аналогов на
|
||||||
|
# комплы дома, n_analogs ДОЛЖЕН считаться по anchor-популяции, а не по
|
||||||
|
# радиусу (listings_clean). Иначе все UI-счётчики («Аналогов N»,
|
||||||
|
# «Показано N из M», «по N аналогам», гистограмма) расходятся: radius=4 vs
|
||||||
|
# anchor=5 → артефакт «Показано 5 из 4». anchor['n'] = число комплов, на
|
||||||
|
# которых построена оценка (= показываемый analogs, capped 10). Для anchor-
|
||||||
|
# пути это и есть «полное число найденных» по контракту n_analogs (#698).
|
||||||
|
n_analogs = anchor["n"]
|
||||||
|
|
||||||
# ── #651: IMV / Yandex BLEND (killer accuracy fix) — SECONDARY, Tier D only ──
|
# ── #651: IMV / Yandex BLEND (killer accuracy fix) — SECONDARY, Tier D only ──
|
||||||
# Радиусная медиана системно занижает премиум/видовые квартиры (нет class/
|
# Радиусная медиана системно занижает премиум/видовые квартиры (нет class/
|
||||||
|
|
|
||||||
|
|
@ -947,3 +947,23 @@ def test_explanation_radius_path_keeps_base_text() -> None:
|
||||||
exp = est.confidence_explanation or ""
|
exp = est.confidence_explanation or ""
|
||||||
assert "Найдено" in exp
|
assert "Найдено" in exp
|
||||||
assert "Оценка построена по" not in exp # якорной фразы нет на чистом радиусе
|
assert "Оценка построена по" not in exp # якорной фразы нет на чистом радиусе
|
||||||
|
|
||||||
|
|
||||||
|
# ── #695 QA fixup: n_analogs синхронизируется с anchor-популяцией (radius≠anchor) ──
|
||||||
|
|
||||||
|
|
||||||
|
def test_anchor_n_analogs_syncs_to_anchor_count() -> None:
|
||||||
|
"""#695 QA-fail: anchor подменяет headline+список на комплы дома, но n_analogs
|
||||||
|
раньше оставался радиусным → «Показано 5 из 4». radius=5 ≠ anchor=3 намеренно;
|
||||||
|
n_analogs ДОЛЖЕН стать 3 (anchor), согласуясь с «по 3 аналогам» в explanation."""
|
||||||
|
radius = [_make_listing(price_per_m2=200_000.0) for _ in range(5)]
|
||||||
|
est = _run_estimate(anchor_comps=_SB_COMPS_PREMIUM, anchor_tier="A", radius_analogs=radius)
|
||||||
|
assert est.n_analogs == 3 # = len(_SB_COMPS_PREMIUM), НЕ 5 (радиус)
|
||||||
|
assert "по 3 аналогам" in (est.confidence_explanation or "")
|
||||||
|
|
||||||
|
|
||||||
|
def test_radius_path_n_analogs_unchanged() -> None:
|
||||||
|
"""#695 контроль: без якоря n_analogs = радиусный счёт (поведение не меняется)."""
|
||||||
|
radius = [_make_listing(price_per_m2=200_000.0) for _ in range(5)]
|
||||||
|
est = _run_estimate(anchor_comps=[], anchor_tier=None, radius_analogs=radius)
|
||||||
|
assert est.n_analogs == 5
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue