Зеркало #3216 для Site Finder. Отдельным PR, чтобы CI двух приложений не
блокировали друг друга.
Мажор ради GHSA-5xrq-8626-4rwp (CRITICAL, vitest ≤2.x). Сам CRITICAL к нам
неприменим — он про `--ui`, а `@vitest/ui` не установлен и скриптов с `--ui`
нет — но держать заведомо непатченный рантайм тестов ради этого рассуждения
не стоит.
vitest тянет vite сам, и у мажора другой диапазон (2.1.9 → vite ^5.0.0;
3.2.7 → ^5||^6||^7), поэтому одним мажором:
vitest 2.1.9 → 3.2.7 GHSA-5xrq-8626-4rwp
vite 5.4.21 → 7.3.6 GHSA-4w7w-66w2-5vf9, GHSA-fx2h-pf6j-xcff, GHSA-v6wh-96g9-6wx3
esbuild 0.21.5 → 0.28.2 GHSA-67mh-4wv8-2f99
OSV по локу: 4 → 1. Остаток — postcss 8.4.31, вендоренный ВНУТРИ
next/node_modules; нашим локом не управляется.
@vitejs/plugin-react 4.3.4 → 5.2.0 — вынужденно: у 4.x peer на vite ^4||^5||^6,
семёрка туда не попадает. В 6.x не идём — там peer уже ^8.0.0.
vitest.config.ts не тронут: в нём нет ничего из переименованного/убранного
мажором (ни environmentMatchGlobs, ни deps.inline, ни workspace).
Приёмка (локально, node 26):
npm run test 278 passed, 13 failed
npm run type-check ok
13 падений — те же самые, что на vitest 2 (те же 4 файла: api, useParcelAnalyzeQuery,
AnalysisPageContent.weights, WeightProfilePanel.identity; TypeError на
src/lib/sessionId.ts:8, localStorage undefined). Мажор их не добавил и не убрал.
Причина локальная — node 26 против node 20/24 в CI. Гейт — CI.
openapi-codegen-check был RED на каждом PR: CI шаг гонял bare `npx prettier`
(резолвится в плавающий latest), а committed api-types.ts был отформатирован
старым prettier (≤3.6.2, union-типы multi-line). 3.9.0 переносит union-wrapping
на single-line → CI-регенерация всегда давала diff → gate падал.
Чиним детерминизмом одной версии на обоих путях:
- frontend/package.json: добавлен prettier@3.9.0 (exact) в devDependencies
+ обновлён package-lock.json.
- CI openapi-codegen-check: bare `npx prettier` → ./node_modules/.bin/prettier
(project-local pinned, не плавает).
- .pre-commit-config.yaml: prettier hook additional_dependencies=["prettier@3.9.0"]
— тот же движок, что в CI (alpha.8-обёртка байт-в-байт == prettier 3.9.0).
- api-types.ts перегенерирован prettier 3.9.0 (union-типы single-line).
Backend OpenAPI-схема не менялась — только формат. CI-регенерация теперь
байт-в-байт совпадает с committed-файлом и с выводом pre-commit hook.
Port the prototype massing.js to a client-only React component (MassingScene)
behind a dynamic(ssr:false) wrapper (MassingViewer), wired into the future3d +
insolation drawers, replacing the СКОРО SoonCards.
Generative mass from parcel area (real geometry_suitability.area_ha) × КСИТ-цель
3.5 (labelled regulation-default · НСПД — honest, real max_far not in /analyze),
OrbitControls (orbit/zoom/auto-rotate), time-of-day sun with shadows (insolation
preview), live GFA/КСИТ-факт metrics (green ≤3.5 / amber over). Full renderer/
scene/RAF dispose on drawer close; graceful WebGL-unavailable fallback.
Adds three@0.184.0 + @types/three (package.json + package-lock.json in sync).
SSR-isolated (three imported only in MassingScene). TS strict, no any.
Wire analysis/[cad]/page.tsx: replace SidebarPlaceholder with
AnalysisSidebar (sticky, IntersectionObserver scrollspy on sections
1/2/3/3.1/3.2/3.3/4/5), header with AnalysisBreadcrumb (SiteFinder
→ cad → Анализ) and UserAvatar (gd_org_id from localStorage, SSR-safe).
Add lucide-react to package.json (was used in A1 but missing from deps).
3 pages (market, PRINZIP drilldown, developers leaderboard) on top of
existing v_developer_full_metrics + domrf_realization views. ECharts on
the frontend, FastAPI router /api/v1/analytics on the backend.