fix(tradein/v2): честность+консистентность — реконсиляция счётчика аналогов, убрать фейк-donut/линейку, outlier-guard, created_at, дисклеймеры #2481

Merged
bot-backend merged 1 commit from fix/v2-honesty-consistency into main 2026-07-12 15:09:11 +00:00
Collaborator

Контекст

Полировка Mera v2 UI-блоков после live-аудита. Тот же класс дефектов, что уже чинили раньше: "фейк-данные под видом реальных". Честная деградация везде: убрать фейк / завести реальные данные / явно разметить как приближение — никогда не выдумывать.

Фиксы

  1. [FLAGSHIP] Реконсиляция счётчика аналогов. Бэкенд (schemas/trade_in.py:163-165,180-181, estimator.py:3286-3310, #2087 M1) явно документирует семантику: n_analogs — полный счёт, использованный в расчёте ("Консьюмер должен брать счёт отсюда, а не из len()"); analogs/source_counts — персистентный top-10 сэмпл, намеренно капнутый, чтобы POST-ответ не расходился с GET-reload. Это не "найдено vs использовано", а "истинный итог vs капнутая выборка для отображения".
    • 02/03/05 headline-цифры уже брали n_analogs — не трогал.
    • Добавил дисклозуру там, где рядом всплывала капнутая выборка и создавала мнимое противоречие:
      • 02 ResultPanel.tsx — под тайлами "ИСТОЧНИКИ ДАННЫХ" caption "Разбивка — по показанным N из M аналогам", когда analogs.length < n_analogs.
      • 05 SourcesMap.tsx — шапка карты "Объявлений: N из M".
      • 05 SourcesView.tsx — подвал таблицы объявлений "Показано N из M объявлений" (по образцу уже существующего паттерна у таблицы сделок).
  2. [03] Убран фейковый donut "КАЧЕСТВО ДАННЫХ" (ObjectSummary.tsx) — хардкод strokeDasharray="126" strokeDashoffset="72" (~43%, никогда не менялся). Композитного quality-score нет нигде в мапперах — не стал выдумывать, убрал кольцо, оставил 3 реальные текстовые строки.
  3. [HeroBar] Убрана фейковая линейка расстояний — хардкод тиков 0/25/50/75/100м поверх стокового фото, без привязки к реальному масштабу.
  4. [HeroBar] Скрыты компас и street-view слот — оба поля всегда "" (TODO BE-3, mappers.ts:mapObject). По образцу уже используемого в файле паттерна locationCoef "нет данных".
  5. [HeroBar/Footer] mapReport теперь берёт реальный created_at (#2043/BE-1), фоллбек на expires_at−24ч только для pre-BE-1 записей без created_at.
  6. [01] Бейдж "ДАННЫЕ АКТУАЛЬНЫ / ДЕЙСТВИТЕЛЕН 24 Ч" (ParamsPanel.tsx) загейчен на hasEstimate — раньше показывался как свежий ДО первой оценки. 24ч TTL сам по себе реальная константа кэша, дефект был только в always-visible.
  7. [01] Дисклеймер у декоративной SVG-карты — "Схематично · не географическая карта · радиус не в масштабе", без изменения самой картинки.
  8. [02/05] Outlier-guard на ₽/м² (mappers.ts:guardPriceOutliers, порог 2.5–3× медианы пула — взял середину 2.75×): исключение выбросов из CV/разброса с раскрытием количества ("N возможных выбросов исключено из расчёта разброса") + бейдж "возможный выброс" на строке в таблице объявлений (05).
  9. [05] SourcesMap.tsx попап сделки "(квартал, Росреестр)" → "(месяц, Росреестр)" — fmtMonthYear реально рендерит месяц, не квартал.
  10. [07] mapCache "ВСЕГО ОЦЕНОК" саб-лейбл "по вашим оценкам" → "последние 50" — useEstimateHistory() капает на 50 (trade-in-api.ts:247), не лайфтайм-тотал.

Тесты

  • tsc --noEmit — зелёный.
  • next lint — зелёный (только pre-existing warnings в нетронутых файлах: CianAuthBanner, pct, <img> в HeroBar:318 вне зоны правок).
  • next build — зелёный (задет shared types.ts → прогнал полный build).

Скоуп/решения, требующие внимания

  • Fix #1 семантика: подтверждена явными комментариями в бэкенде, не гадал.
  • Fix #8 порог: 2.75× — середина запрошенного диапазона 2.5–3×, не тюнил под конкретные данные.
  • Не трогал dealRows/actual_deals outlier-guard — не было в скоупе задачи (только ads/analogs price_per_m2).
  • Не трогал buildSources/source_counts wiring — бэкенд-комментарий (#2087 M1) явно объясняет, почему они капнуты синхронно с analogs; переключение на source_counts дало бы те же числа (той же капнутой выборки), с потерей deals-счёта. Оставил FE groupBy, добавил дисклозуру вместо этого.
## Контекст Полировка Mera v2 UI-блоков после live-аудита. Тот же класс дефектов, что уже чинили раньше: "фейк-данные под видом реальных". Честная деградация везде: убрать фейк / завести реальные данные / явно разметить как приближение — никогда не выдумывать. ## Фиксы 1. **[FLAGSHIP] Реконсиляция счётчика аналогов.** Бэкенд (`schemas/trade_in.py:163-165,180-181`, `estimator.py:3286-3310`, #2087 M1) явно документирует семантику: `n_analogs` — полный счёт, использованный в расчёте ("Консьюмер должен брать счёт отсюда, а не из len()"); `analogs`/`source_counts` — персистентный top-10 сэмпл, намеренно капнутый, чтобы POST-ответ не расходился с GET-reload. Это **не** "найдено vs использовано", а "истинный итог vs капнутая выборка для отображения". - 02/03/05 headline-цифры уже брали `n_analogs` — не трогал. - Добавил дисклозуру там, где рядом всплывала капнутая выборка и создавала мнимое противоречие: - 02 `ResultPanel.tsx` — под тайлами "ИСТОЧНИКИ ДАННЫХ" caption "Разбивка — по показанным N из M аналогам", когда `analogs.length < n_analogs`. - 05 `SourcesMap.tsx` — шапка карты "Объявлений: N из M". - 05 `SourcesView.tsx` — подвал таблицы объявлений "Показано N из M объявлений" (по образцу уже существующего паттерна у таблицы сделок). 2. **[03] Убран фейковый donut "КАЧЕСТВО ДАННЫХ"** (`ObjectSummary.tsx`) — хардкод `strokeDasharray="126" strokeDashoffset="72"` (~43%, никогда не менялся). Композитного quality-score нет нигде в мапперах — не стал выдумывать, убрал кольцо, оставил 3 реальные текстовые строки. 3. **[HeroBar] Убрана фейковая линейка расстояний** — хардкод тиков 0/25/50/75/100м поверх стокового фото, без привязки к реальному масштабу. 4. **[HeroBar] Скрыты компас и street-view слот** — оба поля всегда `""` (TODO BE-3, `mappers.ts:mapObject`). По образцу уже используемого в файле паттерна `locationCoef` "нет данных". 5. **[HeroBar/Footer] `mapReport`** теперь берёт реальный `created_at` (#2043/BE-1), фоллбек на `expires_at−24ч` только для pre-BE-1 записей без `created_at`. 6. **[01] Бейдж "ДАННЫЕ АКТУАЛЬНЫ / ДЕЙСТВИТЕЛЕН 24 Ч"** (`ParamsPanel.tsx`) загейчен на `hasEstimate` — раньше показывался как свежий ДО первой оценки. 24ч TTL сам по себе реальная константа кэша, дефект был только в always-visible. 7. **[01] Дисклеймер у декоративной SVG-карты** — "Схематично · не географическая карта · радиус не в масштабе", без изменения самой картинки. 8. **[02/05] Outlier-guard на ₽/м²** (`mappers.ts:guardPriceOutliers`, порог `2.5–3×` медианы пула — взял середину `2.75×`): исключение выбросов из CV/разброса с раскрытием количества ("N возможных выбросов исключено из расчёта разброса") + бейдж "возможный выброс" на строке в таблице объявлений (05). 9. **[05] `SourcesMap.tsx`** попап сделки "(квартал, Росреестр)" → "(месяц, Росреестр)" — `fmtMonthYear` реально рендерит месяц, не квартал. 10. **[07] `mapCache`** "ВСЕГО ОЦЕНОК" саб-лейбл "по вашим оценкам" → "последние 50" — `useEstimateHistory()` капает на 50 (`trade-in-api.ts:247`), не лайфтайм-тотал. ## Тесты - `tsc --noEmit` — зелёный. - `next lint` — зелёный (только pre-existing warnings в нетронутых файлах: `CianAuthBanner`, `pct`, `<img>` в HeroBar:318 вне зоны правок). - `next build` — зелёный (задет shared `types.ts` → прогнал полный build). ## Скоуп/решения, требующие внимания - Fix #1 семантика: подтверждена явными комментариями в бэкенде, не гадал. - Fix #8 порог: 2.75× — середина запрошенного диапазона 2.5–3×, не тюнил под конкретные данные. - Не трогал `dealRows`/`actual_deals` outlier-guard — не было в скоупе задачи (только ads/analogs price_per_m2). - Не трогал `buildSources`/`source_counts` wiring — бэкенд-комментарий (#2087 M1) явно объясняет, почему они капнуты синхронно с `analogs`; переключение на `source_counts` дало бы те же числа (той же капнутой выборки), с потерей deals-счёта. Оставил FE groupBy, добавил дисклозуру вместо этого.
bot-backend added 1 commit 2026-07-12 15:03:25 +00:00
fix(tradein/v2): честность+консистентность UI-блоков
All checks were successful
CI / changes (pull_request) Successful in 7s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Successful in 58s
CI Trade-In / changes (pull_request) Successful in 8s
CI / openapi-codegen-check (pull_request) Has been skipped
06a88f683d
Полировка Mera v2 после live-аудита — тот же класс "фейк-данные под видом
реальных", что уже чинили раньше. Честная деградация: убрать фейк / завести
реальные данные / явно разметить, никогда не выдумывать.

1. Реконсиляция счётчика аналогов. Бэкенд (schemas/trade_in.py:163-165,180-181,
   estimator.py:3286-3310, #2087 M1) чётко документирует: n_analogs — полный
   счёт, использованный в расчёте; analogs/source_counts — персистентный
   top-10 сэмпл (намеренно капнутый, чтобы POST/GET не расходились). Это НЕ
   "найдено vs использовано", а "полный итог vs капнутая выборка для показа".
   02/03/05 уже использовали n_analogs в headline-цифрах — оставлено. Добавлена
   дисклозура там, где рядом всплывала капнутая выборка и создавала мнимое
   противоречие: 02 (тайлы источников vs "ПОСТРОЕНО ПО N АНАЛОГАМ"), 05 (шапка
   карты и подвал таблицы объявлений) — по образцу уже существующего паттерна
   "Показано N из M" (deals-таблица).
2. Убран фейковый donut "КАЧЕСТВО ДАННЫХ" (ObjectSummary) — хардкод
   strokeDasharray/offset, композитного score нет нигде в мапперах.
3. Убрана фейковая линейка расстояний (HeroBar) — хардкод тиков 0/25/50/75/100м
   поверх стокового фото.
4. Скрыты компас и street-view слот (HeroBar) — оба поля всегда "" (TODO BE-3),
   по образцу уже используемого в файле паттерна locationCoef "нет данных".
5. mapReport берёт реальный created_at (#2043/BE-1), фоллбек на expires−24h
   только для pre-BE-1 записей без created_at.
6. Бейдж "ДАННЫЕ АКТУАЛЬНЫ/ДЕЙСТВИТЕЛЕН 24 Ч" (ParamsPanel) загейчен на
   hasEstimate — раньше показывался как свежий ДО первой оценки.
7. Дисклеймер у декоративной SVG-карты (ParamsPanel): "Схематично · не
   географическая карта · радиус не в масштабе".
8. Outlier-guard на ₽/м² (mappers.ts guardPriceOutliers, порог 2.5–3× медианы
   пула, взята середина — 2.75×): исключение из CV/разброса с дисклозурой
   count + бейдж "возможный выброс" на строке в таблице объявлений (05).
9. SourcesMap: попап сделки "(квартал, Росреестр)" → "(месяц, Росреестр)" —
   fmtMonthYear реально рендерит месяц.
10. mapCache "ВСЕГО ОЦЕНОК" → саб-лейбл "последние 50" (useEstimateHistory
    капает на 50, trade-in-api.ts:247) — было похоже на лайфтайм-тотал.

tsc --noEmit + next lint зелёные; next build (задет shared types.ts) зелёный.
bot-backend merged commit 338ccbb78f into main 2026-07-12 15:09:11 +00:00
bot-backend deleted branch fix/v2-honesty-consistency 2026-07-12 15:09:11 +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#2481
No description provided.