gendesign/tradein-mvp/backend/app/api/v1
bot-backend 37ea0b0f5b fix(tradein/cian): персистить bti_data и valuation house_info в houses (#2435)
Cian secondary-market detail (bti_data) и Valuation Calculator (house_info/
managementCompany/houseId) парсились, но выбрасывались — комментарий "это
задача Stage 6 (houses)" так и не был выполнен.

- cian/detail.py::save_detail_enrichment принимает инжектируемый matcher
  (HouseMatcher, optional) → новый _persist_cian_bti_house резолвит дом через
  match_or_create_house (address/geo листинга, mirror avito/houses.py::
  _persist_house) и пишет BTI-эксклюзивные колонки из 020_houses_alter_cian.sql
  (series_name/entrances/flat_count/is_emergency/heat_supply_type/
  gas_supply_type/overlap_type) через COALESCE(new, existing).
- cian/valuation.py::_save_to_cache получает уже резолвленный house_id (read-only
  match_house_readonly, estimator.py) → новый _persist_cian_valuation_house пишет
  management_company_id (UPSERT management_companies) + cian_internal_house_id
  (filters.houseId) COALESCE(new, existing), плюс houseInfo.items-производные
  поля (год/тип/этажность/газ/отопление/перекрытия/подъезды/квартиры/
  аварийность/детская площадка/лифты) COALESCE(existing, new) — валюация не
  авторитетный источник для них (conflict_resolution.HOUSE_FIELD_PRIORITY).
- Оба пути best-effort: SAVEPOINT (db.begin_nested) изолирует сбой резолва/
  записи дома от основной save-транзакции; house_id=None / matcher=None /
  безномерный адрес (P1 no_house_number) — graceful no-op, без исключений.
- matcher прокинут в реальные call sites: pipeline.py (cian city-sweep +
  full-load — уже был в scope), cian_history_backfill.py, cian_price_history.py,
  admin.py ad-hoc endpoint.

Gap (нет чистого маппинга на существующую колонку houses — не создавали новых
колонок): bti.houseData.{demolishedInMoscowProgramm, heatIndex,
houseOverhaulFundType, lifts (недифференцированный total)}; houseInfo.items
{Мусоропровод, Реновация, Спортивная площадка, Фонд капремонта}.

10 новых тестов (tests/test_cian_bti_house_persist.py), MagicMock db, без
реальной БД — mirror test_snapshot_writer.py / test_extval_house_id_write_path.py.
2026-07-04 22:56:36 +03:00
..
__init__.py feat: add tradein-mvp subproject (Trade-In Estimator под /trade-in) 2026-05-21 00:25:39 +03:00
admin.py fix(tradein/cian): персистить bti_data и valuation house_info в houses (#2435) 2026-07-04 22:56:36 +03:00
brand.py feat: add tradein-mvp subproject (Trade-In Estimator под /trade-in) 2026-05-21 00:25:39 +03:00
buildings.py feat(tradein): второй % «за 45 дней» + zhkh-знаменатель slot (146) (#2071) 2026-06-28 17:51:38 +00:00
geocode.py feat(tradein/matching): fias_exact tier + estimate fias persist + suggest fias_id contract 2026-07-02 20:49:04 +03:00
lead.py feat(tradein/lead): POST /api/v1/trade-in/lead — persist contact leads (#2376) (#2390) 2026-07-04 07:12:22 +00:00
me.py feat(rbac): role-based access control via X-Authenticated-User middleware (#585) 2026-05-26 06:18:40 +00:00
search.py fix(week-review): автофиксы код-ревью — 169 issue (label «week ревью 1») 2026-06-15 20:21:11 +05:00
trade_in.py feat(tradein/history): вернуть все параметры оценки в GET /history (#2420) 2026-07-04 13:09:22 +00:00