fix(tradein/estimator): дедуп кросс-source дублей в anchor-пути (#2265 follow-up) #2311

Merged
lekss361 merged 1 commit from fix/tradein-anchor-dedup-gap into main 2026-07-03 20:35:38 +00:00
Owner

Summary

Живой QA-smoke на проде (2026-07-03) после мерджа PR #2273 воспроизвёл тот же класс бага дублей в analogs — gap оказался в покрытии дедупа, не в алгоритме.

_dedup_cross_source() (введена PR #2273) вызывалась только на радиусном пути (_price_from_inputs()listings). Anchor-тиры (Tier A same_building / Tier C micro_radius, _fetch_anchor_comps() — отдельный raw SQL) никогда не дедуплицировались, а anchor_comps_used фидит и показываемые analogs[], и n_analogs, как только сработал анкорный тир — именно этот путь и сработал на реальном тестовом адресе («Рассветная 5», физлот ул. Сыромолотова 11 показан дважды через cian+domklik).

Фикс: anchor_comps = _dedup_cross_source(anchor_comps) перед _compute_same_building_anchor и перед anchor_comps_used — оба потребителя читают один и тот же постдедуп список, n_analogs и показанные analogs остаются синхронными без отдельной логики.

Test plan

  • 4 новых теста (test_estimator_anchor_dedup_gap_2265.py): точный live-репро физлот на anchor-пути (2→1), честность n_analogs, дедуп на пуле >2, anti-false-merge контроль
  • Регрессия подтверждена: без фикса 3/4 новых теста падают (воспроизводят баг), с фиксом — все зелёные
  • Targeted suite (dedup/anchor/estimator/comps): 651 passed, 4 skipped
  • Full backend suite: 3130 passed, 6 skipped, 1 failed (test_search_api.py::test_search_cache_hit — pre-existing, не связан, подтверждено прогоном на чистом forgejo/main)
  • Существующие 9 тестов PR #2273 (радиусный путь) не тронуты, все зелёные
  • post-merge: прод-smoke — переоценка кейса «Рассветная 5», n_analogs без дублей на anchor-тире

Refs #2265, #2262

## Summary Живой QA-smoke на проде (2026-07-03) после мерджа PR #2273 воспроизвёл тот же класс бага дублей в analogs — gap оказался в покрытии дедупа, не в алгоритме. `_dedup_cross_source()` (введена PR #2273) вызывалась только на радиусном пути (`_price_from_inputs()` → `listings`). Anchor-тиры (Tier A same_building / Tier C micro_radius, `_fetch_anchor_comps()` — отдельный raw SQL) никогда не дедуплицировались, а `anchor_comps_used` фидит и показываемые `analogs[]`, и `n_analogs`, как только сработал анкорный тир — именно этот путь и сработал на реальном тестовом адресе («Рассветная 5», физлот ул. Сыромолотова 11 показан дважды через cian+domklik). Фикс: `anchor_comps = _dedup_cross_source(anchor_comps)` перед `_compute_same_building_anchor` и перед `anchor_comps_used` — оба потребителя читают один и тот же постдедуп список, n_analogs и показанные analogs остаются синхронными без отдельной логики. ## Test plan - [x] 4 новых теста (`test_estimator_anchor_dedup_gap_2265.py`): точный live-репро физлот на anchor-пути (2→1), честность n_analogs, дедуп на пуле >2, anti-false-merge контроль - [x] Регрессия подтверждена: без фикса 3/4 новых теста падают (воспроизводят баг), с фиксом — все зелёные - [x] Targeted suite (dedup/anchor/estimator/comps): 651 passed, 4 skipped - [x] Full backend suite: 3130 passed, 6 skipped, 1 failed (test_search_api.py::test_search_cache_hit — pre-existing, не связан, подтверждено прогоном на чистом forgejo/main) - [x] Существующие 9 тестов PR #2273 (радиусный путь) не тронуты, все зелёные - [ ] post-merge: прод-smoke — переоценка кейса «Рассветная 5», n_analogs без дублей на anchor-тире Refs #2265, #2262
lekss361 added 1 commit 2026-07-03 20:32:55 +00:00
fix(tradein/estimator): дедуп кросс-source дублей в anchor-пути (#2265 follow-up)
All checks were successful
CI / changes (pull_request) Successful in 8s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI Trade-In / changes (pull_request) Successful in 8s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 1m42s
86174e8720
PR #2273 применял _dedup_cross_source() только к радиусному списку listings
внутри _price_from_inputs(). Anchor-тиры (Tier A same_building / Tier C
micro_radius, _fetch_anchor_comps()) строятся отдельным raw SQL-запросом и
никогда не проходили через дедуп, хотя именно anchor_comps_used фидит
показываемые analogs[] и n_analogs, как только сработал анкорный тир.

Живой QA 2026-07-03 воспроизвёл ровно этот класс бага: физлот
ул. Сыромолотова 11 (33.6м², эт.3, 4.0млн) показан дважды через
cian+domklik (оба с пустым cadastral_number) на реальном адресе с
analog_tier=micro_radius.

Фикс: anchor_comps = _dedup_cross_source(anchor_comps) перед
_compute_same_building_anchor и перед anchor_comps_used — оба потребителя
(n_analogs и показываемые analogs) читают один и тот же постдедуп список,
синхронизация не требует отдельной логики.

Refs #2265, #2262
lekss361 merged commit 4fedfc5970 into main 2026-07-03 20:35:38 +00:00
lekss361 deleted branch fix/tradein-anchor-dedup-gap 2026-07-03 20:35:38 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
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#2311
No description provided.