MERA/оценка: порог показа коридора (3) и порог доверия к нему (10) рассогласованы — клиенты в зоне 3..9 видят коридор, но ценовая страховка молча … #3452

Closed
opened 2026-09-11 21:53:51 +00:00 by bot-backend · 1 comment
Collaborator

Найдено при ревью PR #3445 (#3256).

Факт. Два разных порога на одну и ту же выборку:

  • DKP_CORRIDOR_CITY_WIDE_MIN_N = 3 (app/services/estimator.py:171) — ниже трёх сделок включается city-wide расширение (estimator.py:1998), то есть при n≥3 коридор считается пригодным и показывается;
  • estimate_corridor_clamp_min_n = 10 (app/core/config.py:476) — гейт и для клампа headline (estimator.py:3747), и для radius-floor (estimator.py:3770).

В зоне n = 3..9 коридор существует, отображается и участвует в fallback-путях, но не клампит — то есть ценовая страховка выключена, и по виду экрана это неотличимо от работающей.

Почему всплыло сейчас. #3445 (снятие предиката d.rooms) переносит часть клиентов именно в эту зону: у двоих замерено 248 → 3 и 72 → 8 сделок. Механика корректная («улица важнее города»: street-выборка доросла до 3, и city-wide расширение больше не нужно), но следствие — коридор остался, а кламп молча перестал применяться. Само по себе это не регресс #3445: кламп по трём сделкам был бы хуже, чем его отсутствие.

Что решить: либо согласовать пороги (показывать коридор только с n ≥ clamp_min_n), либо оставить зону 3..9 как «advisory-only», но тогда (а) помечать это в ответе/на экране и (б) логировать попадание — сейчас нет ни того, ни другого, и отличить «кламп не сработал» от «кламп не понадобился» по логам нельзя.

Приёмка: в логах видно число оценок, попавших в зону 3..9 за сутки; на экране такой коридор помечен как справочный.

Refs #3256, PR #3445, #652, #1795.

Найдено при ревью PR #3445 (#3256). **Факт.** Два разных порога на одну и ту же выборку: - `DKP_CORRIDOR_CITY_WIDE_MIN_N = 3` (`app/services/estimator.py:171`) — ниже трёх сделок включается city-wide расширение (`estimator.py:1998`), то есть при `n≥3` коридор считается пригодным и показывается; - `estimate_corridor_clamp_min_n = 10` (`app/core/config.py:476`) — гейт и для клампа headline (`estimator.py:3747`), и для radius-floor (`estimator.py:3770`). В зоне `n = 3..9` коридор существует, отображается и участвует в fallback-путях, но **не клампит** — то есть ценовая страховка выключена, и по виду экрана это неотличимо от работающей. **Почему всплыло сейчас.** #3445 (снятие предиката `d.rooms`) переносит часть клиентов именно в эту зону: у двоих замерено 248 → 3 и 72 → 8 сделок. Механика корректная («улица важнее города»: street-выборка доросла до 3, и city-wide расширение больше не нужно), но следствие — коридор остался, а кламп молча перестал применяться. Само по себе это не регресс #3445: кламп по трём сделкам был бы хуже, чем его отсутствие. **Что решить:** либо согласовать пороги (показывать коридор только с `n ≥ clamp_min_n`), либо оставить зону 3..9 как «advisory-only», но тогда (а) помечать это в ответе/на экране и (б) логировать попадание — сейчас нет ни того, ни другого, и отличить «кламп не сработал» от «кламп не понадобился» по логам нельзя. **Приёмка:** в логах видно число оценок, попавших в зону `3..9` за сутки; на экране такой коридор помечен как справочный. Refs #3256, PR #3445, #652, #1795.
Author
Collaborator

Код доехал до прода — 2026-09-12

Маркеры в живом контейнере tradein-backend:

advisory_only в app/schemas/trade_in.py        = 2
corridor_advisory_zone в app/services/estimator.py = 2

