79 lines
4.3 KiB
PL/PgSQL
79 lines
4.3 KiB
PL/PgSQL
-- 018_avito_imv_evaluations.sql
|
||
-- CREATE TABLE avito_imv_evaluations — кэш оценок Avito IMV API
|
||
--
|
||
-- Dependencies:
|
||
-- 001_trade_in_estimates.sql (trade_in_estimates table — FK estimate_id, nullable ON DELETE CASCADE)
|
||
--
|
||
-- Apply after: 017_house_placement_history.sql
|
||
-- Apply before: ничего (последняя миграция Stage 1)
|
||
--
|
||
-- Sources:
|
||
-- decisions/Schema_Avito_Houses_Listings_History.md sec 7 (avito_imv_evaluations DDL)
|
||
-- decisions/AvitoScraper_v2_Implementation_Plan.md (UPDATE: cache_key обязателен для Stage 3)
|
||
--
|
||
-- cache_key: sha256(address + rooms + area + floor + house_type + renovation + balcony + loggia)
|
||
-- TTL: 24 часа по cache_key (lookup в estimator перед вызовом IMV API)
|
||
-- IMV endpoint: POST /web/1/realty-imv/get-data (2 HTTP requests: coords/by_address → imv)
|
||
--
|
||
-- Идемпотентно: безопасно запускать повторно.
|
||
|
||
BEGIN;
|
||
|
||
CREATE TABLE IF NOT EXISTS avito_imv_evaluations (
|
||
id bigserial PRIMARY KEY,
|
||
estimate_id uuid REFERENCES trade_in_estimates(id) ON DELETE CASCADE,
|
||
|
||
-- Input snapshot (для cache lookup + аудита)
|
||
address text NOT NULL,
|
||
rooms int,
|
||
area_m2 numeric(8,2),
|
||
floor int,
|
||
floor_at_home int,
|
||
house_type text, -- panel/brick/monolith/monolith_brick/block/wood
|
||
renovation_type text, -- required/cosmetic/euro/designer
|
||
has_balcony boolean,
|
||
has_loggia boolean,
|
||
|
||
-- Geo (из /coords/by_address response)
|
||
geo_hash text, -- JWT token (для передачи в /realty-imv)
|
||
avito_address_id bigint,
|
||
avito_location_id bigint,
|
||
avito_metro_id int,
|
||
avito_district_id int,
|
||
lat double precision,
|
||
lon double precision,
|
||
|
||
-- Output (из /realty-imv/get-data → price block)
|
||
recommended_price bigint NOT NULL, -- price.recommendedPrice (центральная оценка)
|
||
lower_price bigint NOT NULL, -- price.lowerPrice (нижняя граница ~-3%)
|
||
higher_price bigint NOT NULL, -- price.higherPrice (верхняя граница ~+5%)
|
||
market_count int, -- price.count (кол-во активных в рынке)
|
||
|
||
-- Cache key (критично для on-demand cache — Stage 3)
|
||
-- sha256(address + rooms + area + floor + house_type + renovation_type + has_balcony + has_loggia)
|
||
cache_key text NOT NULL DEFAULT '',
|
||
|
||
raw_response jsonb, -- полный ответ /realty-imv/get-data для retrofit
|
||
fetched_at timestamptz NOT NULL DEFAULT NOW()
|
||
);
|
||
|
||
-- Основной index для on-demand cache lookup (Stage 3: get_or_fetch_imv)
|
||
CREATE INDEX IF NOT EXISTS imv_cache_key_idx ON avito_imv_evaluations (cache_key, fetched_at DESC);
|
||
CREATE INDEX IF NOT EXISTS imv_estimate_idx ON avito_imv_evaluations (estimate_id)
|
||
WHERE estimate_id IS NOT NULL;
|
||
CREATE INDEX IF NOT EXISTS imv_address_idx ON avito_imv_evaluations (address);
|
||
|
||
COMMENT ON TABLE avito_imv_evaluations IS
|
||
'Кэш оценок Avito IMV API. TTL 24h по cache_key. '
|
||
'IMV = POST /web/1/realty-imv/get-data. Вызывается только из estimator (НЕ из cron-scrape).';
|
||
COMMENT ON COLUMN avito_imv_evaluations.cache_key IS
|
||
'sha256(address + rooms + area + floor + house_type + renovation_type + has_balcony + has_loggia). '
|
||
'Используется для lookup с TTL 24h перед вызовом Avito API.';
|
||
COMMENT ON COLUMN avito_imv_evaluations.recommended_price IS
|
||
'Центральная оценка Avito IMV. Используется как external benchmark для валидации нашей median оценки.';
|
||
COMMENT ON COLUMN avito_imv_evaluations.market_count IS
|
||
'Кол-во активных объявлений в рынке по параметрам запроса (confidence indicator). 800+ = высокий.';
|
||
COMMENT ON COLUMN avito_imv_evaluations.geo_hash IS
|
||
'JWT token из /coords/by_address. Передаётся в /realty-imv/get-data как geoHash. TTL неизвестен.';
|
||
|
||
COMMIT;
|