fix(tradein/sql): цена в подписи дедупликации «доли квартир дома в продаже» #2539
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#2539
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/tradein-sale-share-dedup-signature"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Проблема
Метрика «доля квартир дома в продаже» считала числитель как
count(DISTINCT (rooms, round(area_m2), floor)). Замысел верный — убрать кросс-площадочные дубли, когда одна квартира висит на Авито, ЦИАН и Домклике. Но в типовом секционном доме четыре разные квартиры на одном этаже в разных подъездах имеют ровно ту же тройку и схлопываются в одну. Подъезда в данных нет.Валидация исходной миграции 148 проверяла только «числитель не вырос ни у одного дома» — то есть недо-схлопывание не проверялось вовсе.
Замеры на боевой базе
По активным вторичным объявлениям с заполненными ключевыми полями:
Метрика занижена примерно на 10%, правка возвращает 1 173 квартиры.
Из 3 220 схлопываемых групп 1 252 группы (1 756 записей) имеют разные цены, а 233 группы (249 записей) пришли с одной площадки. И то и другое — почти наверняка разные квартиры: одна площадка редко публикует одну квартиру дважды, а разные квартиры в одном доме почти никогда не стоят ровно одинаково.
Решение
В подпись добавлен ценовой бакет
round(price_rub / 100000)— тот же приём и та же величина, что уже используются для дедупликации аналогов вestimator.py(обоснование бакета там же: ±0,5% при 21 млн, ±2% при 2,5 млн). Пустая или неположительная цена даётNULL, то есть такая запись не схлопывается ни с чем — та же философия, что для пустыхrooms/area/floorв исходной миграции.Все накопленные наследниками условия сохранены байт в байт: гео-ограничение ≤300 м (150), проверка этажности ±3 (152), правдоподобие по медианной этажности (153), приоритет ЖКХ в знаменателе (149).
Чего решение не делает — честно
Требование «с разных площадок» в SQL не выражено. Оно потребовало бы двухуровневой агрегации по всем шести фильтрованным агрегатам, и риск регрессии там выше пользы. Следствия задокументированы в комментарии миграции:
Найдено попутно, не в этом PR
buildings_query.py::build_listings_query(панель листингов одного дома) реализует ту же старую тройку самостоятельно, своимDISTINCT ON, не читая view. После этой миграции список домов и детальная панель дома начнут расходиться в числе уникальных квартир. Стоит завести отдельную задачу на консистентность.Test plan
uv run pytest -q— 2658 passed, 8 skipped; изменений в тестах не потребовалось