gendesign/tradein-mvp/backend/data/sql/017_house_placement_history.sql
lekss361 a2147872ed
All checks were successful
Deploy Trade-In / build-backend (push) Successful in 23s
Deploy Trade-In / deploy (push) Successful in 27s
Deploy Trade-In / changes (push) Successful in 5s
Deploy Trade-In / build-frontend (push) Has been skipped
feat(tradein): SQL migrations 009-018 — houses + listings extension + IMV cache (#440)
2026-05-23 11:41:44 +00:00

70 lines
3.9 KiB
PL/PgSQL
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

-- 017_house_placement_history.sql
-- CREATE TABLE house_placement_history — архив размещений из IMV API
-- (исторические объявления в конкретном доме, уже снятые с продажи)
--
-- Dependencies: 009_houses.sql (houses table — FK house_id, nullable)
-- Apply after: 016_listings_snapshots.sql
-- Apply before: 018_avito_imv_evaluations.sql
--
-- Source: decisions/Schema_Avito_Houses_Listings_History.md sec 6 (UPDATE 2026-05-23)
-- Key notes:
-- - photo_url НЕ сохраняем (требование 2026-05-23 "без картинок")
-- - removed_date заполняется ТОЛЬКО из IMV API (в widget housePlacementHistory его НЕТ)
-- - source = 'avito_imv' для данных из IMV API, 'avito' для данных из Houses Catalog widget
--
-- Идемпотентно: безопасно запускать повторно.
BEGIN;
CREATE TABLE IF NOT EXISTS house_placement_history (
id bigserial PRIMARY KEY,
source text NOT NULL, -- 'avito_imv' / 'avito'
house_id bigint REFERENCES houses(id), -- NULL если дом ещё не в houses table
-- Старый item ID (объявление уже снято → 404 на Avito)
ext_item_id text NOT NULL, -- e.g. '7489769108'
-- Описание (raw text + parsed fields)
title text, -- "1-к. квартира, 27,1 м², 2/5 эт."
rooms int,
area_m2 numeric(8,2),
floor int,
total_floors int,
-- Эволюция цены
start_price bigint, -- начальная ask price
start_price_date date, -- из unix timestamp startPriceDate
last_price bigint, -- финальная ask price (при снятии)
last_price_date date, -- из unix timestamp lastPriceDate
-- Дата снятия (ТОЛЬКО из IMV API — в widget housePlacementHistory отсутствует)
removed_date date, -- лучший proxy для deal_date
-- Точный days_on_market (от Avito, точнее нашего вычисления)
exposure_days int,
-- photo_url НЕ сохраняем (raw_payload содержит itemImage URL для retrofit)
raw_payload jsonb, -- полный объект из API
scraped_at timestamptz NOT NULL DEFAULT NOW(),
UNIQUE (source, ext_item_id)
);
CREATE INDEX IF NOT EXISTS hph_house_idx ON house_placement_history (house_id, last_price_date DESC)
WHERE house_id IS NOT NULL;
CREATE INDEX IF NOT EXISTS hph_source_item_idx ON house_placement_history (source, ext_item_id);
-- Для "comparable sales в заданный период"
CREATE INDEX IF NOT EXISTS hph_removed_idx ON house_placement_history (removed_date DESC)
WHERE removed_date IS NOT NULL;
COMMENT ON TABLE house_placement_history IS
'Архив снятых объявлений (proxy для сделок) из IMV API + Houses Catalog. '
'removed_date заполняется только из IMV API. photo_url не сохраняется.';
COMMENT ON COLUMN house_placement_history.removed_date IS
'Дата снятия объявления с продажи. Лучший proxy для deal_date. '
'ТОЛЬКО из IMV API (из widget housePlacementHistory это поле отсутствует).';
COMMENT ON COLUMN house_placement_history.house_id IS
'FK на houses.id. NULL если при scrape дом ещё не был в houses table. '
'Backfill через UPDATE ... WHERE ext_item_id IN (...) при первом scrape дома.';
COMMIT;