(medium) trade_in_pdf: страница «Сделки» рисует выдуманные дни экспозиции (4–118) для rosreestr ДКП-сделок #1366

Closed
opened 2026-06-14 18:09:15 +00:00 by bot-backend · 1 comment
Collaborator

Описание

На странице «Сделки» _days_on_market_range(estimate.actual_deals) передаётся в _price_range_bar с show_days=True. actual_deals — это rosreestr ДКП (зарегистрированные сделки), у которых нет exposure/days_on_market (поле None), поэтому _days_on_market_range возвращает hardcoded fallback (4, 118). Бар сделок печатает '4 дней / 118 дней' как реальные сроки экспозиции закрытых транзакций — выдуманное число в клиентском отчёте под заголовком 'Диапазон цен по фактическим сделкам'. Cover-страница намеренно избегает этого (передаёт только listings-аналоги в days range / show_days по умолчанию False).

Корень

Конфляция sold-deal данных (без срока экспозиции) с days-рендерингом + fallback (4,118). Импорт rosreestr (import-rosreestr.sh) не пишет days_on_market → в проде все строки с NULL.

Evidence

trade_in_pdf.py:830-838:

days_min, days_max = _days_on_market_range(estimate.actual_deals)
range_bar = _price_range_bar(deals_low, deals_high, sub_label="Рынок",
    days_min=days_min, days_max=days_max, show_days=True)
# _days_on_market_range → (4, 118) fallback когда у всех deals days_on_market=None

Suggested fix

На странице «Сделки» вызывать _price_range_bar с show_days=False (у sold-сделок нет периода экспозиции), либо показывать дни только если хотя бы одна сделка реально несёт non-None days_on_market, вместо fallback на 4–118 placeholder из listings.

Обоснование severity

medium: клиентский data-integrity дефект (выдуманная метрика в отчёте по оценке недвижимости), но не влияет на расчёт цены (actual_deals информационны). confidence 0.97.


week ревью 1 · multi-agent аудит 2026-06-14 · severity=medium · category=data-integrity

Затронутые файлы:

  • /Users/anton/Птица/gendesign/tradein-mvp/backend/app/services/exporters/trade_in_pdf.py
## Описание На странице «Сделки» `_days_on_market_range(estimate.actual_deals)` передаётся в `_price_range_bar` с `show_days=True`. `actual_deals` — это rosreestr ДКП (зарегистрированные сделки), у которых нет exposure/days_on_market (поле None), поэтому `_days_on_market_range` возвращает hardcoded fallback `(4, 118)`. Бар сделок печатает '4 дней / 118 дней' как реальные сроки экспозиции закрытых транзакций — выдуманное число в клиентском отчёте под заголовком 'Диапазон цен по фактическим сделкам'. Cover-страница намеренно избегает этого (передаёт только listings-аналоги в days range / show_days по умолчанию False). ## Корень Конфляция sold-deal данных (без срока экспозиции) с days-рендерингом + fallback `(4,118)`. Импорт rosreestr (`import-rosreestr.sh`) не пишет `days_on_market` → в проде все строки с NULL. ## Evidence `trade_in_pdf.py:830-838`: ```python days_min, days_max = _days_on_market_range(estimate.actual_deals) range_bar = _price_range_bar(deals_low, deals_high, sub_label="Рынок", days_min=days_min, days_max=days_max, show_days=True) # _days_on_market_range → (4, 118) fallback когда у всех deals days_on_market=None ``` ## Suggested fix На странице «Сделки» вызывать `_price_range_bar` с `show_days=False` (у sold-сделок нет периода экспозиции), либо показывать дни только если хотя бы одна сделка реально несёт non-None `days_on_market`, вместо fallback на 4–118 placeholder из listings. ## Обоснование severity medium: клиентский data-integrity дефект (выдуманная метрика в отчёте по оценке недвижимости), но не влияет на расчёт цены (actual_deals информационны). confidence 0.97. --- _week ревью 1 · multi-agent аудит 2026-06-14 · severity=**medium** · category=`data-integrity`_ Затронутые файлы: - `/Users/anton/Птица/gendesign/tradein-mvp/backend/app/services/exporters/trade_in_pdf.py`
bot-backend added the
week ревью 1
label 2026-06-14 18:09:15 +00:00
bot-backend added the
scope/backend
label 2026-06-15 11:01:53 +00:00
Owner

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

