(medium) estimator.py/estimate_quality SB-anchor: границы диапазона из RAW comp_ppm2 без repair_coef рассинхронизированы с центром #1518

Closed
opened 2026-06-15 05:59:08 +00:00 by bot-backend · 1 comment
Collaborator

Severity: medium · Категория: report · Файл: tradein-mvp/backend/app/services/estimator.py:2216-2236

estimator.py:2218-2236. В same-building anchor пути point считается с поправкой на ремонт (new_ppm2 = est_ppm2 * repair_coef, point = int(new_ppm2 * area), стр.2218-2219), а spread_low/spread_high берутся из СЫРЫХ comp_min_ppm2/comp_max_ppm2 БЕЗ repair_coef (стр.2233-2234). После range_low=min(new_range_low, spread_low, point) и range_high=max(new_range_high, spread_high, point) (2235-2236) центр и границы оказываются в разных масштабах. Импакт: для needs_repair (coef=0.94) клиент видит медиану на 6% ниже, а верх диапазона — как у квартир без поправки → диапазон несимметрично широк вверх и не согласован с headline; для excellent (1.10) — наоборот. Headline остаётся внутри диапазона (min/max с point), цена корректна — это дефект ширины/согласованности advisory-диапазона, не точечной оценки. Фикс: применять repair_coef к spread_low/spread_high (int(anchor['comp_min_ppm2'] * area * repair_coef)) либо к границам как к центру.

Почему баг: new_ppm2 = est_ppm2 * repair_coef (строка 2218) и point = int(new_ppm2 * area) (2219), но spread_low = int(anchor['comp_min_ppm2'] * area) и spread_high = int(anchor['comp_max_ppm2'] * area) (2233-2234) — comp_min/max_ppm2 это сырые asking ppm² комплов БЕЗ repair_coef. Затем range_low=min(new_range_low, spread_low, point), range_high=max(new_range_high, spread_high, point). repair_coef применён к центру, но НЕ к границам спреда → масштабная несостыковка центра и границ диапазона.

Как чинить: Домножать spread_low/spread_high на repair_coef так же, как point: spread_low = int(anchor['comp_min_ppm2'] * repair_coef * area), spread_high = int(anchor['comp_max_ppm2'] * repair_coef * area).


deep-audit «армия ботов 2» · verify+harden, confidence 0.82 · unit U124

**Severity:** medium · **Категория:** report · **Файл:** `tradein-mvp/backend/app/services/estimator.py:2216-2236` estimator.py:2218-2236. В same-building anchor пути point считается с поправкой на ремонт (new_ppm2 = est_ppm2 * repair_coef, point = int(new_ppm2 * area), стр.2218-2219), а spread_low/spread_high берутся из СЫРЫХ comp_min_ppm2/comp_max_ppm2 БЕЗ repair_coef (стр.2233-2234). После range_low=min(new_range_low, spread_low, point) и range_high=max(new_range_high, spread_high, point) (2235-2236) центр и границы оказываются в разных масштабах. Импакт: для needs_repair (coef=0.94) клиент видит медиану на 6% ниже, а верх диапазона — как у квартир без поправки → диапазон несимметрично широк вверх и не согласован с headline; для excellent (1.10) — наоборот. Headline остаётся внутри диапазона (min/max с point), цена корректна — это дефект ширины/согласованности advisory-диапазона, не точечной оценки. Фикс: применять repair_coef к spread_low/spread_high (int(anchor['comp_min_ppm2'] * area * repair_coef)) либо к границам как к центру. **Почему баг:** new_ppm2 = est_ppm2 * repair_coef (строка 2218) и point = int(new_ppm2 * area) (2219), но spread_low = int(anchor['comp_min_ppm2'] * area) и spread_high = int(anchor['comp_max_ppm2'] * area) (2233-2234) — comp_min/max_ppm2 это сырые asking ppm² комплов БЕЗ repair_coef. Затем range_low=min(new_range_low, spread_low, point), range_high=max(new_range_high, spread_high, point). repair_coef применён к центру, но НЕ к границам спреда → масштабная несостыковка центра и границ диапазона. **Как чинить:** Домножать spread_low/spread_high на repair_coef так же, как point: spread_low = int(anchor['comp_min_ppm2'] * repair_coef * area), spread_high = int(anchor['comp_max_ppm2'] * repair_coef * area). --- <sub>deep-audit «армия ботов 2» · verify+harden, confidence 0.82 · unit U124</sub>
bot-backend added the
week ревью 1
label 2026-06-15 05:59:08 +00:00
bot-backend added the
scope/backend
label 2026-06-15 11:02:17 +00:00
Owner

🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)

