gendesign/tradein-mvp/backend/app
bot-backend 8fdcd8df62
All checks were successful
CI / changes (pull_request) Successful in 7s
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / frontend-checks (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) Successful in 56s
fix(tradein/geocoder): word-boundary EKB short-circuit + gate suggest() + gazetteer (#11)
Deep-review fast-follows on the non-EKB city gate:

1. Word-boundary the "екатеринбург" short-circuit in _names_non_ekb_city
   (new _EKATERINBURG_RE = \bекатеринбург\b, .search() instead of substring
   `in`). A bare-substring check matched "Екатеринбургское шоссе" (a real
   street in satellite towns like Pervouralsk) as if it named EKB, wrongly
   keeping EKB-only local tiers on for a non-EKB address. Still returns False
   for the existing homonym false-positive test case (word boundary is
   satisfied there — "екатеринбург" appears as a standalone token).

2. Gate suggest()'s Tier 1 (same root cause as geocode()): the EKB-only
   cadastral matchers _cadastral_house_match / _cadastral_forward_sync ran
   unconditionally, so a non-EKB oblast autocomplete query could surface an
   EKB building via street+house collision. Gated behind
   `not _names_non_ekb_city(query)`, mirroring geocode()'s use_local_ekb.
   External suggest tiers (DaData/Yandex/Nominatim) untouched — still the
   path for non-EKB autocomplete.

3. Extended SVERDLOVSK_OBLAST_CITIES with unambiguous, deal-heavy oblast
   cities: алапаевск, сухой лог, кушва, красноуральск, карпинск, нижняя
   тура, верхний тагил, нижние серги. Deliberately did NOT add "лесной"
   (reviewer flagged as reviewer-optional, left to judgment): DB check
   (ekb_geoportal_buildings) confirms a real EKB street named exactly
   "Лесной" (3 buildings) — an exact whole-word collision indistinguishable
   from ЗАТО Лесной by word-boundary matching alone (unlike "Серова"/"Серов",
   which are different word forms). Adding it would misclassify a bare
   EKB address ("Лесной, 5", no "Екатеринбург" mention) as non-EKB.

Tests: word-boundary EKB regression test, suggest() gating test, two new
gazetteer entries (Верхняя Пышма multi-word, Сухой Лог).
2026-07-13 00:06:19 +03:00
..
api refactor(tradein): консолидировать corridor/street-deals city-scope на _resolve_target_city (п.3) 2026-07-12 23:18:02 +03:00
core tech-debt(tradein/estimator): collapse won estimate_* flags into defaults (#1970) (#2475) 2026-07-12 12:46:18 +00:00
observability feat(tradein): enrich GlitchTip SDK init — integrations + PII scrub (#396) (#643) 2026-05-29 09:23:17 +00:00
schemas tech-debt(tradein/estimator): collapse won estimate_* flags into defaults (#1970) (#2475) 2026-07-12 12:46:18 +00:00
services fix(tradein/geocoder): word-boundary EKB short-circuit + gate suggest() + gazetteer (#11) 2026-07-13 00:06:19 +03:00
tasks feat(tradein): монитор свежести СберИндекса (audit п.1) 2026-07-12 23:27:35 +03:00
__init__.py feat: add tradein-mvp subproject (Trade-In Estimator под /trade-in) 2026-05-21 00:25:39 +03:00
main.py fix(tradein/rbac): энфорсить roles.yaml scope на всех non-admin путях (R2 H3) 2026-07-12 22:26:14 +03:00
scheduler_main.py refactor(tradein/scheduler): удалить legacy scheduler_loop + scraper-scheduling, kit единственный путь (#2397 Part C) 2026-07-04 13:00:30 +03:00