fix(tradein): geocode backfill + remove Avito exclusion from estimator #490
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#490
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "feat/tradein-geocode-missing-cron"
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
После C-5 fix (PR #487) Avito coords либо
NULLлибо реальные. Estimator исключалsource='avito'из radius search потому что раньше там был jitter (±0.005°) от 5 anchor cron'ов. Сейчас:→ estimator ловит только cian/yandex/n1 = ~30% эффективной базы.
Bundled fix
app/tasks/geocode_missing.py— async callable сGeocodeBackfillResultdataclass. Batch geocoder (Nominatim 1/s или Yandex если key), dedup по address (5 listings одного дома → 1 geocode call → 5 UPDATE).2 admin endpoints:
GET /api/v1/admin/scrape/geocode-missing-listings/status— pending counters per source + estimated timePOST /api/v1/admin/scrape/geocode-missing-listings?batch_size=200&dry_run=false&background=false— manual triggerestimator.py:813— убранAND source <> 'avito'(replaced with updated comment про PR #487).Test plan
tests/tasks/test_geocode_missing.py)GET /admin/scrape/geocode-missing-listings/status→ returns pending countersPOST .../geocode-missing-listings?batch_size=10&dry_run=true→ dry run выводит 10 addressesPOST .../geocode-missing-listings?batch_size=200× 8-12 раз → unique_addresses_pending → 0Expected impact
Notes
/admin/geocode-missing(per-listing) сохранён — coexist с новым (address dedup)?background=trueдля большого batch (избегает HTTP timeout)Reviewer: deep-code-reviewer.
Merged via deep-code-reviewer — verdict APPROVE.
Geocode dedup: correct.
SELECT address, COUNT(*) ... GROUP BY address ORDER BY listings_count DESC LIMIT :limit→ 1 geocode → N UPDATEs WHEREaddress = :addr AND lat IS NULL. Testtest_geocode_missing_dedup_addresses_single_geocode_callподтверждает.Nominatim rate limit: 1 req/sec соблюдён в
geocoder.py:530(await asyncio.sleep(1.0)после success) + line 187 (между typo variants). TOS compliant.Estimator change justified:
AND source <> 'avito'убран; existing safety net —ST_DWithin(geom, ...)отфильтровывает rows с NULL geom (а NULL coords → NULL geom через PostGIS trigger), так что pre-#487 jittered Avito (670 rows) не вызывают новых проблем самим фактом merge — но они появятся в radius search.Merge order: можно мержить независимо от #487 — код forward-compat. Если #487 ещё open, рекомендуется merge first для исторической точности комментария.
Post-merge follow-ups (user action):
UPDATE listings SET lat=NULL, lon=NULL WHERE source='avito' AND scraped_at < '2026-05-23' AND lat IS NOT NULL;→ re-backfillcode/modules/tradein/Geocode_Backfill.md(main session per worker-only-executes rule)Minor non-blocking findings:
admin.py:389duplicatefrom app.core.db import SessionLocalimport (already line 19)background=true + dry_run=true— silent BG dry-run (consider 400 error)UPDATE WHERE address = :addrбез source-filter — implicit cross-source coupling (acceptable, same address = same coords)