Четыре правки HOLD-ревью PR #2732, форма таблиц не меняется:
1. Коллизия номера: 232_listings_observation_time_meaning.sql несёт открытый
PR #2742 (не main, поэтому пропущено в прошлый раз). Переименовано 232 ->
233 (git mv, история сохранена), manifest обновлён. Урок задокументирован
в шапке файла: сверять номер нужно по main И по всем открытым PR-веткам.
Перепроверено дважды (main + 5 остальных открытых веток) — 233 свободен.
2. payments_status_check дополнен пятью реальными in-flight статусами из
канонического источника (OpenAPI-спека developer.tbank.ru/schemas/eacq/
openapi.yaml, схема Confirm-2, v1.24): CHECKING, CHECKED, PROCESSING,
COMPLETING, COMPLETED. Это статусы, которые GetState/CheckOrder вернёт по
зависшему платежу — их читает реконсиляция PR-E; пропуск реального
значения был единственным опасным направлением ошибки CHECK.
3. Блок про источник статусов переписан: убрана ссылка на сторонний Go-клиент
и формулировка "enum рендерится клиентским JS" — источник истины теперь
openapi.yaml. Отдельно зафиксировано: GetState/CheckOrder объявляют Status
свободной строкой (maxLength: 20, без enum) — наш CHECK строже контракта
поставщика, осознанно.
4. Контракт 'UNKNOWN' переадресован: теперь явно на обработчик нотификаций
И задачу реконсиляции (GetState/CheckOrder, PR-E), а не только на вебхуки.
Побочно подтверждено спекой: AUTHORIZED_AND_CHARGED/RECEIPT_REGISTERED
отсутствуют (плюс maxLength:20 делает первое физически невозможным);
3DS_CHECKING/3DS_CHECKED и PREAUTHORIZING есть; ATTEMPTS_EXPIRED/PAY_CHECKING
нет; PARTIAL_REVERSED/REFUND_FAILED тоже нет в спеке — оставлены как
безвредный запас, комментарий перестал ложно утверждать обратное.
Полный pytest: 3858 passed, 10 skipped, 0 failed.
Пока PR был на ревью, в main влились 228_scrape_proxies_browser_health.sql
и 230_house_merge_log.sql — номер 228 занят, 229/231 параллельно занимает
PR #2547. Переименовано в 232_payments.sql (git mv, история файла сохранена),
manifest обновлён (228_payments.sql -> 232_payments.sql), шапка миграции
объясняет причину переименования и актуализирован "Apply after".
Смержен свежий forgejo/main (обычный merge, без rebase/force-push) —
конфликтов не было, config.py не задет. test_new_files_do_not_reuse_prefix
теперь зелёный. Полный pytest после merge: 3858 passed, 10 skipped, 0 failed.
Финальный 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.