Backfill 18,428 listings against an empty houses table:
- INSERT Avito/CIAN-sourced houses (~562 unique via house_source+house_ext_id)
- INSERT derived houses for remaining listings (group by tradein_normalize_short_addr,
synthetic ext_house_id = sha256 truncated to 32 hex chars) → ~6102 derived
- UPDATE listings.house_id_fk by both paths (direct: 2997, fuzzy: 15200)
- Best-effort relink orphan house_placement_history via raw_payload.address (0 rows)
Syntax-validated live: 6664 houses, 18197/18428 listings linked (98.8%).
Idempotent (ON CONFLICT DO NOTHING, WHERE house_id_fk IS NULL).
Logs result counters via RAISE NOTICE.
Phase C (Avito IMV history scrape per house) deferred to separate Celery job.