feat(listings): card_hash column + snapshot-dedup on unchanged cards #1767
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#1767
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/listings-card-hash"
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?
What
Adds
listings.card_hash(migration128) — a SHA-256 of the volatile SERP-card fields (price_rub, area_m2, floor, total_floors, rooms, address, photo-count), computed and stored on every scrape. Uses it to skip the redundant per-daylistings_snapshotswrite when a listing's card is unchanged and a snapshot for today already exists.Why / scope honesty
This does not skip the
listingsUPDATE itself —last_seen_at/is_activemust be bumped on every sighting (10-day delisting TTL), and any row touch rewrites the tuple under MVCC, so there's no perf win there. The genuine win is dropping the redundant daily snapshot write. The larger purpose is laying thecard_hashfoundation for C2 (gating periodic detail-refresh on card change).last_seen_at/is_activeand theinserted/updatedcounters are unchanged. Snapshot is still written on: fresh insert, changed card, or unchanged-card-but-no-snapshot-today.Implementation
ScrapedLot.compute_card_hash()— deterministic, fixed field order, normalized address, no dict-order dependence.save_listings—card_hashadded to INSERT +ON CONFLICT DO UPDATE. A lightweightSELECT card_hash WHERE dedup_hash=:deduppre-read captures the prior hash; snapshot skipped only whenprior == newAND a today-row exists.Tests
tests/test_base_save_listings.py(+~311): hash determinism + sensitivity (price/area/floor/total_floors/rooms/address/photo-count), address normalization, stability when only timestamps/detail fields change; save_listings stores card_hash on insert+update, pre-read occurs, snapshot skipped when unchanged+today-exists, written on change/fresh/no-today-snapshot. 43 passed. Ruff clean. (Pre-existingB011/psycopg2issues in unrelated modules noted, not from this change.)