fix(#112): competitors avg_price_per_m2 всегда None — убран WHERE status='sold' #228
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#228
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/issue112-sold-filter-avg-price"
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?
Проблема
avg_price_per_m2возвращалnullдля всех конкурентов. Баг из Issue #227.Root cause
_AVG_PRICE_SQLфильтровалAND f.status = 'sold', ноdomrf_kn_flats.statusзаполнен только в ~0.2% строк →AVG(price_per_m2)всегда NULL.Fix
Убран фильтр
AND f.status = 'sold'.AVGтеперь по всем квартирам сprice_per_m2 IS NOT NULL— корректно для средней цены ЖК.Changes
backend/app/services/site_finder/competitors.py— remove broken status filter, add commentbackend/tests/api/v1/test_parcel_competitors.py— addtest_competitors_avg_price_populatedregression testAcceptance
avg_price_per_m2не None на реальном кадастре после merge (qa-tester проверит curl)uv run pytest backend/tests/api/v1/test_parcel_competitors.pyDeep Code Review — verdict APPROVE
Severity: APPROVE (no critical / high / medium issues)
Files reviewed: 2 (P1: competitors.py, P3: test_parcel_competitors.py) — +33/-2
Head SHA:
31581ce(стабилен, fixup'ов не было)Что проверено
AND f.status = 'sold'. Фильтрf.price_per_m2 IS NOT NULLсохранён,GROUP BY/ запятые целы. Чисто._AVG_PRICE_SQL— 3 строки + ссылка на Issue #112/227. Защита от регрессии: будущий разработчик не вернёт фильтр обратно.CAST(:x AS type)соблюдён везде в_COMPETITORS_SQL; bind:obj_ids+ANY(...)без::cast trap.grep ':[a-z_]+::[a-z]'пуст.test_competitors_avg_price_populated: mock-based (консистентно с docstring файла line 4), assertpytest.approx(150_000.0), explicit message про регрессию #227. Регрессионный — fails если кто-то вернётstatus='sold'(запрос вернёт пустой result map →avg_price_per_m2=None).frontend/src/types/site-finder.ts:305ужеnumber | null→ contract не меняется.SuccessRecommendationBlock.tsx:171черезformatPrice— null-safe. Frontend изменений не нужно.fixes/Fix_Competitors_Sold_Filter_May16.mdсоздан, ссылается наforgejo_issue: 227. Соблюдён CLAUDE.md rule #6.f3d85f4(Issue #112 backend), без промежуточных правок — это первая корректировка, не повтор ошибки.Data semantic note (не блокирует, на будущее)
После фикса
avg_price_per_m2= AVG по всемdomrf_kn_flatsсprice_per_m2 IS NOT NULL— включает активные объявления + любые статусы. Семантически это «средняя цена м² в ЖК», а не «средняя цена продажи». Текущее имя поля нейтральное (avg_price_per_m2, неavg_sold_price_per_m2) — UI tooltip / label не нужно менять. Если в будущем появится отдельная метрика «средняя цена закрытых сделок» (когдаstatusбудет надёжно заполнено) — она будет новым полем, не переименованием.Carryover (отдельным PR, scope этого фикса не расширять)
backend/tests/integration/test_phantom_columns.py:294-307—test_avg_price_sold_queryвсё ещё EXPLAIN'ит SQL сAND f.status = 'sold'. Тест проходит (EXPLAIN валиден), но имя и тело не отражают актуальный production-запрос. Документационный drift — можно обновить отдельным chore PR.Risk / blast radius
avg_price_per_m2для немногих ЖК с очень редкими ценами окажется чуть менее точным (что лучше чем гарантированныйnull).Approved. Мержу через
merge_pull_request(style:merge).Merged via deep-code-reviewer — verdict APPROVE. Merge commit
e7a5ba8.QA-tester должен проверить на проде:
curl POST /api/v1/parcels/{cad_num}/competitors→competitors[].avg_price_per_m2не null для ЖК с реальными ценами вdomrf_kn_flats.