96 lines
6.9 KiB
PL/PgSQL
96 lines
6.9 KiB
PL/PgSQL
-- 011_listings_alter.sql
|
||
-- ALTER TABLE listings — добавить ~30 полей для Avito detail page + domoteka (Росреестр)
|
||
--
|
||
-- Dependencies:
|
||
-- 002_core_tables.sql (listings table)
|
||
-- 009_houses.sql (houses table — FK house_id_fk)
|
||
--
|
||
-- Apply after: 009_houses.sql
|
||
-- Apply before: 012_sellers.sql, 013_listings_alter_seller.sql
|
||
--
|
||
-- Sources:
|
||
-- decisions/Schema_Avito_Houses_Listings_History.md sec 13 (listings ALTER)
|
||
-- decisions/Schema_Avito_Houses_Listings_History.md sec 29 (owners_count/owners_at_least)
|
||
--
|
||
-- Note: owners_2plus (boolean) из sec 13 заменён на owners_count + owners_at_least (sec 29).
|
||
-- Идемпотентно: ADD COLUMN IF NOT EXISTS безопасен при повторном запуске.
|
||
|
||
BEGIN;
|
||
|
||
ALTER TABLE listings
|
||
-- ── House linking ──────────────────────────────────────────────────────
|
||
ADD COLUMN IF NOT EXISTS house_source text, -- 'avito' / 'cian'
|
||
ADD COLUMN IF NOT EXISTS house_ext_id text, -- Avito's '3171365'
|
||
ADD COLUMN IF NOT EXISTS house_url text, -- /catalog/houses/<slug>/<id>
|
||
ADD COLUMN IF NOT EXISTS house_id_fk bigint REFERENCES houses(id),
|
||
ADD COLUMN IF NOT EXISTS listing_segment text, -- 'vtorichka' / 'novostroyki'
|
||
|
||
-- ── Характеристики квартиры (из detail page "О квартире") ─────────────
|
||
ADD COLUMN IF NOT EXISTS kitchen_area_m2 numeric(6,2),
|
||
ADD COLUMN IF NOT EXISTS balcony_loggia text, -- balcony/loggia/both/none
|
||
-- (заменяет has_balcony boolean для detail)
|
||
ADD COLUMN IF NOT EXISTS room_layout text, -- isolated/adjacent/mixed
|
||
ADD COLUMN IF NOT EXISTS bathroom_type text, -- combined/separate/both/multi
|
||
ADD COLUMN IF NOT EXISTS windows_view text, -- yard/street/both/park
|
||
|
||
-- ── Условия продажи ────────────────────────────────────────────────────
|
||
ADD COLUMN IF NOT EXISTS sale_type text, -- free/alternative/auction
|
||
ADD COLUMN IF NOT EXISTS mortgage_available boolean,
|
||
|
||
-- ── Метрики просмотров (Avito tracks viewership) ──────────────────────
|
||
ADD COLUMN IF NOT EXISTS views_total int,
|
||
ADD COLUMN IF NOT EXISTS views_today int,
|
||
ADD COLUMN IF NOT EXISTS publish_date date, -- "18 мая в 13:40" → 2025-05-18
|
||
|
||
-- ── Текстовое описание ─────────────────────────────────────────────────
|
||
ADD COLUMN IF NOT EXISTS description text, -- 1000+ chars обычно
|
||
|
||
-- ── Domoteka / Росреестр verification badges ──────────────────────────
|
||
-- Note: owners_2plus (boolean из sec 13) заменён на owners_count + owners_at_least (sec 29)
|
||
ADD COLUMN IF NOT EXISTS owners_count int, -- 1 = точно 1; 2 = '2 или больше'
|
||
ADD COLUMN IF NOT EXISTS owners_at_least boolean, -- true если Avito выдал "X или больше"
|
||
ADD COLUMN IF NOT EXISTS last_owner_change_date date, -- "Последняя смена собственника YYYY-MM-DD"
|
||
ADD COLUMN IF NOT EXISTS encumbrances_clean boolean, -- "Не найдены ограничения и обременения"
|
||
ADD COLUMN IF NOT EXISTS registry_match boolean, -- "Совпадают площадь, адрес и этаж"
|
||
|
||
-- ── Metro + location internal IDs ─────────────────────────────────────
|
||
ADD COLUMN IF NOT EXISTS metro_stations jsonb DEFAULT '[]'::jsonb,
|
||
-- [{"name":"Чкаловская","minutes":"11-15","mode":"walk"},...]
|
||
ADD COLUMN IF NOT EXISTS avito_location_id int, -- 654070 (ЕКБ internal ID)
|
||
|
||
-- ── Detail-page enrichment tracking ───────────────────────────────────
|
||
ADD COLUMN IF NOT EXISTS detail_enriched_at timestamptz; -- когда обогатили с detail page
|
||
|
||
-- Индексы для аналитических запросов
|
||
CREATE INDEX IF NOT EXISTS listings_house_ext_id_idx ON listings (house_source, house_ext_id)
|
||
WHERE house_ext_id IS NOT NULL;
|
||
CREATE INDEX IF NOT EXISTS listings_house_id_fk_idx ON listings (house_id_fk)
|
||
WHERE house_id_fk IS NOT NULL;
|
||
CREATE INDEX IF NOT EXISTS listings_kitchen_idx ON listings (kitchen_area_m2)
|
||
WHERE kitchen_area_m2 IS NOT NULL;
|
||
CREATE INDEX IF NOT EXISTS listings_views_idx ON listings (views_total DESC)
|
||
WHERE views_total IS NOT NULL;
|
||
-- Partial index для фильтра "без обременений" — используется estimator
|
||
CREATE INDEX IF NOT EXISTS listings_encumbrances_idx ON listings (encumbrances_clean)
|
||
WHERE encumbrances_clean = true;
|
||
-- Partial index для очереди detail-enrichment (пустой = нужно обогатить)
|
||
CREATE INDEX IF NOT EXISTS listings_detail_enrich_idx ON listings (detail_enriched_at)
|
||
WHERE detail_enriched_at IS NULL;
|
||
-- Partial index для "только с одним собственником" (clean title filter)
|
||
CREATE INDEX IF NOT EXISTS listings_owners_idx ON listings (owners_count)
|
||
WHERE owners_count IS NOT NULL;
|
||
|
||
COMMENT ON COLUMN listings.house_ext_id IS
|
||
'Avito house ID из /catalog/houses/<slug>/<id>. NULL для ~18% карточек без ссылки на дом.';
|
||
COMMENT ON COLUMN listings.balcony_loggia IS
|
||
'Тип балкона: balcony/loggia/both/none. Детальнее чем has_balcony (boolean). Из detail page.';
|
||
COMMENT ON COLUMN listings.owners_count IS
|
||
'Кол-во собственников из domoteka badge. 1=точно один; 2=''2 или больше'' (Avito скрывает точное для privacy).';
|
||
COMMENT ON COLUMN listings.owners_at_least IS
|
||
'true если badge содержит "X или больше" — значит owners_count является нижней границей.';
|
||
COMMENT ON COLUMN listings.metro_stations IS
|
||
'Список станций метро: [{"name":"Чкаловская","minutes":"11-15","mode":"walk"},...]. Из detail page.';
|
||
COMMENT ON COLUMN listings.detail_enriched_at IS
|
||
'Timestamp обогащения с detail page. NULL = ещё не обогащено (используется как queue flag).';
|
||
|
||
COMMIT;
|