feat(concept): живой 3D-massing → пересчёт финмодели в «7. Концепция» (#1965 Stage 2b) #2026

Merged
bot-backend merged 1 commit from feat/concept-live-massing-1965-stage2b into main 2026-06-27 20:10:42 +00:00
Collaborator

#1965 Stage 2b (эпик #1953) — ядро запроса: крутишь этажность/секции в 3D → ТЭП и NPV/IRR пересчитываются вживую. Фронт-онли, без contract-изменений (хук бьёт уже-задеплоенный /concepts/recompute). code-reviewer APPROVE.

Что

  • useRecomputeMassing() (concept-api) — TanStack mutation на POST /concepts/recompute.
  • MassingScene.onModelChange?(model) — колбэк по смене этажности/секций (НЕ по солнцу); no-op без пропа → /ptica-кокпит/preview/дроверы не задеты (regression-safe, проверено по всем 3 консьюмерам).
  • MassingEconomics.tsx — light KPI-полоса: ТЭП (GFA, продаваемая, квартиры, КСИТ факт/цель) + финмодель (выручка, себестоимость, прибыль, ROI, NPV, IRR, цена). Debounce 250мс + latest-wins (monotonic reqId дропает устаревшие success И failure), last-good при ошибке, skeleton на первом расчёте.
  • В «7. Концепция»: lazy MassingViewer (dynamic ssr:false, Three.js) + полоса экономики в 2 колонки.

Маппинг computeModel → MassingProgram

footprint/floors/sections из computeModel; site_area ← polygonAreaSqm; КСИТ ← coerceFloat(nspd_zoning.max_far) (fallback 3.5); class/type/цена/source ← financial_estimate.* (price_source пробрасывается — честный флаг); land ← egrn.cadastral_value_rub; centroid-WKT для DB-fallback. КСИТ-over-cap флагается (farActual>maxFar).

Качество

  • tsc clean; next lint clean; prettier 3.9.0 clean. Без backend/миграций. Edge: нет полигона/financial_estimate=null → graceful (полоса скрыта/деградирует, без краша). Reviewer: regression-safety по 3 консьюмерам + latest-wins проверены.

Закрывает ядро #1965 (Stage 1 консолидация + Stage 2 живой пересчёт). Остаётся опц. Stage 3 (каталог типовых домов: ConceptInput.building_program). Refs #1965.

#1965 Stage 2b (эпик #1953) — **ядро запроса**: крутишь этажность/секции в 3D → ТЭП и NPV/IRR пересчитываются вживую. Фронт-онли, без contract-изменений (хук бьёт уже-задеплоенный `/concepts/recompute`). code-reviewer ✅ APPROVE. ## Что - `useRecomputeMassing()` (concept-api) — TanStack mutation на `POST /concepts/recompute`. - `MassingScene.onModelChange?(model)` — колбэк по смене этажности/секций (НЕ по солнцу); no-op без пропа → /ptica-кокпит/preview/дроверы не задеты (regression-safe, проверено по всем 3 консьюмерам). - `MassingEconomics.tsx` — light KPI-полоса: ТЭП (GFA, продаваемая, квартиры, КСИТ факт/цель) + финмодель (выручка, себестоимость, прибыль, ROI, NPV, IRR, цена). Debounce 250мс + latest-wins (monotonic reqId дропает устаревшие success И failure), last-good при ошибке, skeleton на первом расчёте. - В «7. Концепция»: lazy `MassingViewer` (`dynamic ssr:false`, Three.js) + полоса экономики в 2 колонки. ## Маппинг computeModel → MassingProgram footprint/floors/sections из `computeModel`; site_area ← `polygonAreaSqm`; КСИТ ← `coerceFloat(nspd_zoning.max_far)` (fallback 3.5); class/type/цена/source ← `financial_estimate.*` (price_source пробрасывается — честный флаг); land ← `egrn.cadastral_value_rub`; centroid-WKT для DB-fallback. КСИТ-over-cap флагается (farActual>maxFar). ## Качество - tsc clean; next lint clean; prettier 3.9.0 clean. Без backend/миграций. Edge: нет полигона/financial_estimate=null → graceful (полоса скрыта/деградирует, без краша). Reviewer: regression-safety по 3 консьюмерам + latest-wins проверены. Закрывает ядро #1965 (Stage 1 консолидация + Stage 2 живой пересчёт). Остаётся опц. Stage 3 (каталог типовых домов: ConceptInput.building_program). Refs #1965.
bot-backend added 1 commit 2026-06-27 20:08:03 +00:00
feat(concept): live 3D massing → financial recompute in «7. Концепция» (#1965 Stage 2b)
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 1m1s
CI / openapi-codegen-check (pull_request) Successful in 1m54s
a0232e22f1
Wire the interactive 3D massing to a LIVE financial recompute inside the
Section «7. Концепция» of the light analysis report (epic #1953).

- concept-api.ts: add MassingProgram / MassingRecomputeOutput contracts +
  useRecomputeMassing() (POST /api/v1/concepts/recompute via shared apiFetch),
  and polygonCentroidWkt() helper for the DB-price fallback hint.
- MassingScene.tsx: export MassingModel + add optional onModelChange prop fired
  on the initial build and every floors/sections change (NOT on the sun/hour
  slider). No-op when absent — /ptica cockpit + preview/drawer unchanged.
- MassingEconomics.tsx (new): light-token KPI strip rendering recomputed ТЭП
  (GFA, продаваемая, квартиры, КСИТ факт/цель) + финмодель (выручка,
  себестоимость, прибыль, ROI, NPV, IRR, цена). Debounced ~250ms, latest-wins
  via monotonic request id, last-good values + subtle note on error, grey-fade
  skeleton on first load, КСИТ over-cap flag.
- Section7Concept.tsx: mount lazy MassingViewer (dynamic ssr:false) + the
  economics strip; map computeModel → MassingProgram (footprint/floors/sections
  ← model; site area ← polygon; class/type ← financial_estimate inferred,
  fallback comfort/mid_rise; land ← egrn cadastral; price/source ←
  financial_estimate; КСИТ-цель ← coerced nspd_zoning.max_far, fallback 3.5).
bot-backend merged commit 5b4c0dd1b2 into main 2026-06-27 20:10:42 +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#2026
No description provided.