MERA/оценка: пометка «коридор справочный» не покрывает Tier A — там сделок много, пометки нет, а кламп всё равно выключен #3466

Open
opened 2026-09-12 09:43:36 +00:00 by bot-backend · 0 comments
Collaborator

Выделено из deep-ревью PR #3462 (#3452). Не регресс той правки — расхождение существовало и до неё, PR #3462 просто сделал видимой одну половину проблемы и не трогает вторую.

Факт

advisory_only в ответе считается из одного признака — count < estimate_corridor_clamp_min_n. Но кламп headline выключается тремя разными способами (app/services/estimator.py _apply_corridor_clamp):

  1. corridor_count < min_n — покрыто пометкой (это и есть #3452);
  2. anchor_tier == "A" (комплы того же дома) — не покрыто;
  3. median_ppm2 <= cap — «кламп не понадобился», покрывать и не надо: это честно другая новость.

Ревьюер воспроизвёл случай 2 на ветке:

[TIER-A] n=20 advisory_only=False headline=202100 cap=140000 tier='same_building'

Двадцать сделок, поле говорит «коридор в цене участвует», пометки на экране нет — а headline 202 100 ₽/м² против потолка коридора 140 000: кламп exempt по Tier A, radius-floor тоже (он требует anchor_tier is None). Коридор не тронул цену вообще.

Почему это хуже, чем зона 3..9: здесь клиент видит МНОГО сделок и комплы собственного дома — то есть ровно тот случай, которому доверяют больше всего.

Почему не починено в #3462

Поле живёт в схеме DkpCorridor именно потому, что GET-rehydrate не пересчитывает ценообразование и тира не знает. Утащить тир в схему — значит сломать свойство «поле верно в обоих конструкторах», которое и делает его надёжным. Нужна отдельная форма: либо признак приходит из расчёта (и тогда на rehydrate его надо персистить), либо пометка про Tier A живёт на другом уровне ответа.

Хвосты того же ревью

  • Нет фронт-теста на corridorAdvisoryNote (tradein-mvp/frontend/src/lib/rosreestr.ts), хотя у соседней функции того же файла — dealsAsOfLabel — тест есть: v2/__tests__/dealsAsOf.test.ts, и он гоняет mapResultPanel по всем трём выборкам плитки. Правильный образец лежит в двух шагах. Счётчик vitest подтверждает: 278 тестов и до, и после #3462.
  • Половина порога не покрыта тестом. Докстринг advisory_only обосновывает себя тем, что порог estimate_corridor_clamp_min_n общий у клампа headline И у radius-floor. Мутационный прогон ревьюера: снятие гейта min_n у radius-floor — тест ЗЕЛЁНЫЙ. То есть половина заявленного обоснования ничем не стережётся.
  • Полоса счёта шире заявленной. _fetch_dkp_corridor отдаёт коридор при count >= 1 (city-wide widen принимается по условию len(city) > len(street), без пола в 3), а условие лога — count < 10. Значит grep -c по маркеру считает n = 1..9, тогда как приёмка #3452 сформулирована про 3..9. Либо поправить формулировку приёмки, либо завести пол в widen.

Приёмка

Клиент с Tier-A якорем и коридором n >= 10, где кламп exempt, видит на экране признак того, что коридор в цену не вошёл (или отсутствие признака перестаёт означать «вошёл»). Тест по значению: изменение поведения клампа без изменения пометки — красное.

Refs #3452, PR #3462, #1795, #652.

Выделено из deep-ревью PR #3462 (#3452). **Не регресс той правки** — расхождение существовало и до неё, PR #3462 просто сделал видимой одну половину проблемы и не трогает вторую. ## Факт `advisory_only` в ответе считается из одного признака — `count < estimate_corridor_clamp_min_n`. Но кламп headline выключается **тремя** разными способами (`app/services/estimator.py` `_apply_corridor_clamp`): 1. `corridor_count < min_n` — покрыто пометкой (это и есть #3452); 2. `anchor_tier == "A"` (комплы того же дома) — **не покрыто**; 3. `median_ppm2 <= cap` — «кламп не понадобился», покрывать и не надо: это честно другая новость. Ревьюер воспроизвёл случай 2 на ветке: ``` [TIER-A] n=20 advisory_only=False headline=202100 cap=140000 tier='same_building' ``` Двадцать сделок, поле говорит «коридор в цене участвует», пометки на экране нет — а headline 202 100 ₽/м² против потолка коридора 140 000: кламп exempt по Tier A, radius-floor тоже (он требует `anchor_tier is None`). Коридор не тронул цену вообще. **Почему это хуже, чем зона 3..9:** здесь клиент видит МНОГО сделок и комплы собственного дома — то есть ровно тот случай, которому доверяют больше всего. ## Почему не починено в #3462 Поле живёт в схеме `DkpCorridor` именно потому, что GET-rehydrate не пересчитывает ценообразование и тира не знает. Утащить тир в схему — значит сломать свойство «поле верно в обоих конструкторах», которое и делает его надёжным. Нужна отдельная форма: либо признак приходит из расчёта (и тогда на rehydrate его надо персистить), либо пометка про Tier A живёт на другом уровне ответа. ## Хвосты того же ревью - **Нет фронт-теста на `corridorAdvisoryNote`** (`tradein-mvp/frontend/src/lib/rosreestr.ts`), хотя у соседней функции того же файла — `dealsAsOfLabel` — тест есть: `v2/__tests__/dealsAsOf.test.ts`, и он гоняет `mapResultPanel` по всем трём выборкам плитки. Правильный образец лежит в двух шагах. Счётчик vitest подтверждает: 278 тестов и до, и после #3462. - **Половина порога не покрыта тестом.** Докстринг `advisory_only` обосновывает себя тем, что порог `estimate_corridor_clamp_min_n` общий у клампа headline И у radius-floor. Мутационный прогон ревьюера: снятие гейта `min_n` у radius-floor — тест ЗЕЛЁНЫЙ. То есть половина заявленного обоснования ничем не стережётся. - **Полоса счёта шире заявленной.** `_fetch_dkp_corridor` отдаёт коридор при `count >= 1` (city-wide widen принимается по условию `len(city) > len(street)`, без пола в 3), а условие лога — `count < 10`. Значит `grep -c` по маркеру считает `n = 1..9`, тогда как приёмка #3452 сформулирована про `3..9`. Либо поправить формулировку приёмки, либо завести пол в widen. ## Приёмка Клиент с Tier-A якорем и коридором `n >= 10`, где кламп exempt, видит на экране признак того, что коридор в цену не вошёл (или отсутствие признака перестаёт означать «вошёл»). Тест по значению: изменение поведения клампа без изменения пометки — красное. Refs #3452, PR #3462, #1795, #652.
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#3466
No description provided.