fix(tradein/data): убрать ложный region_code=66 у объявлений чужих городов (#2604) #2612
No reviewers
Labels
No labels
Fable 5 ревью
GG-форсайт
admin
analytics
auth
automation
bug
business
chore
ci
compliance
data
data-moat
docs
duplicate
dx
enhancement
feedback/max
generative
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#2612
Loading…
Add table
Reference in a new issue
No description provided.
Delete branch "fix/tradein-region-code-foreign-cities"
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
Issue #2604 п.2. 16930 строк
listings(source='avito') несутregion_code = 66(Свердловская обл.), хотяsource_urlуказывает на город вне наших шести (Новосибирск, Казань, Челябинск, Тюмень и ещё ~1600 слагов). Строки — наследие массового заброса 18 июня, до появления гео-фильтра карточек (коммитf0264237, 20 июня). Канал давно закрыт, новых таких строк не поступает.Вреда сейчас нет —
listings.region_codeне читает ни одна живая выборка (только исторические миграции077_*/091_*и комментарий в091_*). Но это мина: любой будущий запрос «всё по региону 66» получит их в выборку.Миграция 200 обнуляет
region_codeу этих строк (SET region_code = NULL— честное «неизвестно», не подставной код другого региона; выводить регион из текста адреса не будем, колонку сегодня никто не читает).Номер миграции: 199 -> 200
Первоначально взял 199 (проверил
git ls-tree forgejo/main— max 197, свободный номер по инструкции задачи). Уже после коммита выяснилось, что параллельный PR #2611 (feat/tradein-asocks-rotation, ещё не смержен) занял оба198_scrape_proxy_rotations.sqlи199_scrape_proxies_asocks_rotate_url.sql— проверил напрямую через Forgejo API (contents?ref=feat/tradein-asocks-rotation), подтвердилось. Перенумеровал в 200, также сверил остальные три открытых PR (feat/mera-b2c-privacymax 193,feat/mera-b2c-antiabusemax 191,feat/mera-b2c-perimeter— Caddyfile/frontend, безdata/sql) — коллизий нет.Замеры (прод, read-only, перед миграцией)
source='avito', slug вне наших 6,region_code IS NOT NULL)is_active = falseregion_code = 66(единственное текущее значение)region_codeужеNULL(не были бы задеты повторно)source_url(слаг не извлёкся)total avito(45472) = 28542 + 16930Все
source_urlна проде имеют формуhttps://www.avito.ru/<slug>/...— regex-идиом (тот же, что в 197) не захватывает'www'как слаг (проверено явным запросом, 0 строк).Границы:
cian/domklik/yandex/n1не трогаются — ихregion_code=66в основном верен (не заброс-механизм чужого города, а параметрregion=запроса / отсутствие городской привязки в URL). Там нашлось 27 похожих строк по ненадёжному текстовому разбору адреса — сознательно вне scope.Производительность
Триггеры на
listings— column-scoped (listings_price_change_trgнаUPDATE OF price_rub,listings_set_geom_trgнаUPDATE OF lat, lon) — UPDATE только поregion_codeих не пробуждает. Ноtsv(GENERATED ALWAYS ... STORED) пересчитывается на каждом UPDATE независимо от изменённых колонок.EXPLAIN(безANALYZE— план, без исполнения) показываетBitmap Heap Scanпоlistings_source_idx(source='avito') — тот же путь доступа, что и в 197. 197 обновила 27706 строк с тем же tsv recalculation за 4.1с; здесь строк меньше (16930, ~61% от 27706) -> ожидаемая длительность ~2.5-3с. Никакого DDL, GIST/geom не затронуты.Идемпотентность
AND region_code IS NOT NULL— повторный прогон находит 0 строк, UPDATE становится no-op.Test plan
tests/test_migration_200_region_code_foreign_cities.py— 15/15 passed (статические guard'ы: транзакционность, idempotency-guard, ровно 6 защищённых слагов, kamensk-дефис/pyshma-без-k против внутренних ключей, сверка сCITY_LOCATIONSвpipeline.py, отсутствие substring-коллизий между слагами, точный сегмент пути (неLIKE), без DDL, без psycopg:x::typeловушки)uv run pytest -qвtradein-mvp/backend: 3026 passed, 9 skipped, 1 known pre-existing fail (test_search_api.py::test_search_cache_hit, 401 RBAC, не связан с этим PR)ruff check+ruff format --checkна новом тестовом файле — чистоRefs #2604