feat(tradein): cian price-change badges + split chart Avito/Yandex #547
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#547
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/tradein-multi-source-v2"
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?
Контекст
Продолжение #546 (уже смержён). Добавляет 2 блока аналитики из live данных.
A. Cian price-change badges
Использует offer_price_history (268+ rows, активно льёт cian playwright_history).
GET /api/v1/trade-in/estimate/{id}/cian-price-changes— per-analog stats (n_changes, last_diff_pct, total_change_pct).B. Split PriceHistoryChart
Использует house_placement_history.source column (avito_imv + yandex_valuation, 15k+ rows).
source, SQLGROUP BY year, source.НЕ сделано из плана
Test plan
Backend: - New GET /api/v1/trade-in/estimate/{id}/cian-price-changes — per-analog price change stats (n_changes, last_diff_pct, total_change_pct) из offer_price_history (cian playwright_history backfill, 268+ rows). - house-analytics: PriceHistoryYearPoint gains source field; SQL теперь GROUP BY year, source → 2 серии для chart (avito_imv / yandex_valuation). Frontend: - ListingsCard показывает colored badge ↓N ±X.X% рядом с ценой cian-аналога если есть price changes (зелёный = снижение, красный = рост). - PriceHistoryChart: pivot long→wide format client-side, 2 Line components (синий Avito #2563eb, оранжевый Яндекс #ea580c) + Legend, connectNulls. Использует данные: - offer_price_history (live cian price changes) - house_placement_history.source разделение avito_imv vs yandex_valuationDeep Code Review — verdict
Summary
07cbcd2Strengths
GET /estimate/{id}/cian-price-changesis properly parameterized:CAST(:eid AS uuid)+ named bindings — no injection vector.\d+) and JS literal — both correct.listings.source_idistext, Cian ID kept asstr/stringthroughout — no coercion traps).safeUrlstill wraps external links.oph_listing_time_idx (listing_id, change_time DESC)covers MAX + ORDER BY LIMIT 1 + GROUP BY.enabled: estimate_id !== null && estimate_id.length > 0on TanStack query prevents premature fetch.last_diff_percent > 0 ? '+' : ''+.toFixed(1)produces single-5.0%for negatives.connectNullsbridges sparse year coverage; pivoted data keyed by year is stable.(year, source)withORDER BY year ASC, source ASC— deterministic.Cross-file impact
PriceHistoryYearPointadds requiredsourcefield — only callers are this endpoint +PriceHistoryChart; pivot absorbs new shape; no other grepped consumers.ListingsCardpropestimateId?: stringis optional — backward compatible.HouseAnalyticsSectionrendering unchanged.offer_price_history,listings,trade_in_estimates).Nit-level (non-blocking)
avito_imv/yandex_valuationsources.house_placement_history.sourcealso allowsavito/avito_widget(sql/017 + sql/032 + scrapers). If those rows exist for a house, chart lines won't show them, buttotalLots = points.reduce(...)(PriceHistoryChart.tsx:43) still sums theirn_lotsin the caption — slight count/visual mismatch. In practice avito_widget data is rare per current session state; consider anelsebranch or filtering totalLots to known sources.last_diff_percent < 0 ? green : red→ exactly0falls into red. Realistically unobservable;<= 0or neutral branch would be defensible.changes_aggforfirst_seen_pricecould befirst_value(price_rub) OVER (PARTITION BY listing_id ORDER BY change_time ASC). At small N (~5-20 Cian analogs per estimate) cost is negligible.Tests
No unit tests added. Endpoint is read-only and behaviour is smoke-testable via UI badge. Consistent with peer endpoints (
/imv-benchmark,/house-analytics). Not a blocker.Verdict
Approve and merge. Clean cross-domain change, no regressions in the existing chart/listings card.