1. deploy-tradein.yml: health-check раньше щупал только backend — сломанный
frontend (404 из-за basePath), упавший browser или crash-loop tgbot/scraper
помечались успешным деплоем без отката. Добавлены: frontend (curl изнутри
backend-контейнера на /trade-in/, basePath запечён в prod-образ), browser
(/health, живёт даже без поднятых camoufox-инстансов), tgbot/scraper
(docker inspect state=running с двойной проверкой — у них нет HTTP,
bare python-процессы). Проверяются только сервисы, реально входящие в
$SERVICES текущего деплоя.
2. docker-compose.prod.yml: backend (60s) и browser (90s) получили
stop_grace_period — раньше дефолтные docker 10s SIGKILL'или PDF-экспорт
(WeasyPrint write_pdf, sync route → Starlette threadpool, uvicorn
timeout_graceful_shutdown=None по умолчанию — единственный backstop это
Docker) и headless-навигацию browser (aiohttp shutdown_timeout=60s по
умолчанию + время на закрытие Firefox-инстансов в _on_cleanup) прямо
посреди работы.
3. _manifest_applied.txt: дописаны 173-186 (давно применены на проде,
contract-тест их не защищал от rename/rm). 187/188 (веб-чат поддержки)
НАМЕРЕННО не добавлены — прецедент в этом же репо (commit 5eadae1e, L5):
миграция, добавленная в manifest ДО того как осела на проде в финальном
виде, блокирует легитимный rename; фича ещё активно дорабатывается
параллельно.
Финальный PR issue #2045 (BE-3): GET /api/v1/trade-in/location-coef для
LocationDrawer. FDW foreign table -> локальное зеркало osm_poi_ekb_local
(TRUNCATE+INSERT, тот же паттерн что cad_buildings_local/cadastral_geo_match,
избегает ~1.16s/row FDW round-trip) -> straight-line POI-скоринг, портированный
из Site Finder poi_score.py::compute_poi_weighted_top7 (CATEGORY_WEIGHTS as-is,
радиус 1200м для квартир вместо Ptica 2000м для участков). score->coef -
новая MVP-эвристика (0.95..1.05, не откалибрована на реальных дельтах).
Graceful fallback (не 500, не фабрикуем факторы): пустая/не отрефрешенная
osm_poi_ekb_local или отсутствие lat/lon у оценки -> coef=1.0, factors=[],
geo_source="unavailable".
Scheduler: source=osm_poi_ekb_refresh, daily, зарегистрирован и в боевом
dispatch (scheduler.py), и в kit-registry (product_handlers.py) - иначе
test_kit_registry_completeness падает на ship-dark инварианте (#2192).
Frontend wiring (mappers.ts/LocationDrawer.tsx) - вне scope, отдельная задача
после проверки endpoint'а curl'ом на деплое.
- listings.phones: миграция 166 обнуляет данные; cian.py + scraper-kit
serp.py (golden-parity зеркало) перестают читать offer.get("phones") на
входе — write-path выключен у источника, колонка/поле в модели остаются.
Мёртвая запись "phones" в LISTING_FIELD_PRIORITY убрана.
- trade_in_estimates.client_name/client_phone: миграция 167 дропает колонки;
синхронно убраны из TradeInEstimateInput, обоих INSERT в estimator.py
(основной путь + _empty_estimate), frontend TradeInEstimateInput и
CRM-блока EstimateForm (поля "Имя клиента"/"Телефон").
- sentry_scrub.py и management_companies.phones не тронуты — вне scope.