fix(tradein/estimator): scope year_built NULL cohort-bypass away from avito (#2013) #2474

Closed
bot-backend wants to merge 1 commit from fix/2013-avito-cohort-null into main

1 commit

Author SHA1 Message Date
bot-backend
e042e9bbfd fix(tradein/estimator): scope year_built NULL cohort-bypass away from avito (#2013)
Some checks failed
CI Trade-In / changes (pull_request) Successful in 10s
CI / changes (pull_request) Successful in 10s
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) Failing after 54s
Cohort/era WHERE clause carried `OR year_built IS NULL`, meant to let avito's
frequently-missing year_built field through the filter. In practice this let
ANY-era avito listing bypass the cohort filter entirely once cohort_year_min/
max were set — pollution bug: khrushchevka target could pull in a modern avito
comp with no year parsed, and vice versa.

Narrow the escape to `OR (year_built IS NULL AND source <> 'avito')` in both
places that must stay in sync:
- _COMMON_WHERE (Tier S/H, ~estimator.py:4210)
- Tier W inline SQL copy (~estimator.py:4640)

Non-avito NULL-year rows (cian/domklik/etc without a parsed year) still pass
through untouched; avito NULL-year rows now must satisfy the same
year_built BETWEEN cohort_year_min AND cohort_year_max test as everything
else.

Added tests/test_estimator_avito_cohort_null_2013.py: SQL-source assertions
that both cohort blocks carry the new guard, stay in sync (exactly 2
occurrences), and that the old unscoped escape is gone. A full DB-backed
integration test was impractical — this suite's estimator tests run against
a dummy DATABASE_URL with no live DB.
2026-07-12 15:22:32 +03:00