fix(sf-05): clamp sold_pct_of_supply на 100% + is_oversold flag #274
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#274
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/sf-05-sold-pct-normalize"
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
SF FixList #5 —
sold_pctclamp 100% + warning flag.sold_pct = sum_deals_24mo / supply_count_snapshot * 100использует несопоставимые окна (24 мес сделок vs текущий snapshot supply) → значения >100% (например 199%) для активно продаваемых маленьких форматов.Изменения
backend/app/services/site_finder/best_layouts.py:349:sold_pct = min(round(raw, 1), 100.0)— clamp на 100%is_oversold: bool=raw > 100(UI показывает warning badge)schemas/parcel.py(или соседний) — extended response model.Tests — мок что raw=199 → returned
sold_pct=100,is_oversold=true.Backward compat
sold_pctоставлено как имя — frontend не ломается.is_oversold— opt-in новое поле.Future work (Option B)
Полная нормализация
sum_deals_in_window / avg_supply_in_window— отдельный issue если понадобится (требует rolling avg supply snapshot которого может не быть в схеме).Related: epic #271 item #5 (Wave 1)
Merged via deep-code-reviewer — verdict APPROVE.
Что проверено:
min(raw, 100.0)корректна, no zero division (guardedsupply_count > 0).is_oversold = raw > 100.0— строго>, ровно 100% не флагается. OK.sold_pct_of_supplyимя сохранено;is_oversoldбез default но всегда сериализуется backend'ом.best-layouts.ts).>escaped), CSS tokens из дизайн-системы.fixes/Fix_SF_SoldPct_Clamp_May17.mdуже создан до merge.Bundle bonus (SF-04):
data/sql/103_seed_prinzip_mappings.sql—BEGIN/COMMIT+ON CONFLICT DO NOTHINGidempotent.REFRESH MATERIALIZED VIEW CONCURRENTLY mv_layout_velocityнужно прогнать вручную post-deploy (runbookRefresh_MV_Layout_Velocity.md).Замечания (не блокирующее, follow-up):
Competitorполучилаsite_status/ready_dt(Optional) — это scope из SF-02, не упомянуто в title PR. Бэкенд пока эти поля не заполняет (вернётNone). Нужен follow-up SF-02 PR который заполнит их в SQL competitors query.raw == 100.0 exactlyв тестах не покрыт — low priority.Что проверить после деплоя:
POST /api/v1/parcels/{cad}/best-layoutsна участке с активно-продаваемым маленьким форматом → должен вернутьsold_pct_of_supply=100+is_oversold=true.>100%появляется в колонке sold_pct вBestLayoutsBlock.REFRESH MATERIALIZED VIEW CONCURRENTLY mv_layout_velocityдля подхвата seed mapping'ов.