gendesign/tradein-mvp/backend
bot-backend aef17d1a6a
All checks were successful
CI Trade-In / changes (pull_request) Successful in 9s
CI / backend-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / browser-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 / frontend-checks (pull_request) Successful in 1m2s
CI Trade-In / backend-tests (pull_request) Successful in 4m23s
fix(tradein/dkp): «ФАКТИЧЕСКИЕ СДЕЛКИ» называют свой возраст, а не окно поиска
Плитка ДКП несла count/median/диапазон и молчала о том, когда эти сделки
случились. Молчание было осознанным: единственным кандидатом на подпись было
period_months — ОКНО ПОИСКА, и «за 24 месяца» при январских сделках было бы
хуже молчания (см. комментарий автора в mappers.ts). Но честное поле есть:
max(deal_date) по ОТОБРАННЫМ сделкам — его и добавляем.

Замер прода 2026-08-12 (только чтение):
  deals source='rosreestr': 96 974 строки, max(deal_date)=2026-01-01,
  9 различных дат, day-of-month=1 у 100%, месяцы ровно {01,04,07,10}
  → deal_date это метка КВАРТАЛЬНОЙ пачки, а не дата регистрации.
  Реплей выборок 881 реальной оценки за 90 суток:
    I кв. 2026 — 654 (74.2%) · нет коридора — 165 (18.7%) · IV кв. 2025 — 62 (7.0%)
  → у 8.7% выборок с коридором свежайшая сделка на КВАРТАЛ старше общего
    максимума таблицы: общий max на витрине был бы враньём в их пользу.

Отсюда форма подписи «по I кв. 2026», а не «223 дня назад»: возраст считается
от НАЧАЛА квартальной пачки, тогда как сделка внутри неё могла быть и 31 марта —
день был бы ложной точностью. «по», а не «за»: выборка накрывает несколько
кварталов, подпись называет верхнюю границу свежести.

- DkpCorridor.latest_deal_date — max по выборке, которая реально дала числа
  (включая city-wide widen: переезжают и числа, и дата вместе).
- Строка без ppm² не входит в границы коридора — не входит и в его возраст.
- Плитка v2: хвост «· по I кв. 2026» в существующей ppm-строке, отдельной
  строки не заводим. Каждая из трёх ветвей resolveDealTier тянет СВОЙ as-of —
  это три разные выборки, подпись описывает ту, чьи числа на экране.
- count=0 → «—» без подписи: датировать нечего.
- v1 HeroSummary печатал «{count} ДКП за {period_months} мес» — ту самую
  подмену окна возрастом; заменено на as-of.
- PDF §03 печатал «Период сделок: 08.2025 – 08.2026», где правый конец = сегодня;
  теперь «Сделки: по I кв. 2026» по показанным сделкам.

Роль коридора не менялась: он остаётся ADVISORY и не клампит оценку. Поправка
внешним ориентиром не тронута.

Refs #2846
2026-08-12 23:40:18 +05:00
..
app fix(tradein/dkp): «ФАКТИЧЕСКИЕ СДЕЛКИ» называют свой возраст, а не окно поиска 2026-08-12 23:40:18 +05:00
data/sql fix(tradein/imv): «временная» ошибка снова временная — 1390 домов возвращаются в очередь (#2843) 2026-08-12 16:06:24 +00:00
scripts fix(tradein/scraper): дневной снимок узнаёт свой прогон (#2701) (#2707) 2026-08-06 07:00:17 +00:00
tests fix(tradein/dkp): «ФАКТИЧЕСКИЕ СДЕЛКИ» называют свой возраст, а не окно поиска 2026-08-12 23:40:18 +05:00
.dockerignore feat: add tradein-mvp subproject (Trade-In Estimator под /trade-in) 2026-05-21 00:25:39 +03:00
Dockerfile feat(tradein): версионирование продукта — единый источник, подвал, PDF, /versions (#2824) 2026-08-10 16:00:54 +00:00
pyproject.toml feat(tradein/auth): password hashing + session config foundation (#2550) 2026-07-30 09:40:51 +03:00