Commit graph

8 commits

Author SHA1 Message Date
8fed54971f fix(forecast): §6 honesty layer — pegged-signal plaque + non-residential caveat + segment/pipeline note (#1953)
All checks were successful
CI / changes (pull_request) Successful in 8s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 57s
CI / openapi-codegen-check (pull_request) Successful in 1m51s
Из live-walkthrough Anton'а (66:41:0702017:131): дефицит −1.00 «затоварка» на всех
горизонтах — данные КОРРЕКТНЫ (Кировский Комфорт: 12156 доступных ÷ ~100/мес = ~155 мес,
genuine затоварка при ставке 14.5%), но презентация ложно-точная/сбивающая.

B1: deficitPegState helper — детект насыщения (|deficit_index|≥0.99 одного знака на
    ВСЕХ горизонтах) → честная плашка «сигнал на пределе шкалы, −1.00 не различает
    горизонты, оценка грубая» над 6.1/6.2 + маркер «НА ПРЕДЕЛЕ» вместо ложно-точного ×4.
B2: поднял product_tz.gate_caveat в заметную плашку ВВЕРХ §6 (раньше не рендерился
    нигде) — «участок не под жильё → прогноз справочный».
B3: микрокопия почему future=0 (посегментный баланс vs класс-агностичный pipeline §4.3).

Edit-only, контракт не менялся. +8 unit-тестов на pegState.
2026-06-29 16:23:29 +05:00
a35d42f1c7 fix(site-finder): invest-score advisory flag + velocity data-honesty + h1 a11y (#1926) (#2094)
All checks were successful
Deploy / changes (push) Successful in 7s
Deploy / build-backend (push) Successful in 5m22s
Deploy / build-frontend (push) Successful in 6m11s
Deploy / build-worker (push) Successful in 7m53s
Deploy / deploy (push) Successful in 2m23s
2026-06-29 06:42:50 +00:00
e82761964d fix(report): human RU microcopy in Site Finder Section 6 (#1963)
All checks were successful
CI / changes (pull_request) Successful in 7s
CI / frontend-tests (pull_request) Successful in 1m4s
CI / openapi-codegen-check (pull_request) Successful in 1m54s
CI / backend-tests (pull_request) Successful in 13m50s
Replace dev-jargon with plain RU across the §22 forecast report (6.2/6.3/6.5
+ deficit/затоварка legend). Source of truth = backend reason strings + the
frontend RU maps; text/render-only, no scoring/forecast math touched.

Backend (source of truth):
- scenarios.py _COLLAPSE_REASON_LOW_BETA: «β rate-sensitivity не прошёл gate …»
  → «чувствительность к ставке не оценена на коротком ряде ЕКБ → один базовый
  сценарий вместо трёх».
- confidence_engine.py _coverage_factor: drop «domrf↔objective» jargon, say it
  affects будущее предложение/конкуренцию. New _history_factor: «глубина истории
  N мес» + на что влияет + связь с 6.2 (короткий ряд → один сценарий).

Frontend (both Section-6 families — live analysis page + ptica cockpit):
- Deficit legend: −1 затоварка / 0 баланс / +1 острый дефицит + actionable
  трактовка; MOI tied to «сколько месяцев район распродаёт предложение».
- 6.2 heading «Почему один сценарий, а не три» over the collapse reason.
- 6.3 render confidence.rationale + weakest-link rule («скорее завысим
  недоверие, чем недооценим риск»); FACTOR_RU gains confounded_window/
  advisory_cap; factor notes shown.
- 6.5 «Вес»→«Оценка»; overall verdict vs 0.5; «Риск избытка предложения»→
  «Запас по предложению»; §-refs moved from reason into tooltip; 6 special-
  index 1-line «что это + куда лучше» descriptions; 0.00-score reasons shown.

Tests: confidence_engine (history/coverage notes), stripSectionRefs vitest.

Refs #1963
2026-06-27 17:42:27 +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
f5aa7ed191 feat(sf): 6.6 in-app future-supply pressure + pipeline competitors (§13.3)
All checks were successful
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Successful in 3m21s
Deploy / deploy (push) Successful in 1m32s
Surface the §16-traceability evidence behind the supply forecast that
previously lived only in exports: future_market.future_supply (§9.3
supply-pressure breakdown — open/hidden stock, absorption, months of
pressure, future units, pressure index) and future_market.future_competitors
(§9.7 relevance-weighted pipeline, sorted by relevance desc). New
ForecastFutureSupplyBlock as subsection 6.6 (+ section-6-6 nav),
complementing 6.1's per-horizon aggregates.

- Fix FutureSupply/FutureSupplyBreakdown/FutureCompetitor optionality in
  forecast.ts to match the backend (FutureSupplyPressure/Competitor): null
  metrics typed + rendered «нет данных», never a fabricated 0.
- Supply panel gates on computed metrics (index/pressure), NOT open/hidden
  unit stocks — so the empty-supply_layers state (pre Monday-worker, every
  parcel today) hides the panel instead of falsely showing "0 ед."; the
  competitor table still renders. hasSupplySignal shared in forecast-helpers.
- RU labels reuse report_pdf/excel export wording. Graceful on partial/202.

Part of #958; surfaces #950 future-supply data.
2026-06-07 10:55:59 +00:00
a66c35ae49 feat(forecast): render scoring transparency (§13.6) as in-app subsection 6.5
All checks were successful
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Successful in 3m2s
Deploy / changes (push) Successful in 6s
Deploy / deploy (push) Successful in 1m2s
Surface the product-score + special-index breakdown behind the overall KPI
as two token-bar groups in Section 6 (6.5), sidebar anchor section-6-5.
Product scores use a 0..1 quality gradient anchored on the documented 0.5
balance point (>=0.55 strong / 0.45-0.55 mid / <0.45 weak; risk scores are
pre-inverted so higher=better); special indices use a neutral accent
(value = signal strength, direction non-uniform). Null values render as
«нет данных», never a 0-bar that implies a real zero. Graceful on
absent/partial/202-pending.

- types/forecast.ts: ReportScoring + nested (dict-keyed scores/indices)
- ForecastScoringBlock.tsx: two bar groups, a11y, null-distinct rendering
- forecast-helpers.ts: scoreVariant/scoreBarWidthPct + RU label maps
- Section6Forecast + sidebar nav: wire 6.5

Part of #958.
2026-06-07 10:08:28 +00:00
54a501b90a feat(forecast): render product_tz (ТЗ на ЖК) as in-app subsection 6.4
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Successful in 2m56s
Deploy / deploy (push) Successful in 1m14s
Adds «6.4 Рекомендация по продукту» to Section6Forecast — the §13.4
product recommendation (class, unit-mix, commercial, USP, §16 reasons)
that previously existed only in the export renderers. Unit-mix is shown
as token-colored horizontal bars; since the assembler emits no per-format
share (pct), bars are honestly labeled as a deficit-by-format signal, not
a build-share. Graceful on thin/202-pending/partial reports.

- types/forecast.ts: ReportProductTz + nested interfaces, optional on ForecastReport
- ForecastProductTzBlock.tsx: per-field guards, role=img bars, reasons disclosure
- forecast-helpers.ts: deficitBarWidthPct
- Section6Forecast + sidebar nav: wire 6.4

Part of #958.
2026-06-07 09:55:54 +00:00
4ec762a202 feat(site-finder): forecast Section 6 (прогноз/сценарии/confidence) on analysis screen (#998)
All checks were successful
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Successful in 2m56s
Deploy / deploy (push) Successful in 1m4s
Renders the §22 SiteFinderReport (future_market/scenarios/confidence) as a new
Section 6 on the modern analysis page (/site-finder/analysis/[cad]), mirroring the
Section1-5 pattern. Polls GET /parcels/{cad}/forecast (202 pending → 200 ready) via
TanStack Query. Render-only (horizon selector = separate #996).

- 6.1 прогноз по горизонтам (deficit_index, MOI, demand/supply, ставка)
- 6.2 сценарии base/aggressive/conservative + rate_path
- 6.3 уверенность: level pill + явный список drivers (confidence.factors)
- types/forecast.ts typed against real prod report; fixture parcel-forecast.json (run #68)
- reuses design tokens + Badge/KpiCard; advisory disclaimer always shown

Part of EPIC #958. Deps 955-A2/A4 (backend §13, merged).
2026-06-05 14:09:55 +05:00