PR #3462 merged (dfc39355).

Что изменилось против первоначальной правки

Ревью нашло, что подпись утверждала про АЛГОРИТМ то, чего код не гарантирует: гейт «#1795 шаг 3» (Tier C) использует dkp_raw["high_ppm2"] без порога min_n, и воспроизведён случай, где коридор из 5 сделок уронил headline с 300 500 до 200 000 ₽/м², а подпись говорила «оценку по ним не корректировали». Формулировка переписана на утверждение о ДАННЫХ («справочно: сделок мало (N) — коридор ориентировочный») — оно истинно во всех достижимых состояниях. Добавлена и вторая ветка: когда объявлений рядом нет и headline построен из этих же сделок, клиент теперь видит «оценка построена на этих сделках — их всего N» вместо молчания.

Приёмка по числу попаданий — с датой

Критерий «в логах видно число оценок, попавших в зону, за сутки» сегодня непроверяем по той же причине: контейнер пересоздан, окно логов — минуты. Проверить не раньше 2026-09-13 12:00 UTC:

ssh poincare 'docker inspect tradein-backend --format "{{.State.StartedAt}}";   docker logs --since 24h tradein-backend 2>&1 | wc -l;   docker logs --since 24h tradein-backend 2>&1 | grep -c "corridor_advisory_zone"'

Оговорка к самому критерию: маркер пишется при count < 10, а _fetch_dkp_corridor отдаёт коридор начиная с count >= 1 — значит счёт покрывает зону 1..9, а не 3..9, как сформулировано в issue.

Хвосты вынесены в #3466: Tier A даёт обратное расхождение (сделок много, пометки нет, кламп всё равно exempt), у corridorAdvisoryNote нет фронт-теста, половина порога (radius-floor) тестом не покрыта.

## Код доехал до прода — 2026-09-12 Маркеры в живом контейнере `tradein-backend`: ``` advisory_only в app/schemas/trade_in.py = 2 corridor_advisory_zone в app/services/estimator.py = 2 ``` PR #3462 merged (`dfc39355`). ## Что изменилось против первоначальной правки Ревью нашло, что подпись утверждала про АЛГОРИТМ то, чего код не гарантирует: гейт «#1795 шаг 3» (Tier C) использует `dkp_raw["high_ppm2"]` **без порога `min_n`**, и воспроизведён случай, где коридор из 5 сделок уронил headline с 300 500 до 200 000 ₽/м², а подпись говорила «оценку по ним не корректировали». Формулировка переписана на утверждение о ДАННЫХ («справочно: сделок мало (N) — коридор ориентировочный») — оно истинно во всех достижимых состояниях. Добавлена и вторая ветка: когда объявлений рядом нет и headline построен из этих же сделок, клиент теперь видит «оценка построена на этих сделках — их всего N» вместо молчания. ## Приёмка по числу попаданий — с датой Критерий «в логах видно число оценок, попавших в зону, за сутки» сегодня непроверяем по той же причине: контейнер пересоздан, окно логов — минуты. **Проверить не раньше 2026-09-13 12:00 UTC:** ```bash ssh poincare 'docker inspect tradein-backend --format "{{.State.StartedAt}}"; docker logs --since 24h tradein-backend 2>&1 | wc -l; docker logs --since 24h tradein-backend 2>&1 | grep -c "corridor_advisory_zone"' ``` Оговорка к самому критерию: маркер пишется при `count < 10`, а `_fetch_dkp_corridor` отдаёт коридор начиная с `count >= 1` — значит счёт покрывает зону `1..9`, а не `3..9`, как сформулировано в issue. Хвосты вынесены в #3466: Tier A даёт обратное расхождение (сделок много, пометки нет, кламп всё равно exempt), у `corridorAdvisoryNote` нет фронт-теста, половина порога (radius-floor) тестом не покрыта.
Sign in to join this conversation.
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#3452
No description provided.