Текущее состояние кода: tradein-mvp/backend/app/services/exporters/trade_in_pdf.py:830-838 (страница «Сделки») и fallback в _days_on_market_range на :606-611.

Корень: На странице «Сделки» вызывается days_min, days_max = _days_on_market_range(estimate.actual_deals) (830) и сразу _price_range_bar(deals_low, deals_high, sub_label="Рынок", days_min=days_min, days_max=days_max, show_days=True) (831-837). _days_on_market_range (606-611): берёт lot.days_on_market только у непустых, и если список пуст — return 4, 118 (610). У actual_deals (rosreestr ДКП) days_on_market = None во всех строках, поэтому печатается хардкод-плейсхолдер 4 дней / 118 дней под заголовком «Диапазон цен по фактическим сделкам» (884) как реальные сроки экспозиции закрытых сделок. Контраст: cover-страница использует _days_on_market_range(estimate.analogs) (668) — listings, у которых поле реально заполнено. То есть дефект именно в конфляции sold-deal (без экспозиции) с days-рендерингом.

Что править:

  • На странице «Сделки» (831-838) передавать show_days=False — у зарегистрированных ДКП нет периода экспозиции.
  • Либо в _price_range_bar / на call-site показывать дни только если хотя бы одна сделка несёт non-None days_on_market (а не отдавать fallback 4–118 из листинговой эвристики). Текущая защита if show_days and days_min is not None and days_max is not None (trade_in_pdf.py:288) не спасает, т.к. fallback всегда возвращает int.

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

  • Код: trade_in_pdf.py:830-838 (deals page), :606-611 (_days_on_market_range fallback), :267-288 (_price_range_bar, ветка show_days), :668-675 (cover, корректное использование на analogs). Тест: PDF-рендер с actual_deals, у которых days_on_market=None → бар «Сделки» не должен печатать «4 дней / 118 дней».
  • Vault: релевантных заметок не найдено (запрос trade_in_pdf days_on_market fallback exposure сделки — пусто).
**🔍 week ревью 1 — верификация (ПОДТВЕРЖДЕНО)** **Текущее состояние кода:** `tradein-mvp/backend/app/services/exporters/trade_in_pdf.py:830-838` (страница «Сделки») и fallback в `_days_on_market_range` на `:606-611`. **Корень:** На странице «Сделки» вызывается `days_min, days_max = _days_on_market_range(estimate.actual_deals)` (830) и сразу `_price_range_bar(deals_low, deals_high, sub_label="Рынок", days_min=days_min, days_max=days_max, show_days=True)` (831-837). `_days_on_market_range` (606-611): берёт `lot.days_on_market` только у непустых, и если список пуст — `return 4, 118` (610). У `actual_deals` (rosreestr ДКП) `days_on_market` = None во всех строках, поэтому печатается хардкод-плейсхолдер `4 дней / 118 дней` под заголовком «Диапазон цен по фактическим сделкам» (884) как реальные сроки экспозиции закрытых сделок. Контраст: cover-страница использует `_days_on_market_range(estimate.analogs)` (668) — listings, у которых поле реально заполнено. То есть дефект именно в конфляции sold-deal (без экспозиции) с days-рендерингом. **Что править:** - На странице «Сделки» (831-838) передавать `show_days=False` — у зарегистрированных ДКП нет периода экспозиции. - Либо в `_price_range_bar` / на call-site показывать дни только если хотя бы одна сделка несёт non-None `days_on_market` (а не отдавать fallback 4–118 из листинговой эвристики). Текущая защита `if show_days and days_min is not None and days_max is not None` (trade_in_pdf.py:288) не спасает, т.к. fallback всегда возвращает int. **Что посмотреть:** - Код: `trade_in_pdf.py:830-838` (deals page), `:606-611` (`_days_on_market_range` fallback), `:267-288` (`_price_range_bar`, ветка `show_days`), `:668-675` (cover, корректное использование на analogs). Тест: PDF-рендер с `actual_deals`, у которых `days_on_market=None` → бар «Сделки» не должен печатать «4 дней / 118 дней». - Vault: релевантных заметок не найдено (запрос `trade_in_pdf days_on_market fallback exposure сделки` — пусто).
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#1366
No description provided.