feat(tradein/zhkh): ЖКХ-приоритет знаменателя «квартир в доме» + loader
ГАР дико недосчитывает квартиры в МКД (прод-замер: Крауля 89А ГАР=11 vs
ЖКХ=429; 27 из 347 домов ГАР ≥2× недосчёт). ГИС ЖКХ точнее — резолвит ~90%
вторички с gar_house_guid.
- мигр.149: COALESCE знаменателя → ЖКХ ПЕРВЫЙ
(zhkh_flat_count, gar_flat_count, total_units, flat_count) во всех 7 местах
view v_building_sale_share; +houses.zhkh_year/zhkh_floors_raw; +transparency-
колонки zhkh_flat_count/flat_count_source.
- app/services/zhkh_flats_loader.py + app/tasks/zhkh_flats_load.py: фетч ГИС ЖКХ
searchByAddress (батч ≤100 по gar_house_guid == ЖКХ houseGuid, pageIndex=1,
cookieless), идемпотентный UPDATE houses.zhkh_* (CAST(:x AS type) +
IS DISTINCT FROM gate, SAVEPOINT-чанки, dry-run).
Безопасно к мержу: до ручного прогона loader'а zhkh_flat_count=NULL → COALESCE
падает на ГАР → поведение идентично до-149. ruff clean, pytest 8 green.