feat(parcels): layout signature schemas + extractor (#113 PR A) #193
No reviewers
Labels
No labels
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
Fable 5 ревью
feedback/max
generative
GG-форсайт
needs-discussion
needs-human
observability
pause-bots
performance
priority/p0
priority/p1
priority/p2
priority/p3
scope/backend
scope/db
scope/devops
scope/frontend
scope/qa
scrapers
security
site-finder
stage/1
stage/2
status/blocked
status/done
status/needs-analysis
status/needs-fix
status/qa
status/ready
status/review
status/wip
tech-debt
tradein
ux
week ревью 1
wontfix
вторичка
ИРД
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: lekss361/gendesign#193
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/113-layout-signature-schemas"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Foundation PR (A из 4) для Issue #113 «Layout Analysis → ТЗ на проектирование» (Макс Phase 2 after #112).
Phase 2.1 minimal: layout signature =
(room_bucket × area_bin)= 5×6 = 30 классов.layout_type(евро/классика) иbalcony_countотсутствуют вdomrf_kn_flats— ждут B2B Объектив (#52, отдельный issue).Что в этом PR
backend/app/schemas/parcel.py:LayoutSignature,BestLayoutsRequest,TopLayoutRow,LayoutTzMixRow,LayoutTzRecommendation,LayoutDataQuality,BestLayoutsResponsebackend/app/services/site_finder/layout_signature.py(NEW, 56 LOC, no DB) — 3 pure-Python helpers:room_bucket_from_flat(rooms, flat_type, is_studio) → "studio"|"1"|"2"|"3"|"4+"area_bin(area_m2) → "<25"|"25-40"|"40-60"|"60-80"|"80-100"|"100+"layout_signature(room_bucket, area_bin) → "1__25-40"(deterministic)backend/tests/test_layout_signature.py(parametrized — studio detection, edge boundaries, fallbacks)Что НЕ в этом PR (sequenced)
feat/113-mv-layout-velocity(database-expert) —data/sql/94_mv_layout_velocity.sqlmaterialized viewfeat/113-best-layouts-endpoint(backend-engineer) —POST /api/v1/parcels/{cad_num}/best-layoutsfeat/113-pdf-tz-and-ui(backend + frontend) — WeasyPrint PDF ТЗ +BestLayoutsBlock.tsxCarryover bug to flag (НЕ в скоупе этого PR)
backend/app/services/site_finder/competitors.py:138— фильтрWHERE f.status = 'sold'всегда возвращает 0 (поле 99.8% NULL на проде вdomrf_kn_flats).avg_price_per_m2в Competitor never works. PR C будет использоватьobjective_corpus_room_monthвместо. Follow-up issue для фикса #112 рекомендуется.Test plan
cd backend && uv run pytest tests/test_layout_signature.py -v→ 27/27 passcd backend && uv run pytest tests/api/v1/test_parcel_competitors.py tests/api/v1/test_parcel_connection_points.py -q→ 16/16 pass (no regression)cd backend && uv run ruff check app/services/site_finder/layout_signature.py app/schemas/parcel.py→ cleancd backend && uv run ruff format --check app/services/site_finder/layout_signature.py→ cleanCloses part of #113 (full close after PR B/C/D).
Auto-review (SHA
0e2d976f) — verdict: approve ✅Foundation PR (1 of 4 для Issue #113). Pure-Python additions, zero DB/SQL/auth surface.
Verified
room_bucket_from_flat,area_bin,layout_signature) — deterministic, без side effectsMinor (non-blocking, можно fix потом)
layout_signature.py:31—return str(rooms) # type: ignore[return-value]acknowledges Literal narrowing issue. Альтернатива:cast(RoomBucket, str(rooms))илиmatch rooms: case 1 | 2 | 3: return ...— но это nit, не блокер.competitors.py:138 status='sold'всегда 0) — follow-up issue рекомендуется отдельно.Merge
CI: 0 checks total (workflow или ещё не запустился, или не триггерится для этого PR type). Per rule v3 (auto-merge при approve + ci ∈ {success, none}) → squash merge after this comment.