Текущее состояние кода: tradein-mvp/backend/app/services/estimator.py:2218-2236 (same-building anchor путь). Строки совпадают с телом issue в точности.

Корень: new_ppm2 = est_ppm2 * repair_coef (2218), point = int(new_ppm2 * area) (2219) — repair-поправка применена к центру. Но spread_low = int(anchor["comp_min_ppm2"] * payload.area_m2) (2233) и spread_high = int(anchor["comp_max_ppm2"] * payload.area_m2) (2234) берут СЫРЫЕ asking-ppm² комплов без repair_coef. Затем range_low = min(new_range_low, spread_low, point) (2235) и range_high = max(new_range_high, spread_high, point) (2236) сводят центр (repair-scaled) и границы (raw) в разных масштабах. Комментарий 2228-2231 объясняет почему spread в asking-space (комплы — активные объявления), но это ортогонально repair-coef: при needs_repair (0.94) point смещён вниз, а spread_high остаётся как у неотремонтированных → диапазон несимметрично широк вверх и рассогласован с headline. Headline остаётся внутри (min/max включают point), точечная цена корректна — дефект ширины/согласованности advisory-диапазона.

Что править:

  • Домножить spread на repair_coef симметрично с point: spread_low = int(anchor["comp_min_ppm2"] * repair_coef * payload.area_m2), spread_high = int(anchor["comp_max_ppm2"] * repair_coef * payload.area_m2). Тогда границы и центр в одном масштабе.
  • Альтернатива (если spread намеренно держат в чистом asking-пространстве по комментарию 2228-2231) — задокументировать, что границы остаются raw-asking сознательно, и тогда headline/point тоже не должен нести repair-поправку при сравнении с ними. Но первый вариант ближе к семантике issue.

Что посмотреть:

  • Код: estimator.py:2213-2236 (floor_ppm2 на 2213 тоже из raw comp_min_ppm2 — при правке проверить, нужна ли ему та же поправка), _repair_coefficient (estimator.py:179). Тест: добавить кейс needs_repair (0.94) + excellent (1.10) в same-building anchor, assert range_low ≤ point ≤ range_high и согласованность масштаба границ с point.
  • Vault: релевантных заметок не найдено (запросы estimator same-building anchor repair_coef spread — пусто).
**🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)** **Текущее состояние кода:** `tradein-mvp/backend/app/services/estimator.py:2218-2236` (same-building anchor путь). Строки совпадают с телом issue в точности. **Корень:** `new_ppm2 = est_ppm2 * repair_coef` (2218), `point = int(new_ppm2 * area)` (2219) — repair-поправка применена к центру. Но `spread_low = int(anchor["comp_min_ppm2"] * payload.area_m2)` (2233) и `spread_high = int(anchor["comp_max_ppm2"] * payload.area_m2)` (2234) берут СЫРЫЕ asking-ppm² комплов без `repair_coef`. Затем `range_low = min(new_range_low, spread_low, point)` (2235) и `range_high = max(new_range_high, spread_high, point)` (2236) сводят центр (repair-scaled) и границы (raw) в разных масштабах. Комментарий 2228-2231 объясняет почему spread в asking-space (комплы — активные объявления), но это ортогонально repair-coef: при needs_repair (0.94) `point` смещён вниз, а `spread_high` остаётся как у неотремонтированных → диапазон несимметрично широк вверх и рассогласован с headline. Headline остаётся внутри (min/max включают `point`), точечная цена корректна — дефект ширины/согласованности advisory-диапазона. **Что править:** - Домножить spread на `repair_coef` симметрично с point: `spread_low = int(anchor["comp_min_ppm2"] * repair_coef * payload.area_m2)`, `spread_high = int(anchor["comp_max_ppm2"] * repair_coef * payload.area_m2)`. Тогда границы и центр в одном масштабе. - Альтернатива (если spread намеренно держат в чистом asking-пространстве по комментарию 2228-2231) — задокументировать, что границы остаются raw-asking сознательно, и тогда headline/point тоже не должен нести repair-поправку при сравнении с ними. Но первый вариант ближе к семантике issue. **Что посмотреть:** - Код: `estimator.py:2213-2236` (floor_ppm2 на 2213 тоже из raw `comp_min_ppm2` — при правке проверить, нужна ли ему та же поправка), `_repair_coefficient` (estimator.py:179). Тест: добавить кейс needs_repair (0.94) + excellent (1.10) в same-building anchor, assert `range_low ≤ point ≤ range_high` и согласованность масштаба границ с point. - Vault: релевантных заметок не найдено (запросы `estimator same-building anchor repair_coef spread` — пусто).
Sign in to join this conversation.
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#1518
No description provided.