b5f8f7b437
feat(report): §7 открыт по умолчанию + выделение участка на подложке + шире карта ( #2179 ) ( #2183 )
Deploy / deploy (push) Blocked by required conditions
Deploy / build-backend (push) Has been skipped
Deploy / changes (push) Successful in 6s
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Has been cancelled
2026-07-02 17:52:21 +00:00
daf4ebefc2
feat(concept): 3D-масса корпусов на карте с тенями (§7) ( #1953 ) ( #2109 )
Deploy / deploy (push) Successful in 1m14s
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 3m35s
2026-06-30 11:58:47 +00:00
6adba229f0
fix(site-finder): wire encumbrance/obj_class/ЗОУИТ display + forecast axis & flat-state ( #1953 )
...
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 51s
CI / openapi-codegen-check (pull_request) Successful in 1m45s
Four frontend display fixes for the Site Finder analysis report (audit #1953 );
all consume fields the (already-deployed) backend now returns.
- #1954 : ЕГРН «Обременения» row was hardcoded «—». Wire top-level
`encumbrance` block {has_zouit, zouit_count, zouit_types} via
formatEncumbrance → «ЗОУИТ: N (types)» / «не выявлено (НСПД)».
- #1955 : show obj_class per success bucket («Студии 15-30 · Комфорт») so
rows with identical area-labels are distinct; fix top-row match + React key
to (bucket, obj_class).
- #1957 : NspdZouitOverlapsBlock renders human type_zone + reg_numb_border,
adds a СЗЗ caveat banner (СанПиН 2.2.1/2.1.1.1200-03) and «СЗЗ вашего
участка» highlight; switched raw hex to UI tokens.
- #1958 : ForecastChart axis names → nameLocation:middle + nameGap (no legend
overlap); grey flat-state callout when the deficit line is degenerate
(scenarios_collapsed or all points clamped at ±1).
Tests: formatEncumbrance + isDeficitDegenerate (15 new). Real segment
differentiation is backend #1959 (separate).
2026-06-27 16:51:40 +05:00
16e505326d
perf(site-finder): honour AbortSignal в poll-цикле useParcelAnalyzeQuery ( #1248 )
...
Deploy / deploy (push) Blocked by required conditions
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Has been cancelled
queryFn игнорировал TanStack v5 AbortSignal: first POST /analyze, poll GET
/fetch-status и re-POST не передавали signal, цикл спал на non-abortable
setTimeout без проверки signal.aborted. При unmount / смене cad|horizon цикл
жил до 2-мин кэпа, дёргая GET /fetch-status каждые 2с + POST /analyze на каждый
ready — зомби-поллинг. Проброс signal во все 3 fetch, sleep через shared
abortableSleep (extracted из useSiteAnalysis #1242 ), throw AbortError перед
итерацией. +3 vitest (abort + happy-path).
Closes #1248
2026-06-13 13:19:50 +00:00
03e5d07907
fix(site-finder): adapt backend egrn_block → frontend ParcelEgrn ( #1217 )
...
Deploy / deploy (push) Blocked by required conditions
Deploy / build-worker (push) Has been skipped
Deploy / changes (push) Successful in 7s
Deploy / build-backend (push) Has been skipped
Deploy / build-frontend (push) Has been cancelled
Бэкенд /analyze отдаёт egrn_block c snake_case-ключами
permitted_use_text/land_category/ownership_type/parcel_status/
last_egrn_update_date (parcels.py:2151-2171), фронт ждёт ParcelEgrn с
vri/category/owner_type/status/last_updated (site-finder-api.ts:255).
Section1ParcelInfo делал `data.egrn as ParcelEgrn` — каст глушит TS;
6 из 10 строк таблицы ЕГРН в prod пустые. ExportButtons тем же кастом
писал пустые ячейки в CSV. egrn={} (truthy) глушил buildFallbackEgrn.
Mock-фикстура была в старой фронт-форме — маскировала баг в dev.
Patch:
- `adaptEgrn(raw, cad)` в site-finder-api.ts: маппит backend-ключи →
frontend, пустой `{}` → null. Тестируется в изоляции.
- AnalyzeResponse.egrn: ParcelEgrn|null → unknown (wire-shape).
- Section1ParcelInfo: `adaptEgrn(data.egrn, cad) ?? buildFallbackEgrn(cad)`.
- ExportButtons: пропс `egrn` (адаптированный) вместо bad-cast'а.
- mock parcel-analyze.json — на реальную backend-форму.
- 7 vitest-кейсов: backend→frontend mapping, {}→null, null/scalar→null,
partial nullable→em-dash, threading cad, пустые строки=missing.
80/80 frontend тестов зелёные. tsc + lint clean.
Closes #1217
2026-06-13 05:36:52 +00:00
9a2cf32787
fix(api): handle 204 No Content в apiFetch ( #1219 )
...
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / deploy (push) Blocked by required conditions
Deploy / changes (push) Successful in 7s
Deploy / build-frontend (push) Has been cancelled
apiFetch безусловно звал response.json() после !response.ok-check, что
падало SyntaxError'ом на пустом теле 204. DELETE /custom-pois/{id} и
DELETE /admin/site-finder/weight-profiles/{id} объявлены status_code=204
→ mutation promise реджектился → onSuccess/invalidateQueries не срабатывали
→ POI/профиль виден в UI до случайного рефетча, хотя реально удалён на
сервере. Silent fail для DELETE кастомных POI на SiteMap (#1219 , P2).
Fix: на 204 или пустом теле resolve'имся с undefined (аналог семантики
apiFetchWithStatus). Сигнатура Promise<T> сохранена — 80 не-204 callers
backward-compatible; два DELETE-хука уже типизированы <unknown>/<void>
и корректно игнорируют возврат.
6 новых vitest кейсов (api.test.ts): 204, empty-body-200, 200+JSON, 404,
500, regression guard. 73/73 frontend тестов зелёные, lint+tsc clean.
Closes #1219
2026-06-13 05:13:44 +00:00
df9d54b532
feat(site-finder): add opportunity-ЗУ + red-line map layers (§12.1-13, #958 )
...
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Has been skipped
Deploy / build-frontend (push) Successful in 2m40s
Deploy / build-worker (push) Has been skipped
Deploy / deploy (push) Successful in 1m4s
Render the §12.1-13 geometry already exposed on /analyze but previously
dropped by the MiniMap adapter:
- Перспективные ЗУ (nspd_opportunity_parcels.geom_wkt) — viz-3 polygons
- Красные линии застройки (nspd_red_lines.geom_wkt) — warn dashed lines
Wired as toggles in the existing CpLayerControlPanel (Рынок group),
reusing wkt.ts (extended with LINESTRING/MULTILINESTRING for red lines).
Empty/invalid geometry renders nothing gracefully; popups RU plain-text.
§22 forecast (future_market/special_indices), ППТ-ПМТ planning polygons
and future-ЖК points carry no map-able geometry on the frontend yet — left
as backend follow-ups, not faked.
Refs #958
2026-06-09 07:19:53 +00:00
cdb6035e39
chore(frontend): add vitest runner + WKT parser unit tests
...
CI / changes (push) Successful in 6s
CI / backend-tests (push) Has been skipped
Deploy / deploy (push) Blocked by required conditions
CI / changes (pull_request) Successful in 5s
CI / backend-tests (pull_request) Has been skipped
Deploy / changes (push) Successful in 6s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Has been cancelled
- Wire vitest (jsdom, globals, @ alias->src, jest-dom matchers); add
test / test:watch scripts and dev deps (vitest 2.1, @vitejs/plugin-react,
jsdom, @testing-library/{react,dom,jest-dom,user-event}); regen lockfile
(both package.json + package-lock.json, alpine-musl binaries verified).
- Revive 4 orphaned tests: jest.fn->vi.fn (Drawer); fix outdated subtitle
DOM assertion (HeadlineBar); drop stale jest setup comments.
- Extract WKT->GeoJSON parser (wktToGeometry/splitTopLevel/parseRing) from
MarketLayers into src/lib/wkt.ts (pure, behavior-preserving refactor) +
add EWKT SRID-prefix tolerance; cover with src/lib/__tests__/wkt.test.ts
(16 cases incl. lon/lat order, holes, multipolygon, EWKT, garbage->null).
57 tests green; type-check green; build green. CI wiring is a devops follow-up.
Refs #999 .
2026-06-07 16:46:27 +05:00
c08e4d7811
feat(rbac): pilot scope → только /trade-in/** ( #587 )
...
Deploy Trade-In / changes (push) Successful in 6s
Deploy / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 26s
Deploy / build-backend (push) Successful in 28s
Deploy / build-worker (push) Successful in 28s
Deploy / build-frontend (push) Successful in 27s
Deploy Trade-In / deploy (push) Successful in 36s
Deploy / deploy (push) Successful in 55s
Decision 2026-05-26: pilot не видит landing/analytics/site-finder/concept, только Trade-In.
2026-05-26 07:40:44 +00:00
7a2b055b35
feat(rbac): frontend route-guard + nav filter ( #586 )
...
Deploy / changes (push) Successful in 5s
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 1m42s
Deploy Trade-In / deploy (push) Successful in 39s
Deploy / build-frontend (push) Successful in 2m55s
Deploy / deploy (push) Successful in 1m1s
PR B (frontend) to backend RBAC #585 . RouteGuard wraps app, NoAccessScreen on 403 from /me, TopNav filtered by role.
2026-05-26 06:51:45 +00:00