gendesign/tradein-mvp/backend/app/services
bot-backend ac99886201
All checks were successful
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
fix(tradein/estimator): remove dead tier-aware-ratio path — truncation artifact + footgun (#2002)
The tier_aware_ratio_enabled path (#928) binned SOLD deals by sold-ppm² against
ASKING-derived percentile bounds, then divided within-tier medians. That is a
ratio-of-truncated-medians ARTIFACT: a Monte-Carlo with a CONSTANT true
sold/asking=0.84 reproduced the prod tier values (0.94/0.99/0.96) and the skewed
deal split (57/27/15%) exactly — the "premium sells closer to asking" gradient is
100% spurious. Flipping the flag ON made prod WORSE (overall MAPE 14.6→17.2,
эконом bias +5.8→+18.1). It shipped dark (default False) but is a latent footgun.

A valid within-price-tier sold/asking is uncomputable from asking-less ДКП deals;
the per-rooms blend + the shipped hedonic (year+area) are the correct conditioning.
So the dead path is removed entirely, not just disabled.

- estimator._get_asking_sold_ratio: drop the tier branch (bounds read, t33/t66,
  asking_to_sold_ratios_tiered read, empirical-Bayes shrink) + the _legacy/tier
  cache-key split; keep only the legacy per-rooms → global -1 lookup. Cache key
  collapses to rooms bucket. anchor_ppm2 param retained for call-site compat (now
  unused).
- config: remove tier_aware_ratio_enabled + tier_ratio_shrink_k settings.
- tasks/asking_to_sold_ratio: drop the tiered refresh (DELETE/re-derive bounds +
  tier rows, tiered counters); the daily task no longer touches the dead tier
  tables. Legacy asking_to_sold_ratios DELETE+re-derive intact.
- tests: delete the tier-ratio unit test file (legacy path covered by
  test_estimator_expected_sold.py Layer 1); fix the daily-refresh fake-db
  (8→3 execute calls, 3 counter keys); drop the two segment-guard tests that
  asserted the removed tiered SQL; clean a dead per_rooms_tier basis in fixtures.

Tier tables asking_to_sold_ratios_tiered / asking_to_sold_tier_bounds + migration
098 are left in place (inert once nothing reads/writes them); a DROP migration is
a separate, optional follow-up.

Regression gate stays byte-identical (flag was False in prod → active path
unchanged). Refs #2002
2026-06-27 20:31:49 +03:00
..
exporters fix(tradein): trade-in PDF cover uses estimate.expires_at, not hardcoded +30d (#1530) 2026-06-17 20:27:57 +03:00
matching fix(matching): conflict_resolution picks freshest (last_seen_at) value, deterministic (#1539) 2026-06-17 22:43:59 +03:00
scrapers feat(tradein/domclick): enrich Layer A SERP parser — description, repair-inference, minhash, seller 2026-06-27 16:35:25 +03:00
__init__.py feat: add tradein-mvp subproject (Trade-In Estimator под /trade-in) 2026-05-21 00:25:39 +03:00
account_quota.py fix(tradein): atomic conditional quota increment — close TOCTOU (#747) (#749) 2026-05-30 15:52:34 +00:00
brand.py feat: add tradein-mvp subproject (Trade-In Estimator под /trade-in) 2026-05-21 00:25:39 +03:00
cache.py feat(tradein): Phase 3.2 — /api/v1/search endpoint + Redis cache (#479) 2026-05-23 14:44:22 +00:00
cian_price_history.py fix(week-review): автофиксы код-ревью — 169 issue (label «week ревью 1») 2026-06-15 20:21:11 +05:00
cian_session.py feat(tradein): dedicated Cian mobile proxy — separate egress from Avito (#923) 2026-05-31 19:30:14 +00:00
dadata.py fix(week-review): автофиксы код-ревью — 169 issue (label «week ревью 1») 2026-06-15 20:21:11 +05:00
estimator.py fix(tradein/estimator): remove dead tier-aware-ratio path — truncation artifact + footgun (#2002) 2026-06-27 20:31:49 +03:00
geocoder.py fix(tradein): drop non-EKB avito detail coords on ingest (audit #1871 P2) 2026-06-23 14:33:10 +05:00
house_dedup_merge.py feat(tradein): recurring house-dedup merge (schedule dormant) (#1772) (#1933) 2026-06-26 21:39:30 +00:00
house_imv_backfill.py feat(tradein-imv): route IMV backfill через BrowserFetcher.fetch_json за dormant-флагом (#915 Stage 3) (#1916) 2026-06-26 09:54:28 +00:00
house_metadata.py feat(tradein): postgres_fdw live read of gendesign.cad_buildings (replaces snapshot) (#493) 2026-05-24 08:57:30 +00:00
image_sanitizer.py fix(week-review): автофиксы код-ревью — 169 issue (label «week ревью 1») 2026-06-15 20:21:11 +05:00
rosreestr_poll.py feat(tradein): scheduled monthly Rosreestr new-quarter poll → ingest alert (#888) (#894) 2026-05-31 13:13:55 +00:00
sber_index.py fix(tradein): correct SberIndex hedonic/asking dataset-paths + 404 warning (#902) 2026-06-17 22:50:52 +03:00
scheduler.py feat(tradein): recurring house-dedup merge (schedule dormant) (#1772) (#1933) 2026-06-26 21:39:30 +00:00
scrape_pipeline.py fix(tradein/domclick): rewrite dead scraper to BFF JSON API + honest status (#1846, #1968) 2026-06-27 13:57:07 +03:00
scrape_runs.py fix(tradein): persist scrape_runs.total_seen/new_count from sweep counters (#1926) (#1928) 2026-06-26 18:09:17 +00:00
scraper_settings.py chore(tradein): деактивировать N1.ru scraper — источник переехал в Cian 2026-06-16 14:50:51 +03:00
search_query.py feat(tradein): segment=vtorichka|novostroyki|all query-param on listings (#1188) 2026-06-17 21:43:01 +03:00
yandex_address_backfill.py fix(tradein): yandex address-enrich — city-agnostic title regex (спутники ЕКБ) (#875) 2026-05-31 09:08:29 +00:00
yandex_price_history.py feat(tradein): populate offer_price_history for yandex from gate price.previous/trend 2026-06-18 14:23:23 +03:00