-- Extras-эндпойнты наш.дом.рф (sale_graph, sales_agg, infrastructure, photos) -- + журнал ошибок per-request для ручной проверки в браузере. -- См. план C:\Users\user\.claude\plans\crispy-waddling-swing.md. -- ── Time-series продаж per-ЖК (apartments + parking) ────────────────────── -- Источник: GET /сервисы/api/object/{obj_id}/sale_graph?type=apartments|parking CREATE TABLE IF NOT EXISTS domrf_kn_sale_graph ( obj_id BIGINT NOT NULL, report_month DATE NOT NULL, -- '01.04.2025' → 2025-04-01 type TEXT NOT NULL, -- 'apartments' | 'parking' realised INT, -- штук реализовано contracted INT, -- штук законтрактовано (ДКП) area_sq NUMERIC, -- м² за месяц price_avg NUMERIC, -- средняя цена ₽/м² snapshot_date DATE NOT NULL DEFAULT CURRENT_DATE, UNIQUE (obj_id, report_month, type, snapshot_date) ); CREATE INDEX IF NOT EXISTS idx_sg_obj ON domrf_kn_sale_graph (obj_id, snapshot_date); CREATE INDEX IF NOT EXISTS idx_sg_month ON domrf_kn_sale_graph (report_month, type); -- ── Текущие агрегаты per-ЖК (apartments + nonliv + parking) ─────────────── -- Источник: GET /сервисы/api/object/{obj_id}/sales_agg CREATE TABLE IF NOT EXISTS domrf_kn_sales_agg ( obj_id BIGINT NOT NULL, type TEXT NOT NULL, -- 'apartments'|'nonliv'|'parking' name TEXT, -- 'Квартира'|'Нежилое помещение'|'Машино-место' total INT, -- всего юнитов в ЖК realised INT, -- реализовано perc NUMERIC, -- sold % (server-calculated) snapshot_date DATE NOT NULL DEFAULT CURRENT_DATE, UNIQUE (obj_id, type, snapshot_date) ); CREATE INDEX IF NOT EXISTS idx_sa_obj ON domrf_kn_sales_agg (obj_id, snapshot_date); -- ── POI вокруг ЖК (нормализованная) ─────────────────────────────────────── -- Источник: GET /сервисы/api/object/{obj_id}/infrastructure CREATE TABLE IF NOT EXISTS domrf_kn_infrastructure ( obj_id BIGINT NOT NULL, poi_name TEXT NOT NULL, poi_subtitle TEXT, poi_category TEXT, -- tabName: Развлечения|Образование|... poi_address TEXT, poi_lat NUMERIC, poi_lon NUMERIC, distance_m NUMERIC, snapshot_date DATE NOT NULL DEFAULT CURRENT_DATE, UNIQUE (obj_id, poi_name, poi_lat, poi_lon, snapshot_date) ); CREATE INDEX IF NOT EXISTS idx_infra_obj ON domrf_kn_infrastructure (obj_id, snapshot_date); CREATE INDEX IF NOT EXISTS idx_infra_cat_dist ON domrf_kn_infrastructure (poi_category, distance_m); -- ── Фото-метаданные (binary в data/raw/domrf_photos/{obj_id}/{file_id}.png) ─ -- Источник: GET /сервисы/api/object/construction/progress/photo/{obj_id} CREATE TABLE IF NOT EXISTS domrf_kn_photos ( obj_id BIGINT NOT NULL, obj_file_id TEXT NOT NULL, -- DOM.РФ хеш-ID, идемпотентен ord_num INT, photo_url TEXT, -- абсолютный URL DOM.РФ photo_dttm TIMESTAMP, period_dt DATE, -- '2026-04-01' size_bytes BIGINT, photo_name TEXT, -- 'PRINZIP_43_new.jpg' ready_desc TEXT, -- 'Строится'/'Сдан' build_type TEXT, -- 'Жилое'/'Нежилое' hidden BOOLEAN, local_path TEXT, -- если binary скачан downloaded_at TIMESTAMPTZ, UNIQUE (obj_id, obj_file_id) ); CREATE INDEX IF NOT EXISTS idx_photos_obj ON domrf_kn_photos (obj_id, period_dt DESC); -- ── Журнал per-request ошибок для ручной проверки в браузере ────────────── CREATE TABLE IF NOT EXISTS kn_scrape_failures ( failure_id BIGSERIAL PRIMARY KEY, run_id BIGINT REFERENCES kn_scrape_runs(run_id) ON DELETE CASCADE, obj_id BIGINT, endpoint TEXT, -- 'sale_graph'|'sales_agg'|'infra'|'photos' full_url TEXT, -- полный URL для копирования в браузер http_status INT, error TEXT, body_preview TEXT, -- первые ~500 байт ответа occurred_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE INDEX IF NOT EXISTS idx_kn_fail_run ON kn_scrape_failures (run_id, occurred_at DESC); COMMENT ON TABLE domrf_kn_sale_graph IS 'Time-series продаж per-ЖК. /сервисы/api/object/{id}/sale_graph?type=apartments|parking'; COMMENT ON TABLE domrf_kn_sales_agg IS 'Текущие агрегаты per-ЖК. /сервисы/api/object/{id}/sales_agg'; COMMENT ON TABLE domrf_kn_infrastructure IS 'POI вокруг ЖК. /сервисы/api/object/{id}/infrastructure'; COMMENT ON TABLE domrf_kn_photos IS 'Фото прогресса стройки. /сервисы/api/object/construction/progress/photo/{id}'; COMMENT ON TABLE kn_scrape_failures IS 'Per-request ошибки парсера для ручной проверки full_url в браузере.';