feat(tradein/db): derived price-history trigger (avito/yandex) + last_seen_at deactivate index #1559
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#1559
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/price-history-trigger-and-lastseen-index"
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
Two DB migrations closing audit gaps in listings data completeness.
116 — derived price-change trigger →
offer_price_historyThe
listingsupsert (base.py::save_listings,ON CONFLICT … SET price_rub = EXCLUDED.price_rub) overwrites price with no history row. Only cian hadoffer_price_historydata (7125 rows, source-provided from cian'spriceChangesJSON). avito/yandex price changes were silently lost on re-scrape.New
AFTER UPDATE OF price_rubtriggerlistings_price_change_trgrecords a derived history row whenprice_rubactually changes.Critical cian-exclusion:
cian_price_history.py::backfill_cian_price_historyselects cian listings viaLEFT JOIN offer_price_history … WHERE oph.listing_id IS NULL(only listings with zero history rows). A trigger row for a cian listing would permanently exclude it from that backfill, losing the full source-provided timeline. So the trigger fires only forNEW.source <> 'cian'(verified against cian_price_history.py:77).No-ops by design:
deactivate_stale(setsis_active, not price) and geocode backfill (setsgeom) never fire it —AFTER UPDATE OF price_rubisn't even evaluated for them.117 — index for deactivate_stale queries
deactivate_stale_listingsfiltersWHERE source=… AND is_active=true AND last_seen_at < …; there was no supporting index (seq scan ~39k rows). Adds partiallistings_active_source_lastseen_idx (source, last_seen_at) WHERE is_active.Verification (prod, rolled-back transactions)
offer_price_historyrow; UPDATE cian listing price → 0 rows. Proven, then ROLLBACK.EXPLAINof a deactivate-shaped query → Bitmap Index Scan on listings_active_source_lastseen_idx.Test plan
Refs #753