gendesign/data/sql/60_v_zk_rosreestr_velocity.sql
lekss361 25b73035a1 sprint1: nspd scraper industrialization, per-bucket elasticity, cadastre cross-check, sentry releases
- NSPD-skraper переехал в backend/app/services/scrapers/nspd_kn.py +
  Celery task scrape_nspd_region (beat: 20-е февраля/мая/авг/нояб).
  Redis lock 3h, WAF auto-retry, heartbeat в nspd_scrape_runs.
- Recommend_mix Tier 3: per-bucket elasticity через регрессию по
  «доминирующему bucket» каждого ЖК. Weighted-elasticity для inverse-mode.
  UI показывает разброс эластичностей и переключение regression/fallback.
- Cadastre vs market cross-check: spatial-join cad_buildings →
  ekb_districts_geom; cadastre_vs_market_pct в scope, аномалии
  (>+50% / <-30%) подсвечены в UI.
- Sentry release tracking (#4): IMAGE_TAG → backend/.env.runtime →
  sentry_sdk.init(release=...). Compose v2 env_file optional path.

Schemas: 63_schema_nspd_runs.sql (cad_buildings + nspd_scrape_runs/log
формализуют то, что уже жило в проде через 61_import_nspd_batch.py),
64_v_zk_rosreestr_velocity.sql (refresh с cad_buildings).
2026-04-30 21:51:19 +03:00

83 lines
4.1 KiB
SQL
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.

-- View: per-ЖК velocity и средняя цена через rosreestr-сделки в cad-квартале,
-- распределённые пропорционально flat_count.
--
-- Логика: rosreestr_deals не имеет obj_id, но имеет quarter_cad_number.
-- domrf_kn_objects.cad_quarter заполнен через spatial-join (см. 59).
-- Для каждого квартала: суммируем сделки за 12 мес, распределяем по ЖК
-- внутри квартала пропорционально их flat_count.
--
-- estimated_velocity_pm — оценка скорости продаж конкретного ЖК (кв/мес).
-- estimated_price_th_per_m2 — медианная цена сделок в квартале (тыс. ₽/м²).
--
-- ВАЖНО: это АППРОКСИМАЦИЯ. Если в одном квартале несколько ЖК, доли точные
-- только когда они продают равномерно. Для крупных одиночных ЖК (квартал
-- содержит только их) — точно.
CREATE OR REPLACE VIEW v_zk_rosreestr_velocity AS
WITH zk_pool AS (
-- Берём последний snapshot каждого активного ЖК.
SELECT DISTINCT ON (o.obj_id)
o.obj_id,
o.comm_name,
o.dev_name,
o.district_name,
o.flat_count,
o.cad_quarter,
o.obj_class
FROM domrf_kn_objects o
WHERE o.region_cd = 66
AND o.cad_quarter IS NOT NULL
AND o.flat_count IS NOT NULL
AND o.flat_count > 0
AND o.site_status = 'Строящиеся'
ORDER BY o.obj_id, o.snapshot_date DESC
),
quarter_totals AS (
-- Сумма flat_count активных ЖК в каждом квартале (denominator для split).
SELECT cad_quarter, SUM(flat_count)::numeric AS total_flats
FROM zk_pool
GROUP BY cad_quarter
),
quarter_deals AS (
-- Rosreestr-сделки за 12 мес по каждому кварталу.
SELECT quarter_cad_number AS cad_quarter,
COUNT(*) AS deals_12mo,
AVG(price_per_sqm) AS avg_price_pm,
PERCENTILE_CONT(0.5) WITHIN GROUP
(ORDER BY price_per_sqm) AS median_price_pm,
AVG(area) AS avg_area_sqm
FROM rosreestr_deals
WHERE region_code = 66
AND doc_type = 'ДДУ'
AND realestate_type_code = '002001003000'
AND area > 10 AND area <= 200
AND price_per_sqm BETWEEN 30000 AND 1000000
AND period_start_date >= NOW() - INTERVAL '12 months'
GROUP BY quarter_cad_number
)
SELECT
z.obj_id,
z.comm_name,
z.dev_name,
z.district_name,
z.obj_class,
z.flat_count,
z.cad_quarter,
qt.total_flats AS quarter_total_flats,
qd.deals_12mo AS quarter_deals_12mo,
-- estimated deals = quarter_deals × my_flats / quarter_total_flats
ROUND(qd.deals_12mo * z.flat_count::numeric / qt.total_flats, 1)
AS estimated_deals_12mo,
ROUND(qd.deals_12mo * z.flat_count::numeric / qt.total_flats / 12.0, 2)
AS estimated_velocity_pm,
ROUND(qd.median_price_pm / 1000.0, 1) AS median_price_th_per_m2,
ROUND(qd.avg_area_sqm, 1) AS avg_deal_area_sqm
FROM zk_pool z
JOIN quarter_totals qt ON qt.cad_quarter = z.cad_quarter
JOIN quarter_deals qd ON qd.cad_quarter = z.cad_quarter
;
COMMENT ON VIEW v_zk_rosreestr_velocity IS
'Per-ЖК аппроксимация скорости продаж и медианной цены через rosreestr_deals '
'квартала, распределённые по ЖК пропорционально flat_count. Источник для '
'cross-validation domrf_kn_sale_graph и обнаружения ЖК-аутлайеров.';