Commit graph

3 commits

Author SHA1 Message Date
41804ed70e fix(forecast): посегментный+дедуплицированный индекс дефицита (#1959)
Корень «−1.00 везде» (эпик #1953): compute_demand_supply_forecast брал
district-wide unit_velocity (847.5/мес, ВСЕ классы/комнаты) как спрос и
весь district-сток (~63k доступных) как предложение для КАЖДОЙ ячейки
what_to_build → один и тот же ratio во всех ячейках → все deficit_index
прижаты к −1.0. Плюс objective_lots — append-per-snapshot (~2.9× инфляция
строк), что симметрично раздувало обе базы → даже сегментация без дедупа
осталась бы вырожденной.

Фикс (blast radius — ТОЛЬКО forecast/deficit calc; platform-wide dedup = #1964):
- market_metrics.compute_market_metrics: +obj_class/+room_bucket (+cache key).
  _STOCK_SQL и _SALES_WINDOW_SQL дедуплят до ПОСЛЕДНЕГО снапшота на физлот
  (DISTINCT ON project_name,corpus_name,section,floor,lot_number ORDER BY …
  snapshot_date DESC,id DESC), затем агрегируют. Class-фильтр (LOWER=LOWER,
  class lowercase) + room-bucket (Source-B room_area-вокабуляр, зеркало
  sales_series.room_area_bucket_of → what_to_build фильтрует без перевода).
  ROLLUP/GROUPING сохранён; confidence считается на дедуплицированных counts.
- demand_supply_forecast: base_pace и open-сток теперь ПОСЕГМЕНТНЫЕ
  (market_metrics(obj_class,room_bucket)). При заданном сегменте L2/L3
  (hidden/future) ИСКЛЮЧЕНЫ из баланса — они класс/формат-агностичны, иначе
  двоились бы по всем ячейкам. +_market_room_bucket VOCAB-мост (валидирующий
  pass-through Source-B меток; неизвестное → None = без фильтра, не тихий 0-rows).
- what_to_build/_DEFAULT_CLASSES и recommendation Economy-маппинг: «эконом»→
  «стандарт» (в objective_lots эконома НЕТ, стандарт=483k → раньше ячейка
  матчила 0 строк и молча выпадала).
- report_assembler honesty-guard: если ВСЯ сетка прижата к ±1.0
  (degenerate-fallback) — не эмитим «строить»/«избегать», показываем
  «недостаточно гранулярных данных для посегментного вывода».
- data/sql/173_objective_lots_physflat_idx.sql: partial index под DISTINCT ON
  (Index Only Scan + Unique, без Sort на 1.75M строк; idempotent, BEGIN/COMMIT).

Prod-verify (parcel 66:41:0205010:287, Железнодорожный, h=24): ячейки
ДИФФЕРЕНЦИРУЮТ (12 measured, 7 distinct) вместо all −1.0; MOI комфорт/студия
38.5 vs стандарт/студия 244.3 (точное совпадение с ожидаемым).

Тесты: регрессия «ячейки различаются (не all −1.0)» + vocab-translation +
honesty-guard + посегментное предложение. ruff clean; no :name::type.
2026-06-27 22:50:58 +05:00
8cd0620543 feat(site-finder): продуктовые решения по фидбеку analyze (#1741 #1742 #1743 #1744 #1745)
All checks were successful
CI / changes (pull_request) Successful in 8s
CI / changes (push) Successful in 9s
CI / frontend-tests (push) Successful in 1m43s
CI / frontend-tests (pull_request) Successful in 1m59s
CI / openapi-codegen-check (push) Successful in 2m43s
CI / openapi-codegen-check (pull_request) Successful in 1m55s
CI / backend-tests (push) Successful in 9m28s
CI / backend-tests (pull_request) Successful in 9m28s
После ролевой дискуссии (аналитик×комдир×собственник):
- #1741 секции в 2 группы «Участок»→«Стройка и рынок» (Section1→4→2→3→5→6), gate-баннер вынесен НАД группой (убран дубль из Section4Estimate), nav-группы
- #1742 объяснение выбора класса: фраза-причина + мини-таблица 3 классов по deficit_index («+1 острый дефицит, −1 затоварка»). POI «обеспеченность»/market-overstock relabel — N/A (в UI не выводятся)
- #1743 «Остатки и скорость»→«Как продаётся рынок рядом» + headline-вердикт + «Темп продаж»/«Будущее предложение конкурентов (24 мес)» (убран англицизм Velocity-score/Pipeline) + интерпретированные единицы
- #1744 горизонт: caption+tooltip «пересчёт ~10-30с» + статус «Пересчитываем…»; колонки прогноза «…, квартир» + caveat advisory
- #1745 фаза1: таблица «Прогноз по всем форматам» (студия/1-5к × индекс дефицита/прогноз спроса/сигнал); backend пробросил per-format projected_demand_units + signal. Слайдеры/рубли — фаза2 после бэктеста #951

Verify: tsc 0 ошибок; py_compile; what_to_build/recommendation/report/exporter тесты pass.

Closes #1741
Closes #1742
Closes #1743
Closes #1744
Closes #1745
2026-06-18 12:18:04 +05:00
489e380f1e feat(forecasting): what-to-build ranker + MAI proxy (#981, 952-B) (#1013)
All checks were successful
Deploy / build-backend (push) Successful in 1m31s
Deploy / build-worker (push) Successful in 2m43s
Deploy / deploy (push) Successful in 1m9s
Deploy / changes (push) Successful in 5s
Deploy / build-frontend (push) Has been skipped
2026-06-03 07:07:17 +00:00