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

1 commit

Author SHA1 Message Date
a0232e22f1 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
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).
2026-06-28 01:01:53 +05:00