41e9c820c9
fix(tradein/estimator): ghost-anchor invariant guard — n_analogs=0 forces low (audit #1871 P1.2)
...
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
Audit #1871 P1.2: estimate 5fcc1e99 показывал confidence='high' при
n_analogs=0 (median 38.45M ₽, sources=['yandex_valuation']) при реальной
истории листингов дома 4.2-6.5M. По prod-DB это ЕДИНСТВЕННАЯ legacy-строка
от 2026-05-30, давно expired (TTL оценок = 1 день, все 66 high/medium-c-n<5
строк expired). Текущий mainline уже честен. Фикс — defensive invariant,
чтобы ghost не мог родиться снова из будущих external-valuation-blend /
rehydrate / migration путей.
Backend (estimator.py):
- helper _enforce_zero_analog_low(confidence, n_analogs, explanation, ...)
форсит 'low' + caveat когда n_analogs==0 and confidence!='low'.
Идемпотентен (low+0 → low без дубля caveat), не трогает high+N>0, реальный
median внешнего сервиса сохраняется (fake-коэффициенты не вводятся),
logger.warning для observability.
- Вызов перед сборкой AggregatedEstimate в estimate_quality (единственный
уязвимый return-путь; _empty_estimate хардкодит low — структурно безопасен).
- +5 unit-тестов (high+0→low+caveat, medium+0→low, low+0 идемпотент,
high+N unchanged, None-explanation).
Frontend (HeroSummary, HeroTransparency, history):
- effectiveConfidence = n_analogs===0 ? 'low' : confidence — defensive depth
на случай legacy-rehydrate / контракт-drift. Caveat-текст из backend
confidence_explanation (не хардкод). Type-safe (ConfidenceLevel).
Refs #1871
2026-06-23 11:05:34 +05:00
TradeIn Deploy
abafb60120
feat(tradein): рабочие страницы История и Кэш ( #399 )
...
Заглушки навбара (href=#) → рабочие страницы.
- GET /api/v1/trade-in/history — последние оценки из trade_in_estimates.
- GET /api/v1/trade-in/cache-stats — счётчики данных/кэшей.
- app/history/page.tsx — таблица прошлых оценок, ссылки на отчёты.
- app/cache/page.tsx — состояние данных (объявления, сделки, кадастр,
кэш геокодера, последний парсинг).
- navbar — ссылки История / Кэш ведут на страницы.
Closes #399
2026-05-22 11:28:27 +05:00