64ed95271f
fix(leads): window revenue_total/deals_total to leads_window ( #1383 )
...
CI / changes (push) Successful in 10s
CI / changes (pull_request) Successful in 8s
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Successful in 1m42s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m45s
CI / backend-tests (push) Failing after 8m48s
CI / backend-tests (pull_request) Failing after 8m46s
Both metrics were querying prinzip_deals without any date filter,
returning all-time figures while the surrounding stats (leads_window,
converted_window, conv_pct_window) were scoped to the last N months.
Now both subqueries restrict to deals linked to leads in window_leads
(via deal_id IN (...)), making all «за период» figures consistent.
2026-06-17 20:49:16 +03:00
ba83c36bf4
Merge pull request 'fix(sql): dedup deals-to-district assignment in ekb districts median refresh ( #1352 )' ( #1678 ) from fix/district-median-dedup-1352 into main
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
Deploy / changes (push) Waiting to run
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
2026-06-17 17:45:31 +00:00
11fe22b49a
Merge pull request 'fix(cadastre): cad_territorial_zones MULTIPOLYGON typmod + ST_Multi coercion ( #1344 )' ( #1673 ) from fix/cad-zones-multipolygon-1344 into main
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
Deploy / changes (push) Waiting to run
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
2026-06-17 17:45:26 +00:00
cf21ff76a9
Merge pull request 'fix(forecasting): cap trend_ratio by v_rec magnitude when v_prior==0 ( #1508 )' ( #1679 ) from fix/trend-ratio-vprior-zero-1508 into main
2026-06-17 17:45:13 +00:00
ea32f064c1
Merge pull request 'fix(site-finder): non-overlapping L2/L3 ready_dt windows, stop double-count of 13-24mo supply ( #1355 )' ( #1677 ) from fix/supply-layers-overlap-1355 into main
Deploy / changes (push) Waiting to run
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
2026-06-17 17:45:08 +00:00
3dcddae647
Merge pull request 'fix(tradein): trade-in PDF cover uses estimate.expires_at, not hardcoded +30d ( #1530 )' ( #1676 ) from fix/pdf-expires-at-1530 into main
Deploy Trade-In / changes (push) Waiting to run
Deploy Trade-In / test (push) Blocked by required conditions
Deploy Trade-In / build-backend (push) Blocked by required conditions
Deploy Trade-In / build-frontend (push) Blocked by required conditions
Deploy Trade-In / build-browser (push) Blocked by required conditions
Deploy Trade-In / deploy (push) Blocked by required conditions
2026-06-17 17:45:03 +00:00
3ffba9f8a8
Merge pull request 'fix(analytics): align portfolio series to area buckets in quartirography ( #1406 )' ( #1675 ) from fix/quartirography-area-bucket-1406 into main
Deploy / changes (push) Waiting to run
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
2026-06-17 17:44:58 +00:00
79c5068e96
Merge pull request 'fix(analytics): drop false market verdict from per-object Sold % KpiCard ( #1407 )' ( #1672 ) from fix/sold-pct-market-verdict-1407 into main
Deploy / changes (push) Waiting to run
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
2026-06-17 17:44:47 +00:00
cf36151dbc
fix(forecasting): cap trend_ratio by v_rec magnitude when v_prior==0 ( #1508 )
...
CI / changes (push) Successful in 10s
CI / changes (pull_request) Successful in 7s
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) 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
When v_prior == 0 and v_rec > 0, the old code unconditionally assigned
trend_ratio = 2.0, producing an artificial 2x jump even for districts
with negligible recent velocity.
New formula:
ratio = 1.0 + min(1.0, v_rec / _REF_VELOCITY) * (_TREND_CAP_VPRIOR_ZERO - 1.0)
Where:
_REF_VELOCITY = 10.0 (monthly flats/corpus — EKB "well-performing" benchmark)
_TREND_CAP_VPRIOR_ZERO = 1.5 (max ratio for the v_prior==0 case)
Tiny v_rec (e.g. 1 flat/month) → ratio ≈ 1.05 (near neutral)
Large v_rec (≥ 10 flat/month) → ratio → 1.5 (capped, below old hard 2.0)
v_prior > 0 branch is unchanged.
Also fixes pre-existing ruff violations in the same file (E401 multi-import,
E701 inline colon, E722 bare except, F401 unused import) so ruff check passes clean.
2026-06-17 20:29:46 +03:00
04d1a64e25
fix(sql): dedup deals-to-district assignment in ekb districts median refresh ( #1352 )
...
CI / changes (push) Successful in 9s
CI / changes (pull_request) Successful in 6s
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Successful in 1m56s
CI / backend-tests (push) Failing after 9m1s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m44s
CI / backend-tests (pull_request) Failing after 9m12s
Replace ST_Intersects(district.geom, quarter.geom) with ST_Within(ST_Centroid(quarter.geom), district.geom)
so each cadastral quarter is assigned to exactly one district. Eliminates 85 double-counted quarter-district
pairs and 307 spurious deal-district rows that were skewing PERCENTILE_CONT medians. Function signature
unchanged; no backend code changes required.
2026-06-17 20:29:34 +03:00
be68ba8f54
fix(site-finder): non-overlapping L2/L3 ready_dt windows, stop double-count of 13-24mo supply ( #1355 )
CI / changes (push) Successful in 10s
CI / changes (pull_request) Successful in 6s
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Successful in 1m52s
CI / backend-tests (push) Failing after 8m55s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m47s
CI / backend-tests (pull_request) Failing after 9m0s
2026-06-17 20:29:09 +03:00
f8ea119d22
fix(tradein): trade-in PDF cover uses estimate.expires_at, not hardcoded +30d ( #1530 )
CI / changes (push) Successful in 10s
CI / changes (pull_request) Successful in 6s
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) 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
2026-06-17 20:27:57 +03:00
26ae507c11
fix(analytics): align portfolio series to area buckets in quartirography ( #1406 )
...
CI / changes (push) Successful in 8s
CI / changes (pull_request) Successful in 9s
CI / frontend-tests (push) Successful in 1m1s
CI / openapi-codegen-check (push) Successful in 1m50s
CI / backend-tests (push) Failing after 9m8s
CI / frontend-tests (pull_request) Successful in 54s
CI / openapi-codegen-check (pull_request) Successful in 1m59s
CI / backend-tests (pull_request) Failing after 8m56s
Switch portfolio source from domrf_region_aggregates (room_count_type ONE/TWO/THREE/FOUR)
to domrf_flat_area_distribution (area_bucket FROM_0_TO_25…FROM_100), aggregated into the
same 5 area buckets as the deals series. Both series now share the same axis and are
directly comparable. Frontend portfolioMap simplified to direct bucket key lookup.
2026-06-17 20:25:17 +03:00
13327e5a2c
fix(cadastre): cad_territorial_zones MULTIPOLYGON typmod + ST_Multi coercion ( #1344 )
CI / changes (push) Successful in 12s
CI / changes (pull_request) Successful in 10s
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Successful in 2m12s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m42s
CI / backend-tests (push) Failing after 9m11s
CI / backend-tests (pull_request) Failing after 8m55s
2026-06-17 20:23:56 +03:00
18da92ccc7
Merge pull request 'fix(week-review): дожим — 4 фикса ( #1569 , #1590 , #1642 , #801 )' ( #1662 ) from fix/week-review-finish into main
Deploy / changes (push) Successful in 7s
Deploy / build-backend (push) Successful in 1m40s
Deploy / build-frontend (push) Successful in 3m40s
Deploy / build-worker (push) Successful in 4m27s
Deploy / deploy (push) Successful in 1m34s
2026-06-17 17:23:10 +00:00
66afac8bb3
fix(analytics): drop false market verdict from per-object Sold % KpiCard ( #1407 )
CI / changes (push) Successful in 8s
CI / openapi-codegen-check (push) Successful in 1m47s
CI / changes (pull_request) Successful in 6s
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Successful in 50s
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Successful in 1m4s
CI / openapi-codegen-check (pull_request) Successful in 2m19s
2026-06-17 20:22:29 +03:00
20efc3bf64
merge: resolve conflicts with main ( #1660 ) into week-review-finish
...
CI / backend-tests (pull_request) Failing after 9m11s
CI / backend-tests (push) Failing after 9m22s
CI / openapi-codegen-check (push) Successful in 2m14s
CI / changes (pull_request) Successful in 6s
CI / changes (push) Successful in 8s
CI / frontend-tests (pull_request) Successful in 1m13s
CI / frontend-tests (push) Successful in 1m2s
CI / openapi-codegen-check (pull_request) Successful in 1m47s
5 conflicts resolved:
- redaction.py: merged INN checksum + _PHONE_LOCAL_RE + _Repl alias from main
- recommendation.py: kept commercial_sell_through_pct rename (#1635 )
- report_pdf.py: kept _scenario_deficit_cell + int|None return type (#1590 )
- parcel.py: kept main's detailed docstring (functionally identical)
- alembic/env.py: kept HEAD (app.models import in __init__ already covers all)
2026-06-17 20:21:06 +03:00
14f3ef2019
fix(week-review): backend-аудит v2 — 82 фиксов ( #1660 )
...
Deploy / build-worker (push) Successful in 2m47s
Deploy / deploy (push) Successful in 1m20s
Deploy / changes (push) Successful in 9s
Deploy / build-frontend (push) Has been skipped
Deploy / build-backend (push) Successful in 1m52s
Co-authored-by: bot-backend <bot-backend@gendsgn.local>
Co-committed-by: bot-backend <bot-backend@gendsgn.local>
2026-06-17 17:13:38 +00:00
50db2b82aa
Merge pull request 'fix(site-finder): nearest_top3 metro from osm_poi_ekb ( #1667 )' ( #1670 ) from fix/1667-metro-block into main
Deploy / build-backend (push) Has been cancelled
Deploy / build-worker (push) Has been cancelled
Deploy / build-frontend (push) Has been cancelled
Deploy / changes (push) Successful in 9s
Deploy / deploy (push) Has been cancelled
2026-06-17 17:13:17 +00:00
e4b80938a0
Merge pull request 'docs(site-finder): analyze confidence by-design distinct from §15 ( #1668 )' ( #1671 ) from fix/1668-analyze-confidence into main
Deploy / changes (push) Waiting to run
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
2026-06-17 17:13:07 +00:00
184e429526
Merge pull request 'fix(workers): schedule mv_layout_velocity refresh ( #1666 )' ( #1669 ) from fix/1666-layout-velocity-beat into main
Deploy / changes (push) Waiting to run
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
2026-06-17 17:12:54 +00:00
829f046852
feat(scripts): Potrace floor-plan vectorization spike ( #299 ) ( #1663 )
...
Deploy / build-backend (push) Blocked by required conditions
Deploy / build-worker (push) Blocked by required conditions
Deploy / build-frontend (push) Blocked by required conditions
Deploy / deploy (push) Blocked by required conditions
Deploy / changes (push) Has been cancelled
Co-authored-by: bot-backend <bot-backend@gendsgn.local>
Co-committed-by: bot-backend <bot-backend@gendsgn.local>
2026-06-17 17:12:48 +00:00
d3a53ae475
docs(site-finder): clarify analyze confidence is by-design distinct from §15 ( #1668 )
...
CI / changes (push) Successful in 8s
CI / changes (pull_request) Successful in 6s
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Successful in 1m38s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Successful in 1m40s
CI / backend-tests (push) Successful in 8m42s
CI / backend-tests (pull_request) Successful in 8m40s
_compute_confidence docstring claimed "stub до G1/G2/D1/D2" — те эшелоны уже
отгружены, формулировка устарела. Это намеренно отдельная метрика: надёжность
site-finder скоринга (coverage POI/район/рынок), НЕ форсайтный §15
confidence_engine (надёжность прогноза спроса/цены над форсайт-входами,
которых в analyze hot-path нет). Поведение не меняется — резолв документацией.
Closes #1668
2026-06-17 18:47:07 +05:00
7072d7803e
fix(site-finder): compute nearest_top3 metro from osm_poi_ekb ( #1667 )
...
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Successful in 1m39s
CI / backend-tests (pull_request) Successful in 8m41s
CI / backend-tests (push) Successful in 8m40s
CI / frontend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 7s
CI / changes (push) Successful in 7s
CI / openapi-codegen-check (pull_request) Successful in 1m41s
Replace bare metro_block placeholder ({"nearest_top3": None}, blocked on a
never-merged 22h metro scraper) with a direct KNN query against osm_poi_ekb
category='metro_stop' (loaded by poi_loader). Returns 3 nearest stations with
name + rounded distance_m; empty list when none nearby (vs None on error),
SAVEPOINT + try/except like adjacent SF-B5 blocks. No frontend consumer yet.
Closes #1667
2026-06-17 18:44:29 +05:00
7276edc885
fix(workers): schedule mv_layout_velocity refresh in Celery beat ( #1666 )
...
CI / backend-tests (push) Successful in 8m49s
CI / backend-tests (pull_request) Successful in 8m52s
CI / changes (push) Successful in 6s
CI / frontend-tests (push) Has been skipped
CI / changes (pull_request) Successful in 8s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (push) Successful in 1m57s
CI / openapi-codegen-check (pull_request) Successful in 1m55s
mv_layout_velocity (powers best_layouts, #113 ) refreshed only via manual
refresh_layout_velocity() → prod data silently went stale. Add Celery task
mirroring refresh_quarter_price_index, register in celery_app include, add
weekly beat entry (Sun 03:00 MSK, outside the monday heavy-refresh cluster).
Closes #1666
2026-06-17 18:40:01 +05:00
764db61734
fix(exporters): annotate scenario deficit horizon in docx/pptx ( #1590 follow-up)
...
CI / changes (pull_request) Successful in 7s
CI / changes (push) Successful in 7s
CI / frontend-tests (push) Successful in 1m1s
CI / frontend-tests (pull_request) Successful in 1m17s
CI / openapi-codegen-check (push) Successful in 2m19s
CI / backend-tests (pull_request) Successful in 9m11s
CI / backend-tests (push) Successful in 9m15s
CI / openapi-codegen-check (pull_request) Successful in 1m43s
report_docx и report_pptx рендерили bare _scenario_deficit_index под
захардкоженной шапкой «(12 мес)» — при fallback на другой горизонт подпись
лгала. Переключил оба на _scenario_deficit_cell (как в report_md): per-cell
аннотация «(гор. N мес)» при N != 12. Закрывает code-review major по #1590 .
2026-06-17 14:35:48 +05:00
c9ba595abe
refactor(forecasting): rename commercial_share_pct → commercial_sell_through_pct ( #1635 )
...
CI / changes (pull_request) Successful in 6s
CI / frontend-tests (push) Successful in 1m40s
CI / openapi-codegen-check (push) Successful in 1m38s
CI / backend-tests (pull_request) Successful in 9m51s
CI / changes (push) Successful in 7s
CI / frontend-tests (pull_request) Successful in 53s
CI / openapi-codegen-check (pull_request) Successful in 3m10s
CI / backend-tests (push) Successful in 9m52s
Внутренний recommendation→product_scoring контракт-ключ был мислейблом: величина —
темп распродажи нежилого (sell-through, прокси ликвидности/спроса), а НЕ доля нежилого
в объёме застройки. Переименован ключ + исправлены reason/docstring/комментарии у
потребителя _score_commercial. Числовая логика не изменена. Ключ внутренний (нет
frontend/schema/openapi-потребителей) → rename контракт-безопасен. pytest 171 passed.
Closes #1635
2026-06-17 13:32:03 +05:00
f8779c0812
feat(yandex): switch SERP scraping to JSON gate-API (bypasses bandwidth tarpit) ( #1665 )
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / test (push) Successful in 32s
Deploy Trade-In / build-backend (push) Successful in 51s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 42s
Deploy Trade-In / changes (push) Successful in 6s
2026-06-17 08:20:46 +00:00
edaadc7685
Merge pull request 'fix(yandex): rotate proxy IP + retry on tarpit-timeout/captcha in combos sweep' ( #1664 ) from fix/yandex-rotate-on-tarpit into main
...
Deploy Trade-In / test (push) Successful in 39s
Deploy Trade-In / build-backend (push) Successful in 53s
Deploy Trade-In / deploy (push) Successful in 44s
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
Reviewed-on: #1664
2026-06-17 07:13:48 +00:00
b19c4a0b8c
fix(tradein): yandex fetch_around rotate-on-tarpit + retry (combos sweep resilience)
...
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Has been skipped
CI / changes (pull_request) Successful in 6s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
CI / changes (push) Successful in 8s
CI / backend-tests (push) Has been skipped
CI / backend-tests (pull_request) Has been skipped
Add _YANDEX_TARPIT_MAX_RETRIES=2 constant and rewrite fetch_around with a
loop: on status_code==0 (curl exit 28, bandwidth tarpit) or captcha detected,
call _rotate_ip() + sleep(2s) and retry. Non-zero non-200 codes (404 etc.)
return [] immediately without rotation. Mirrors the existing exhaustive-path
pattern in _walk_price_range. 4 new unit tests cover: tarpit→rotate→success,
captcha→rotate→success, exhausted retries→empty, 404→no-rotate.
2026-06-17 10:12:24 +03:00
249182b678
fix(week-review): дожим ревью — #1569 , #1590 , #1642 + feat #801 MSW-preview
...
CI / frontend-tests (pull_request) Successful in 1m2s
CI / openapi-codegen-check (push) Successful in 2m13s
CI / openapi-codegen-check (pull_request) Successful in 1m45s
CI / backend-tests (push) Successful in 9m29s
CI / backend-tests (pull_request) Successful in 9m29s
CI / changes (push) Successful in 8s
CI / changes (pull_request) Successful in 8s
CI / frontend-tests (push) Successful in 1m7s
Финиш-волна по cross-file/partial остаткам аудита + a11y-харнесс.
Полностью (4): #1569 alembic регистрирует все ORM-модели (+убран фантомный Parcel) ·
#1590 «Индекс дефицита» больше не лжёт на fallback-горизонте (report_pdf+report_md) ·
#1642 thumbs mtime-freshness (нет устаревшей миниатюры) ·
#801 /__preview/estimate mock-render для axe/lighthouse (env-gated bypass).
Частично (остаток cross-file/домен, открыты): #1593 #1635 #1640 .
needs-leha (открыт): #1650 (нужна новая миграция вьюхи supply-слоёв).
Verify: tsc --noEmit 0; py_compile OK.
Closes #1569
Closes #1590
Closes #1642
Closes #801
2026-06-17 11:24:34 +05:00
7a88964ef5
fix(avito): scale per-anchor timeout for detail-enrich + durable SERP counters ( #1661 )
Deploy Trade-In / test (push) Successful in 36s
Deploy Trade-In / changes (push) Successful in 7s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 54s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 45s
2026-06-17 06:07:50 +00:00
4811920d28
fix(tradein): yandex combos watchdog timeout (P0) + deploy scraper filter gap ( #1659 )
...
Deploy Trade-In / changes (push) Successful in 7s
Deploy Trade-In / build-browser (push) Successful in 28s
Deploy Trade-In / test (push) Successful in 34s
Deploy Trade-In / build-frontend (push) Successful in 1m46s
Deploy Trade-In / deploy (push) Successful in 46s
Deploy Trade-In / build-backend (push) Successful in 53s
Co-authored-by: lekss361 <lekss361@gendsgn.local>
Co-committed-by: lekss361 <lekss361@gendsgn.local>
2026-06-16 20:22:27 +00:00
e7901bc1e8
feat(tradein): yandex city sweep — EKB-center rooms×price combos (replaces 5-anchor shallow) ( #1658 )
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 / test (push) Successful in 33s
Deploy Trade-In / build-backend (push) Successful in 52s
Deploy Trade-In / deploy (push) Successful in 43s
2026-06-16 19:57:37 +00:00
66433dfe1b
feat(cian): collect price history via BrowserFetcher (fixes silent no-op backfill) ( #1657 )
...
Deploy Trade-In / changes (push) Successful in 7s
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 33s
Deploy Trade-In / build-backend (push) Successful in 52s
Deploy Trade-In / deploy (push) Successful in 44s
Co-authored-by: lekss361 <lekss361@gendsgn.local>
Co-committed-by: lekss361 <lekss361@gendsgn.local>
2026-06-16 19:47:16 +00:00
b5829fa226
feat(scrapers): enable cian_city_sweep (proxy alive, sweep is cookieless) ( #1568 )
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 35s
Deploy Trade-In / build-backend (push) Successful in 26s
Deploy Trade-In / deploy (push) Successful in 42s
2026-06-16 17:08:47 +00:00
e46867fa7f
feat(tradein/db): derived price-history trigger (avito/yandex) + last_seen_at deactivate index ( #1559 )
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 / test (push) Successful in 33s
Deploy Trade-In / build-backend (push) Successful in 27s
Deploy Trade-In / deploy (push) Successful in 41s
2026-06-16 16:48:58 +00:00
91f9a95f93
feat(scrapers): segment-aware generic deactivate_stale for yandex/cian ( #1558 )
Deploy Trade-In / changes (push) Successful in 7s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 45s
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 33s
Deploy Trade-In / build-backend (push) Successful in 56s
2026-06-16 16:09:19 +00:00
496af12c9c
Merge pull request 'fix(scrapers): deactivate pre-#753 ghost duplicate listings (dedup correctness)' ( #1557 ) from fix/deactivate-ghost-duplicate-listings into main
...
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 35s
Deploy Trade-In / deploy (push) Successful in 43s
Deploy Trade-In / changes (push) Successful in 7s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-backend (push) Successful in 1m8s
Reviewed-on: #1557
2026-06-16 12:59:46 +00:00
6b7391ba93
fix(db): deactivate pre-#753 ghost duplicate listings (167 rows)
...
CI / changes (push) Successful in 8s
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Has been skipped
CI / changes (pull_request) Successful in 6s
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
Before #753 dedup_hash included price, so each price change created a new
active row. The canonical rows are now upserted correctly; ghost rows sit
frozen with stale hashes. Deactivates only active non-canonical rows in
groups that already have a canonical twin, excluding all-ghost groups.
Dry-run on prod (2026-06-16): UPDATE 167 rows as expected (yandex ~164,
cian ~1, n1 ~2, avito 0).
Refs #753
2026-06-16 15:40:30 +03:00
a200025571
Merge pull request 'chore(scrapers): убрать устаревший n1-скраппер (n1.ru → cian), сохранить историч. данные' ( #1556 ) from chore/remove-n1-scraper into main
Deploy Trade-In / build-browser (push) Has been skipped
Deploy Trade-In / test (push) Successful in 33s
Deploy Trade-In / build-backend (push) Successful in 53s
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / deploy (push) Successful in 44s
2026-06-16 11:58:02 +00:00
c07b5d7c5d
chore(tradein): деактивировать N1.ru scraper — источник переехал в Cian
...
CI / openapi-codegen-check (push) 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 / changes (push) Successful in 8s
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / changes (pull_request) Successful in 7s
N1.ru перестал быть самостоятельным источником (переехал в Cian, подтверждено
владельцем 2026-06). Активный скрап прекращён; 389 исторических listings в БД
сохраняются без изменений.
Убрано:
- app/services/scrapers/n1.py (удалён)
- run_n1_city_sweep + N1CitySweepCounters + N1_SWEEP_MAX_CONSECUTIVE_FAILURES
из scrape_pipeline.py
- trigger_n1_city_sweep_run + dispatch elif в scheduler.py
- POST /scrape/n1 + GET /scrape/n1/runs endpoints из admin.py
- N1Scraper из scrape_around dispatch dict и ScrapeRequest.multi_room_n1
- "n1": 5.0 из scraper_settings._DEFAULT_DELAY_BY_SOURCE
- tests/test_n1_city_sweep.py, tests/test_n1_floor_parse.py (удалены)
Добавлено:
- data/sql/114_disable_n1_sweep.sql: UPDATE scrape_schedules SET enabled=false
WHERE source='n1_city_sweep' (idempotent, строка сохраняется для audit-истории)
Сохранено (историческое):
- schemas/search.py Literal[..."n1"] — API-фильтр исторических listings
- config.py scrape_allowed_hosts n1.ru / ekaterinburg.n1.ru
- exporters/trade_in_pdf.py — цвет/лейбл N1 для отображения старых записей
- geocoder.py и admin.py docstring N1-комментарии где не активный код
1802 passed, 2 deselected (test_search_cache_hit, test_cian_valuation.cache_hit)
2026-06-16 14:50:51 +03:00
f160ad3859
Merge pull request 'fix(scrapers): cian detail — извлечение kitchen_area_m2 (part of #1553 )' ( #1555 ) from fix/cian-kitchen-area into main
Deploy Trade-In / test (push) Successful in 32s
Deploy Trade-In / build-backend (push) Successful in 52s
Deploy Trade-In / deploy (push) Successful in 42s
Deploy Trade-In / changes (push) Successful in 6s
Deploy Trade-In / build-frontend (push) Has been skipped
Deploy Trade-In / build-browser (push) Has been skipped
2026-06-16 11:42:35 +00:00
b390c8334c
fix(tradein): cian detail-парсер не извлекал kitchen_area_m2 из offer.kitchenArea
...
CI / changes (push) Successful in 8s
CI / openapi-codegen-check (push) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / changes (pull_request) Successful in 7s
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
Добавлено поле kitchen_area_m2 в DetailEnrichment dataclass,
извлечение через _parse_float(offer.get("kitchenArea")) в fetch_detail,
и COALESCE(CAST(:ka AS double precision), kitchen_area_m2) в UPDATE listings
внутри save_detail_enrichment.
Имя поля kitchenArea — стандартное cian offer API (live-verify не делался,
прокси недоступен в dev-окружении).
Closes #1553
2026-06-16 14:37:49 +03:00
d76df54ece
Merge pull request 'feat(scrapers): yandex detail-enrichment — save + ночной backfill через прокси (part of #1553 )' ( #1554 ) from feat/yandex-detail-backfill into main
Deploy Trade-In / changes (push) Successful in 6s
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 33s
Deploy Trade-In / build-backend (push) Successful in 50s
Deploy Trade-In / deploy (push) Successful in 44s
2026-06-16 11:18:18 +00:00
fd4a0d643d
fix(tradein): review minors — scheduler comment + save-error log label
...
CI / changes (push) Successful in 7s
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Has been skipped
CI / changes (pull_request) Successful in 6s
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
- scheduler.py: исправлен stale-комментарий yandex_detail_backfill
(был: «YandexDetailScraper httpx, no proxy layer»;
теперь: fetch via curl_cffi chrome120 + scraper_proxy_url,
parse via YandexDetailScraper.parse)
- yandex_detail_backfill.py: outer except — сообщение лога изменено на
«save/iteration error for listing_id=%d» чтобы отличать save-ошибку
от fetch/parse-None путей (run_id убран — он менее важен в этом scope)
2026-06-16 14:14:07 +03:00
e2e0291a0a
fix(tradein): yandex detail backfill — заменить fetch_detail на curl_cffi+proxy
...
CI / changes (push) Successful in 8s
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Has been skipped
YandexDetailScraper.fetch_detail использует plain httpx (BaseScraper._http_get)
без прокси и без TLS-fingerprinting → на датацентровом IP Yandex отдаёт капчу /
shell-HTML → parse всегда None → backfill 0% эффективен.
Замена: curl_cffi AsyncSession(chrome120 + scraper_proxy_url), идентично
yandex_address_backfill.py (доказано работающий путь на проде). HTTP 200 →
YandexDetailScraper.parse(html) (чистая функция, без сети). parse→None
считается fail (captcha wall); consecutive None → abort после max_consecutive_blocks.
Тесты обновлены: мокается AsyncSession.get + YandexDetailScraper.parse
(не fetch_detail). Добавлены кейсы: non-200 → abort, proxy=None → proxies=None.
2026-06-16 14:05:22 +03:00
03e43f12b5
feat(tradein): yandex detail backfill — save_detail_enrichment + nightly task ( #1553 )
...
CI / changes (push) Successful in 7s
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Has been skipped
- yandex_detail.py: добавить save_detail_enrichment(db, listing_id, enrichment) → bool;
UPDATE listings COALESCE по 17 полям (rooms/area_m2/floor/total_floors/address/
description/repair_state/publish_date/views_total_yandex/publish_date_relative/
agency_name/agency_founded_year/agency_objects_count/metro_stations/photo_urls/
newbuilding_url/newbuilding_id); metro/photos → jsonb; detail_enriched_at = NOW()
- app/tasks/yandex_detail_backfill.py: новый task run_yandex_detail_backfill;
snapshot SELECT source='yandex' AND detail_enriched_at IS NULL; YandexDetailScraper
async context manager; consecutive None abort (max_consecutive_blocks=5); budget guard;
run lifecycle update_heartbeat/mark_done/mark_failed
- scheduler.py: trigger_yandex_detail_backfill_run + elif source=='yandex_detail_backfill'
в scheduler_loop; window 12-15 UTC (после avito_detail 09-12 UTC)
- migration 113: ADD COLUMN IF NOT EXISTS photo_urls jsonb, newbuilding_url text,
newbuilding_id text; seed scrape_schedules yandex_detail_backfill enabled=true
- tests: 10 тестов (8 backfill + 2 save_detail_enrichment); 1819 passed 0 failed
Closes #1553
2026-06-16 13:58:20 +03:00
1fc375c2cc
Merge pull request 'feat(scrapers): ночной avito detail-enrichment backfill для legacy listings ( Closes #1551 )' ( #1552 ) from feat/avito-detail-backfill into main
Deploy Trade-In / changes (push) Successful in 6s
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 34s
Deploy Trade-In / build-backend (push) Successful in 49s
Deploy Trade-In / deploy (push) Successful in 42s
2026-06-16 10:32:57 +00:00
227e82dc01
feat(tradein): avito detail-enrichment nightly backfill ( #1551 )
...
CI / changes (push) Successful in 7s
CI / backend-tests (push) Has been skipped
CI / frontend-tests (push) Has been skipped
CI / openapi-codegen-check (push) Has been skipped
CI / changes (pull_request) Successful in 6s
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
- New task app/tasks/avito_detail_backfill.py with run_avito_detail_backfill()
* Single snapshot SELECT at start (guarantees termination)
* Same proxy/AsyncSession path as scrape_pipeline.py step 5
* Budget guard (budget_sec), consecutive block abort (mark_done not mark_failed)
* rotate_ip() on every AvitoBlockedError; rollback on generic Exception (#1368 )
* start = time.monotonic() initialized before try so except can reference it
- Scheduler wiring: trigger_avito_detail_backfill_run() + elif in scheduler_loop()
- Migration 112: scrape_schedules INSERT window 09-12 UTC, batch_size=800,
budget_sec=3600, request_delay_sec=6, max_consecutive_blocks=5
- 7 unit tests (no pytest-mock, unittest.mock only): all 7 passing,
full CI suite 1809 passed
2026-06-16 13:25:29 +03:00