feat(velocity): per-room-bucket breakdown in VelocityResult #163
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#163
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/velocity-per-room-breakdown"
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
Adds per-room sales breakdown to velocity API. User feedback: 'поквартирно сколько и каких а не м2'.
Changes (
backend/app/services/site_finder/velocity.py)New SQL query (
bucket_rows) — третий после competitor + sales aggregations:Wrapped в SAVEPOINT (PR #155 pattern); CAST() syntax (PR #160 lesson).
Response shape
velocitygains 2 fields:by_room_bucket: {bucket: {units, sqm, complexes_count}}— aggregatesample_competitors[].by_room_bucket: {bucket: units}— per ЖКTests
3 new (aggregation, empty fallback, sample entries). All pass.
Verified data для test cad
Refs #161
Final review (SHA
fdfe023, CI ✅)Cross-checked агентом — все 6 проверок пройдены, плюс бонусная находка.
✅ SAVEPOINT integrity: новый
bucket_rowsquery wrapped вwith db.begin_nested():с graceful fallback на exception (bucket_rows = [], logger.warning). Pattern matches PR #155.✅ Frontend contract additive only:
as_dict()addsby_room_bucketfield; existing keysobj_id,name,obj_class,distance_m,total_sqm_periodpreserved через**competitor_meta[oid].VelocityBlock.tsxне сломается.✅ SQL syntax clean: использует
CAST(:window_interval AS interval)(PR #160 lesson). Бонус: фиксит lingering::intervalcast в_get_ekb_medianline 375 — PR #160 пропустил это место!✅ 3 новых теста:
test_by_room_bucket_aggregation,test_by_room_bucket_empty_when_no_bucket_data,test_sample_competitors_include_by_room_bucket. Existingtest_as_dict_structureобновлён.✅ CI green (backend + frontend SUCCESS)
Минор (follow-up, не блокер)
🟡 TS types не обновлены:
frontend/src/types/site-finder.ts(Velocity/VelocityCompetitor) не содержитby_room_bucket. Backend-only PR — extra fields в JSON не крашит frontend (TS additive-properties tolerant), но UI не сможет потребить field type-safe до follow-up.🟢 Parking filter sanity check: source
objective_corpus_room_month.room_buckettypically только residential (студия/1/2/3+); если non-residential bucket'ы есть — они leak вby_room_bucket. Worth quick grep distinct values, но likely fine.Рекомендую follow-up
site-finder.tsVelocity + VelocityCompetitor interfaces withby_room_bucketдля type-safe frontend consumptionapprove merge