feat(tradein): вся Свердловская область — 40 городов в city-sweep #2879

Merged
lekss361 merged 2 commits from feat/tradein-oblast-full into main 2026-08-13 19:08:45 +00:00

2 commits

Author SHA1 Message Date
bot-backend
609768a3bd fix(tradein/sql): окно 23→0 вместо 23→24 — миграция не применялась
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 9s
CI Trade-In / browser-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Successful in 4m21s
CI поймал то, что статические проверки пропустили: пять строк получили
window_start_hour=23, window_end_hour=24, а констрейнт из 052_ требует
BETWEEN 0 AND 23. Весь INSERT падал, миграция не применялась.

Час 23 заворачивается в 0 — планировщик поддерживает окна через полночь
явно (window_end_hour <= window_start_hour → cross-midnight).

Тест test_migration_262_windows_are_one_hour и пропустил ошибку: он
требовал end == start + 1, что для 23 даёт ровно 24. Теперь сверяет
(start + 1) % 24, плюс отдельная проверка на диапазон 0..23 — то есть
на то самое условие прод-констрейнта.

Проверено сухим прогоном на боевой схеме: BEGIN → миграция → ROLLBACK,
psql exit 0, число строк не изменилось.
2026-08-13 22:01:49 +03:00
bot-backend
76116f8869 feat(tradein): вся Свердловская область — 40 городов в city-sweep
Some checks failed
CI Trade-In / changes (pull_request) Successful in 7s
CI / changes (pull_request) Successful in 9s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI Trade-In / backend-tests (pull_request) Failing after 50s
Покрытие было 6 городов: по области 3229 объявлений против 20111 по ЕКБ.
Заводим оставшиеся 40 городов области.

Координаты и идентификаторы площадок добыты, а не выведены по правилу.
Каждый метод сначала прогонялся на 5 городах с уже известными значениями и
только после точного воспроизведения применялся к новым:
- координаты — прод-геокодер, сверка с медианой сделок Росреестра по городу
- cian_id — geo-suggest, фильтр по «Свердловская область» (тёзки реальны:
  Ревда в Мурманской, Заречный в Пензенской)
- yandex_rgid — region_suggest, дизамбигуация по label
- avito_slug — живой запрос страницы города; контроль: заведомо ложные
  варианты дают чистый 404, то есть метод различает, а не угадывает

Сверка поймала три ошибки, которые иначе уехали бы в прод:
- Заречный: геокодер вернул микрорайон ВНУТРИ Екатеринбурга (обратное
  геокодирование: «улица Софьи Перовской, Екатеринбург»)
- Сысерть: промах на ~23 км
- Бисерть: у Циана её нет, поиск отдаёт Сысерть — исключена целиком (пгт,
  а не город области)

Строки заводятся ТОЛЬКО там, где идентификатор подтверждён: cian 40,
yandex 39 (нет Михайловска — его нет в гео-базе Яндекса вовсе), avito 23.
Итого 102 строки. Развёртка с неподтверждённым идентификатором молча
собирала бы Екатеринбург под меткой другого города — это хуже отсутствия.

- CityLocation: avito_slug/yandex_rgid стали Optional, cian_region_id
  остался обязательным как единственный подтверждённый у всех
- явный ValueError до любого I/O, если город есть в CITY_LOCATIONS без
  идентификатора: _city_seg() иначе откатывается на "ekaterinburg"
- CITY_DISPLAY_NAMES на 40 городов, иначе listings.city = «Екатеринбург»
- попутно: _OBLAST_AVITO_URL_PATTERNS падала на импорте при avito_slug=None

Все 102 строки выключены — включение волнами, вручную.
2026-08-13 21:48:31 +03:00