-- 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;