Commit graph

423 commits

Author SHA1 Message Date
bot-backend
8a10d943d7 fix(tradein/scraper-kit): scale cian anchor watchdog for proxy-pool browser fetches (#2160)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 11s
CI / changes (pull_request) Successful in 11s
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 1m51s
Fixed ANCHOR_TIMEOUT_SEC=240 guillotined every cian anchor when running via
USE_PROXY_POOL_BROWSER=true: each SERP fetch goes through camoufox with relaunch
on proxy swap (13-45s/page), and an anchor = 4 room-buckets x pages_per_anchor
SERP fetches + detail_top_n details + houses-enrich >> 240s. save_listings never
ran, lots_fetched=0, and after 3 consecutive skips the run was mark_banned.

Introduces _cian_anchor_timeout_s() mirroring the avito/yandex/domclick scaling
pattern: max(ANCHOR_TIMEOUT_SEC, buckets*pages*(delay+per_serp) + details*per_detail
+ houses_budget). Defaults -> 1580s worst-case watchdog (hang guard, not expected
duration). Applied to both the scraper-kit copy (strangler target) and the active
app.services.scrape_pipeline copy that run 581 actually hit.
2026-07-03 10:05:06 +03:00
bbe596747d Merge pull request 'fix(tradein/data): yandex url-«дубли» — каноникализация URL (скрейпер + миграция 164) + manifest 162 (#2235, #2216)' (#2271) from fix/tradein-yandex-url-dedup into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m38s
Deploy Trade-In / build-backend (push) Successful in 1m44s
Deploy Trade-In / deploy (push) Successful in 3m3s
2026-07-03 06:53:27 +00:00
c44bb49809 Merge pull request 'fix(tradein/data): external_valuations.house_id — резолв в write-path + идемпотентный бэкфилл (#2236)' (#2263) from fix/tradein-extval-house-id into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 19s
Deploy Trade-In / build-frontend (push) Successful in 1m3s
Deploy Trade-In / build-browser (push) Successful in 1m7s
Deploy Trade-In / test (push) Successful in 2m4s
Deploy Trade-In / build-backend (push) Successful in 1m11s
Deploy Trade-In / deploy (push) Successful in 3m20s
2026-07-03 06:40:21 +00:00
bot-backend
33e3503f97 fix(tradein/data): yandex url-дубли — дедуп-миграция + инвариант + корень (#2235) 2026-07-03 09:39:29 +03:00
e1c5f2184c fix(tradein/scraper-kit): wire browser proxy-pool into yandex/cian SERP + persist activation flags (#2160) (#2268)
Some checks failed
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 17s
Deploy Trade-In / build-frontend (push) Successful in 43s
Deploy Trade-In / build-browser (push) Successful in 44s
Deploy Trade-In / test (push) Successful in 1m58s
Deploy Trade-In / build-backend (push) Has been cancelled
2026-07-03 06:36:56 +00:00
5f6db8dbb7 Merge pull request 'fix(tradein/security): admin.py — generic detail + error-id вместо сырого текста исключений (#2234)' (#2261) from fix/tradein-admin-exception-leak into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / test (push) Successful in 2m25s
Deploy Trade-In / build-backend (push) Successful in 1m54s
Deploy Trade-In / deploy (push) Successful in 1m32s
2026-07-03 06:27:22 +00:00
bot-backend
291717fa2f fix(tradein/data): external_valuations.house_id — резолв в write-path + идемпотентный бэкфилл (#2236) 2026-07-03 09:22:44 +03:00
bot-backend
c65a73ca9a fix(tradein/security): admin.py — generic detail + error-id вместо сырого текста исключений (#2234) 2026-07-03 09:16:34 +03:00
bot-backend
edbdd28286 fix(tradein/security): photo-upload — чанковое чтение с капом 10MB + Caddy request_body 12MB (#2233)
All checks were successful
CI Trade-In / changes (pull_request) Successful in 29s
CI / changes (pull_request) Successful in 20s
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 2m16s
2026-07-03 09:06:51 +03:00
9f28092356 fix(tradein/estimator): min-width floor ±12% на ценовой диапазон (#2209) (#2230)
All checks were successful
Deploy Trade-In / test (push) Successful in 1m31s
Deploy Trade-In / changes (push) Successful in 9s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 1m18s
Deploy Trade-In / deploy (push) Successful in 46s
2026-07-02 21:21:28 +00:00
5fb5675871 fix(tradein/security): defense-in-depth trusted-header auth + rate-limiter fix (#2213) (#2229)
All checks were successful
Deploy / changes (push) Successful in 8s
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-browser (push) Successful in 35s
Deploy Trade-In / build-frontend (push) Successful in 38s
Deploy / build-worker (push) Successful in 42s
Deploy / build-backend (push) Successful in 43s
Deploy / build-frontend (push) Successful in 42s
Deploy / deploy (push) Successful in 1m32s
Deploy Trade-In / test (push) Successful in 1m50s
Deploy Trade-In / build-backend (push) Successful in 52s
Deploy Trade-In / deploy (push) Successful in 51s
2026-07-02 21:15:58 +00:00
0793571c4a fix(tradein/deploy): миграции ДО подъёма app-контейнеров + manifest-инвариант (#2216) (#2228)
All checks were successful
Deploy Trade-In / test (push) Successful in 1m35s
Deploy Trade-In / build-backend (push) Successful in 29s
Deploy Trade-In / deploy (push) Successful in 49s
Deploy Trade-In / changes (push) Successful in 20s
Deploy Trade-In / build-browser (push) Successful in 29s
Deploy Trade-In / build-frontend (push) Successful in 30s
2026-07-02 21:03:37 +00:00
ac19c4f7b3 feat(tradein/monitor): алерт на staleness данных deals по max(deal_date) (#2212) (#2226)
All checks were successful
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / changes (push) Successful in 8s
Deploy Trade-In / test (push) Successful in 1m35s
Deploy Trade-In / build-backend (push) Successful in 56s
Deploy Trade-In / deploy (push) Successful in 1m2s
2026-07-02 20:50:37 +00:00
4ce0f51bb8 perf(tradein): снять блокировку event loop на POST /estimate (#2207) (#2225)
All checks were successful
Deploy Trade-In / changes (push) Successful in 10s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m35s
Deploy Trade-In / build-backend (push) Successful in 1m27s
Deploy Trade-In / deploy (push) Successful in 1m5s
2026-07-02 20:39:48 +00:00
47f45fc3d2 fix(tradein/scrapers): bump scraped_at при ре-подтверждении живым + бэкфилл (#2206) (#2224)
All checks were successful
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m29s
Deploy Trade-In / build-backend (push) Successful in 1m25s
Deploy Trade-In / deploy (push) Successful in 1m48s
Deploy Trade-In / changes (push) Successful in 9s
Deploy Trade-In / build-frontend (push) Has been skipped
2026-07-02 20:30:01 +00:00
f5b0076e6f fix(tradein): deactivate_stale для domklik/n1 + честная freshness по scraped_at (#2204) (#2221)
All checks were successful
Deploy Trade-In / changes (push) Successful in 9s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m30s
Deploy Trade-In / build-backend (push) Successful in 58s
Deploy Trade-In / deploy (push) Successful in 2m57s
2026-07-02 20:10:34 +00:00
ca473a0012 feat(proxy-pool): P4 — browser dynamic pool-proxy (acquire→/fetch→relaunch) + orchestration wiring, ship-dark (#2164)
All checks were successful
Deploy Trade-In / build-browser (push) Successful in 2m13s
Deploy Trade-In / build-backend (push) Successful in 1m18s
Deploy Trade-In / deploy (push) Successful in 2m29s
Deploy Trade-In / changes (push) Successful in 13s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m32s
2026-07-02 19:20:29 +00:00
0937da4260 feat(proxy-pool): P3 — kit curl-paths acquire/release from pool behind USE_PROXY_POOL_CURL, ship-dark (#2163)
All checks were successful
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / changes (push) Successful in 8s
Deploy Trade-In / test (push) Successful in 1m26s
Deploy Trade-In / build-backend (push) Successful in 1m18s
Deploy Trade-In / deploy (push) Successful in 1m22s
2026-07-02 18:56:36 +00:00
ee47e331f3 Merge pull request 'fix(tradein/dedup): drop geo-guard in fias-pass — same-fias identity outranks proximity (#2187)' (#2195) from fix/tradein-dedup-fias-pass-no-geoguard into main
All checks were successful
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m26s
Deploy Trade-In / deploy (push) Successful in 51s
Deploy Trade-In / changes (push) Successful in 9s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 51s
2026-07-02 18:51:54 +00:00
a9d06c9c44 Merge pull request 'fix(tradein/matching): P1 extended — never create a house from a numberless address (no cadastral)' (#2194) from fix/tradein-no-numberless-house-insert into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 7s
Deploy Trade-In / test (push) Successful in 1m28s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 1m22s
Deploy Trade-In / deploy (push) Successful in 1m10s
2026-07-02 18:46:20 +00:00
bcdec5ebd4 feat(rewire): scheduler_main → kit-scheduler behind USE_KIT_SCHEDULER flag, ship-dark (#2192)
All checks were successful
Deploy Trade-In / deploy (push) Successful in 58s
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 37s
Deploy Trade-In / test (push) Successful in 1m38s
Deploy Trade-In / build-backend (push) Successful in 50s
2026-07-02 18:41:12 +00:00
bot-backend
03ece36abd fix(tradein/dedup): drop geo-guard in fias-pass — same-fias identity outranks proximity (#2187)
All checks were successful
CI / changes (pull_request) Successful in 10s
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
2026-07-02 21:35:20 +03:00
bot-backend
0eb033d77d fix(tradein/matching): P1 extended — never create a house from a numberless address (no cadastral)
All checks were successful
CI / changes (pull_request) Successful in 14s
CI / backend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
2026-07-02 21:33:52 +03:00
b2d794587f Merge pull request 'feat(tradein/estimator): кросс-source физдедуп аналогов за флагом (#2087 H4)' (#2173) from fix/tradein-analog-dedup-cv into main
All checks were successful
Deploy Trade-In / test (push) Successful in 1m29s
Deploy Trade-In / build-backend (push) Successful in 1m0s
Deploy Trade-In / changes (push) Successful in 7s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 51s
2026-07-02 18:04:39 +00:00
1c520cadb7 Merge pull request 'fix(tradein/dedup): fias-key clustering + cross-fias merge guard + identity carry-over (#1772 follow-up)' (#2185) from fix/tradein-dedup-by-fias into main
All checks were successful
Deploy Trade-In / test (push) Successful in 1m27s
Deploy Trade-In / build-backend (push) Successful in 51s
Deploy Trade-In / changes (push) Successful in 9s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 52s
2026-07-02 18:00:58 +00:00
bot-backend
3505a4e3e5 feat(tradein/estimator): включить кросс-source физдедуп аналогов по умолчанию (#2087 H4, #2173)
All checks were successful
CI / frontend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 9s
CI / backend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
estimate_dedup_analogs_enabled: False → True. Бэктест #1966 OFF vs ON
accuracy-идентичен (MAPE 13.89%, coverage 83.33%, bias −3.83%, median
width/cv без изменений) — включение меняет только user-visible n_analogs:
перестаёт быть раздутым кросс-постингом одного физлота на avito+cian+domklik
×3. Откат — ENV ESTIMATE_DEDUP_ANALOGS_ENABLED=false.

Тесты разведены default vs explicit (не ослаблены):
- test_estimator_dedup_cross_source_2087: добавлен test_dedup_default_is_on
  (без monkeypatch — дедуп активен по умолчанию); test_dedup_flag_off_is_noop
  оставляет ЯВНЫЙ OFF-override.
- test_backtest_regression_gate: пиним флаг OFF — гейт это байт-идентичный
  replay frozen OFF-capture (recorded call-sequence фикстуры без дедупа); с
  ON _dedup_cross_source триммит listings до quarter_indexes_lookup и
  control-flow расходится с записью.
- test_estimator_n_analogs_priced (autouse) + test_radius_path_n_analogs_unchanged:
  пиним OFF — инвариант «n_analogs = число priced-аналогов»/radius-passthrough
  ортогонален дедупу, а синтетические аналоги делят адрес/этаж/площадь и
  схлопнулись бы как кросс-посты.

Refs #2087, #2173
2026-07-02 20:56:39 +03:00
d87ebcc30e Merge pull request 'feat(tradein/matching): fias_exact tier + estimate fias persist + suggest fias_id contract' (#2184) from feat/tradein-fias-tier-matching into main
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m34s
Deploy Trade-In / build-backend (push) Successful in 54s
Deploy Trade-In / deploy (push) Successful in 55s
2026-07-02 17:56:13 +00:00
bot-backend
c4b1992de5 fix(tradein/dedup): fias-key clustering + cross-fias merge guard + identity carry-over (#1772 follow-up)
All checks were successful
CI / changes (pull_request) Successful in 7s
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
2026-07-02 20:53:25 +03:00
bot-backend
67a852caf1 feat(tradein/matching): fias_exact tier + estimate fias persist + suggest fias_id contract
All checks were successful
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 / changes (pull_request) Successful in 10s
2026-07-02 20:49:04 +03:00
509cecfa6a feat(scraper-kit): copy scheduler with registry-dispatch (25+ trigger_* → dict), strangler (#2136)
All checks were successful
Deploy Trade-In / changes (push) Successful in 9s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m30s
Deploy Trade-In / build-backend (push) Successful in 1m21s
Deploy Trade-In / deploy (push) Successful in 59s
2026-07-02 17:44:03 +00:00
bot-backend
3909db745b fix(tradein/estimator): не отравлять asking→sold ratio-кэш транзиентной ошибкой
All checks were successful
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI / changes (pull_request) Successful in 6s
CI / backend-tests (pull_request) Has been skipped
Блок «ОЖИДАЕМАЯ ЦЕНА СДЕЛКИ» (expected_sold, «с учётом торга») молча гас в «—» у
части оценок с полноценным headline (прод: high-confidence, 17 аналогов, цена
есть — expected_sold NULL). Причина: `_get_asking_sold_ratio` gracefully ловит
ЛЮБУЮ ошибку БД → (None, None), но запись в `_asking_sold_ratio_cache` шла
БЕЗУСЛОВНО (после try/except) → один транзиентный сбой (poisoned tx от
вышестоящего graceful-except, коннект-хиккап) отравлял кэш бакета `(None, None)`
на весь TTL (300с) и гасил expected_sold для ВСЕХ оценок этого rooms-бакета на
воркере до истечения TTL.

Фикс: ранний `return None, None` из except БЕЗ записи в кэш → следующая оценка
ретраит. Кэшируем только успешный lookup (ratio может быть None, если строки
реально нет — стабильный факт БД, безопасно кэшировать).

Прод-диагностика (30 дней, 304 оценки): 39 пустых expected_sold, из них 37 —
легитимно n_analogs=0 (нет аналогов), а 2 — этот баг (headline есть, ratio-кэш
отравлён). Таблица asking_to_sold_ratios полна по всем бакетам + global fallback
0.843 → при исправном lookup ratio всегда резолвится.

Юнит-тесты: транзиентная ошибка → None БЕЗ кэша; error→retry не залипает;
успех кэшируется.
2026-07-02 20:34:10 +03:00
abdb413a99 feat(scraper-kit): copy remaining sweep orchestrators (yandex/cian/domclick/full-load), strangler (#2135 F2)
All checks were successful
Deploy Trade-In / changes (push) Successful in 7s
Deploy Trade-In / deploy (push) Successful in 59s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m27s
Deploy Trade-In / build-backend (push) Successful in 1m32s
2026-07-02 17:29:05 +00:00
bot-backend
3ad1550363 feat(tradein/estimator): кросс-source физдедуп аналогов за флагом (#2087 H4)
All checks were successful
CI / changes (pull_request) Successful in 7s
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
Один физический лот кросс-постится на avito+cian+domklik (разные source и
source_id) → existing radius-дедуп по (source, source_id) его НЕ ловит →
n_analogs И source_counts раздуты кросс-постами (аудит #2087: лот
80м²/265000₽/м² = N1+Домклик+Циан ×3; «14 аналогов» → ~6-7 уникальных).

_dedup_cross_source схлопывает дубли по физическому ключу (building_cadastral
| нормализованный address + floor + area-bucket round(m²) + price-bucket
round(₽/100k)) ДО подсчёта n_analogs/median/cv, оставляя свежайшего (scraped_at)
представителя. За флагом estimate_dedup_analogs_enabled (default OFF =
байт-идентично; регресс-гейт зелёный).

Бэктест #1966 (400 ДКП, full spine, OFF vs ON, тот же сэмпл): MAPE 13.89%→13.89%,
coverage 83.33%→83.33%, bias −3.83%→−3.83%, median width 0.743→0.743, median cv
0.0988→0.0988, avg n_analogs 27.64→27.57 (дедуп отработал 107× на 335 оценках).
Кросс-посты имеют identical price → нулевой вклад в дисперсию → cv/коридор НЕ
сужаются: это фикс ЧЕСТНОСТИ СЧЁТА (n_analogs не раздут, source_counts по
физлотам), accuracy-нейтральный, а НЕ рычаг cv-сужения (рычаг cv→коридор —
estimate_sb_clip_after_weight, уже default ON). Default OFF — narrowing не
продемонстрирован; флаг готов к canary/монкипатч-бэктесту.

Refs #2087
2026-07-02 20:22:46 +03:00
8a177df0e2 feat(scraper-kit): copy sweep pipeline orchestration (avito) with protocol injection, strangler (#2135)
All checks were successful
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m35s
Deploy Trade-In / changes (push) Successful in 8s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 1m24s
Deploy Trade-In / deploy (push) Successful in 1m0s
2026-07-02 17:08:40 +00:00
d7f4873a53 feat(proxy-pool): pool service (acquire/release/health) + healthcheck scheduler task (#2162)
Some checks failed
Deploy Trade-In / changes (push) Successful in 16s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Failing after 1m36s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / deploy (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 33s
2026-07-02 16:41:39 +00:00
62fa1f732a refactor(scraper-kit): unify price bisection engine across providers + dedup (#2134)
Some checks failed
Deploy Trade-In / deploy (push) Blocked by required conditions
Deploy Trade-In / changes (push) Successful in 14s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Blocked by required conditions
Deploy Trade-In / build-frontend (push) Has been cancelled
Deploy Trade-In / test (push) Has been cancelled
2026-07-02 16:41:04 +00:00
90e4a741f7 feat(proxy-pool): scrape_proxies table + admin bulk-load/list endpoints (#2161)
Some checks failed
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-frontend (push) Successful in 33s
Deploy Trade-In / test (push) Failing after 1m32s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / deploy (push) Has been skipped
2026-07-02 16:31:21 +00:00
3be8062062 feat(scraper-kit): copy yandex providers with protocol injection, strangler (#2133 yandex)
Some checks failed
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / test (push) Failing after 1m31s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / deploy (push) Has been skipped
2026-07-02 16:13:32 +00:00
19c0be5d5a feat(scraper-kit): copy cian providers with protocol injection, strangler (#2133 cian)
Some checks failed
Deploy Trade-In / test (push) Failing after 1m30s
Deploy Trade-In / build-backend (push) Has been skipped
Deploy Trade-In / deploy (push) Has been skipped
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / build-frontend (push) Has been skipped
2026-07-02 16:11:31 +00:00
b7abaeb569 feat(scraper-kit): copy domclick provider with protocol injection, strangler (#2133 domclick)
Some checks failed
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m28s
Deploy Trade-In / build-backend (push) Successful in 1m24s
Deploy Trade-In / deploy (push) Has been cancelled
2026-07-02 16:08:09 +00:00
df5e9003df feat(scraper-kit): copy avito providers with protocol injection, strangler (#2133 avito)
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m30s
Deploy Trade-In / build-backend (push) Successful in 1m47s
Deploy Trade-In / deploy (push) Successful in 1m1s
2026-07-02 15:58:00 +00:00
5c17d21f6c feat(scraper-kit): copy core layer (base/save_listings/transport) with protocol injection, strangler (#2132)
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m27s
Deploy Trade-In / build-backend (push) Successful in 1m22s
Deploy Trade-In / deploy (push) Successful in 1m8s
2026-07-02 15:43:15 +00:00
9d71d94586 Merge pull request 'fix(tradein/estimator): честный asking_to_sold_ratio — бейдж «−N% к рынку» больше не врёт' (#2152) from fix/tradein-honest-asking-to-sold-ratio into main
All checks were successful
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m28s
Deploy Trade-In / deploy (push) Successful in 52s
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 1m5s
2026-07-02 15:37:00 +00:00
ecc3ab5aab fix(tradein/estimator): честный asking_to_sold_ratio — бейдж «−N% к рынку» больше не врёт
All checks were successful
CI / changes (pull_request) Successful in 8s
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
Оценщик клиента жаловался на «большой интервал между рекомендованной ценой
и оценкой». Разбор: бейдж «−23% к рынку» (web HeroSummary + PDF, формула
round((1−ratio)×100)) систематически завышал скидку.

Root cause: сохранённый asking_to_sold_ratio — это СЫРОЙ per-rooms/tier дисконт
из ratio_resolver, но фактический expected_sold сдвинут относительно median×ratio
последующими корректировками: hedonic year+area (#2002, factor ∈ [0.75, 1.30], ON
by default), le_asking-clamp и corridor-clamp. Пример с прода (451de30b): median
7.75M × raw 0.771 = 5.97M, hedonic ×1.226 → expected_sold 7.32M — но stored ratio
остался 0.771, тогда как фактическое expected_sold/median = 0.945. Бейдж показывал
«−23%» вместо честных «−5%».

Fix: после финализации expected_sold пересчитываем сохранённый asking_to_sold_ratio
как реальное expected_sold_price/median_price (честный дескриптор). Сам expected_sold
(выкуп) НЕ трогаем — hedonic-uplift остаётся прибит к sale-модели, buyout не падает
до наивного median×raw. Порог _RATIO_DESCRIPTOR_EPS=1e-4 отсекает шум округления:
без сдвига (hedonic OFF, нет клампа) табличный ratio сохраняется байт-в-байт →
регрессия на не-зажатых оценках отсутствует.

Стор asking_to_sold_ratio — чисто ДЕСКРИПТОР (web/PDF/history badge), НЕ калибровочный
вход: калибровочный ratio живёт в таблице asking_to_sold_ratios (refresh-task, читает
resolver) — не тронута. Backtest #1966 скорит expected_sold_per_m2 (не stored ratio) —
не затронут (expected_sold без изменений).

Tests: 3 новых в test_estimator_price_spine.py (инвариант при hedonic-uplift +
corridor-clamp; byte-identical регрессия без сдвига); поправлен
test_global_fallback_basis_carried_through (hedonic OFF для сырого ratio).
Full suite: 2749 passed (кроме pre-existing test_search_cache_hit).

Refs #2141
2026-07-02 18:26:19 +03:00
6391587572 feat(scraper-kit): protocol boundaries (matcher/config/session/jobs) + backend adapters (#2131)
All checks were successful
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m27s
Deploy Trade-In / build-backend (push) Successful in 1m26s
Deploy Trade-In / deploy (push) Successful in 1m0s
2026-07-02 15:25:38 +00:00
18b22c9df8 fix(tradein/v2): canonical sources_used — kill «ИСТОЧНИКОВ X/7» POST↔GET desync
All checks were successful
CI / changes (pull_request) Successful in 7s
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
Единый helper estimator._canonical_sources(analogs, valuation_flags) — источник
правды для sources_used, зовётся идентично на POST (estimate_quality) и
GET-rehydrate (get_estimate) из ТЕХ ЖЕ persisted analogs + оценочных флагов.

Root cause: три расходящиеся деривации — POST брал sources_used из top-N
analogs_lots, GET возвращал persisted-колонку (радиусный набор + quarter_index),
source_counts на GET считался из persisted analogs. Источник (напр. cian) мог
попасть в source_counts, но не в sources_used → счётчик «X/7» прыгал 4→5 между
POST-ответом и reload(GET).

- sources_used = {листинговые из persisted analogs} ∪ {avito_imv/yandex_valuation/
  cian_valuation}. Детерминированно отсортирован.
- source_counts на POST теперь тоже из analogs_lots (не полной metadata-выборки)
  → инвариант source_counts.keys() ⊆ sources_used на POST и GET.
- POST персистит канонический sources_used в колонку (history/PDF консистентны для
  новых строк); GET рехайдрейтит его же helper'ом — чинит и СТАРЫЕ строки
  (листинговая часть пересобирается из analogs, quarter_index/радиусный шум
  отбрасывается фильтром оценочных флагов).

Оценочные флаги персистятся в колонке sources_used и читаются оттуда на GET —
реконструкция не требуется.

Repro 451de30b: до — sources_used=[avito,avito_imv,domklik,yandex], source_counts
имеет cian (не в sources_used); после — sources_used=[avito,avito_imv,cian,
domklik,yandex] (5/7), counts.keys() ⊆ sources_used.

Part of #2087 (M1).
2026-07-02 17:22:20 +03:00
32d1818fd4 fix(scrapers/avito): unify _unix_to_date timezone across serp/houses/imv (#2129)
Some checks failed
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m32s
Deploy Trade-In / deploy (push) Has been cancelled
Deploy Trade-In / changes (push) Successful in 11s
Deploy Trade-In / build-backend (push) Successful in 59s
2026-07-02 14:03:11 +00:00
3bf2c1a48a feat(tradein/api): #2044 BE-2 — optional radius_m on house-analytics + sell-time-sensitivity
All checks were successful
CI / changes (pull_request) Successful in 11s
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
radius_m (schema + estimate_quality comp-search) уже в main (e23dabe4). Здесь —
остаток: два derived-роута принимают radius_m как optional query-param.

- GET /estimate/{id}/house-analytics и /sell-time-sensitivity: += radius_m
  (int|None). None → байт-идентичная авто-логика (расширение до 300 м только при
  <8 in-house записей). Задан → явный радиус расширения выборки домов, клампится
  в [100,5000], возвращается в radius_m ответа.

Refs #2044
2026-07-02 16:51:11 +03:00
24b107ddb5 feat(tradein): #2043 BE-1 — surface cv/source_counts/created_at + /history.sources_used + cache-KPI
Данные уже считаются в estimator — отдаём наружу для /trade-in/v2 (снимает
approximate-флаги CV / счётчиков источников / даты отчёта / «ИСТОЧНИКОВ N/7»).

- AggregatedEstimate += cv (float|None), source_counts (dict[str,int]), created_at.
- estimator: _cv_from_ppm2 / _source_counts helpers. cv прокинут через
  PricingResult — anchor-путь берёт CV комплов (anchor["cv"]), radius-путь — CV
  радиусной ₽/м²-выборки. source_counts считается по ПОЛНОЙ выборке (metadata_lots)
  до top-N отсечки. created_at = момент создания.
- POST /estimate возвращает все три; GET /estimate/{id} пересчитывает cv/
  source_counts из сохранённых analogs (best-effort) + created_at из колонки.
- /history: += sources_used (jsonb) в проекции → колонка «ИСТОЧНИКОВ N/7».
- /cache-stats: += avg_median_price (по median_price>0) + repeat_address_pct
  (доля строк с неуникальным address). Честный best-effort по persisted-оценкам.

Refs #2043
2026-07-02 16:50:18 +03:00
69845ddcee fix(tradein/avito-detail): живой прогрев сессии + батч-на-сессию — снимает 403 на curl-backfill (#1551)
All checks were successful
Deploy Trade-In / changes (push) Successful in 12s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 1m27s
Deploy Trade-In / build-backend (push) Successful in 51s
Deploy Trade-In / deploy (push) Successful in 1m37s
2026-06-28 22:34:38 +00:00