-- Rosreestr open dataset: dataset_СДЕЛКИ (registered real estate deals).
-- Source: https://rosreestr.gov.ru/data-sets/{Q}%20квартал%20{YYYY}г./dataset_СДЕЛКИ_r-r_01-92_y_{YYYY}_q_{Q}.csv.zip
-- Encoding: UTF-8. Separator: '~' (since 2024 Q4) or ';' (2024 Q3 only).
-- Granularity: aggregated rows — same (region+district+city+cad_quarter+street+type+material+year+floor+purpose+area+doc_type) deals
-- collapsed into a single row with `deal_count` (was `number`) and AVERAGE price.
-- Time granularity: quarter (period_start_date = first day of quarter).
-- Coverage: ALL registered transactions (DKP=secondary+land+commercial, DDU=primary in МКД).
-- Excluded: gratuitous deals (gift/inheritance), buyer/seller PII, exact deal date, apartment number, room count, mortgage flag.
-- Data quality notes (observed in 7 loaded quarters):
--   * deal_price может быть мусорным с десятками знаков — фильтруем при INSERT
--   * year_build бывает с датой типа '09.07.1988' — оставляем NULL если не 4-цифровой год
--   * wall_material_code/realestate_type_code иногда '"code1;code2"' — поэтому TEXT вместо VARCHAR(15)

CREATE TABLE IF NOT EXISTS rosreestr_deals (
    id              BIGSERIAL,
    -- Origin
    source_quarter      VARCHAR(8)   NOT NULL,        -- '2024Q3' for traceability
    period_start_date   DATE         NOT NULL,        -- first day of the quarter (partition key)
    -- Geo
    region_code         SMALLINT     NOT NULL,        -- 66 = Свердловская обл, 77 = Москва, ...
    okato               TEXT,                         -- ОКАТО (often '-' or 11 digits)
    district            TEXT,                         -- муниципальный район/округ
    city                TEXT,                         -- населённый пункт (часто пустой)
    quarter_cad_number  VARCHAR(30)  NOT NULL,        -- '66:41:0506001' — гео-ключ для JOIN с ПКК / NSPD
    street              TEXT,
    -- Object
    realestate_type_code  TEXT,                       -- 002001001000=ЗУ | 002001002000=Здание | 002001003000=Помещение | 002001009000=Машиноместо
    wall_material_code    TEXT,                       -- справочник 126_УНСИ (может быть multi-value)
    purpose_code          TEXT,                       -- 66/67/148_УНСИ
    year_build            SMALLINT,
    floor                 TEXT,
    area                  NUMERIC,                    -- м²
    -- Deal
    doc_type            VARCHAR(8)   NOT NULL,        -- 'ДКП' | 'ДДУ'
    deal_price          NUMERIC,                      -- средняя если deal_count > 1
    currency            VARCHAR(20)  DEFAULT 'рубль',
    deal_count          INT          NOT NULL DEFAULT 1, -- было `number`
    -- Computed
    price_per_sqm       NUMERIC      GENERATED ALWAYS AS (
        CASE WHEN area > 0 AND deal_price > 0 THEN deal_price / area ELSE NULL END
    ) STORED,
    -- Audit
    loaded_at           TIMESTAMPTZ  NOT NULL DEFAULT NOW(),
    PRIMARY KEY (id, period_start_date)
) PARTITION BY RANGE (period_start_date);

-- Quarterly partitions for available data (2024 Q3 — 2026 Q1)
CREATE TABLE IF NOT EXISTS rosreestr_deals_2024q3 PARTITION OF rosreestr_deals
    FOR VALUES FROM ('2024-07-01') TO ('2024-10-01');
CREATE TABLE IF NOT EXISTS rosreestr_deals_2024q4 PARTITION OF rosreestr_deals
    FOR VALUES FROM ('2024-10-01') TO ('2025-01-01');
CREATE TABLE IF NOT EXISTS rosreestr_deals_2025q1 PARTITION OF rosreestr_deals
    FOR VALUES FROM ('2025-01-01') TO ('2025-04-01');
CREATE TABLE IF NOT EXISTS rosreestr_deals_2025q2 PARTITION OF rosreestr_deals
    FOR VALUES FROM ('2025-04-01') TO ('2025-07-01');
CREATE TABLE IF NOT EXISTS rosreestr_deals_2025q3 PARTITION OF rosreestr_deals
    FOR VALUES FROM ('2025-07-01') TO ('2025-10-01');
CREATE TABLE IF NOT EXISTS rosreestr_deals_2025q4 PARTITION OF rosreestr_deals
    FOR VALUES FROM ('2025-10-01') TO ('2026-01-01');
CREATE TABLE IF NOT EXISTS rosreestr_deals_2026q1 PARTITION OF rosreestr_deals
    FOR VALUES FROM ('2026-01-01') TO ('2026-04-01');

-- Indexes
CREATE INDEX IF NOT EXISTS rosreestr_deals_region_cq_idx
    ON rosreestr_deals (region_code, quarter_cad_number);
-- DROPPED 2026-05-14: BRIN on partitioned parent is dead weight — PG16 does
-- not propagate it to child partitions and idx_scan=0 confirmed zero usage.
-- See data/sql/89_drop_dead_brin_rosreestr_deals.sql for the removal migration.
-- CREATE INDEX IF NOT EXISTS rosreestr_deals_period_brin
--     ON rosreestr_deals USING BRIN (period_start_date);
CREATE INDEX IF NOT EXISTS rosreestr_deals_dealtype_idx
    ON rosreestr_deals (doc_type) WHERE doc_type IN ('ДКП', 'ДДУ');
CREATE INDEX IF NOT EXISTS rosreestr_deals_realtype_idx
    ON rosreestr_deals (realestate_type_code);

-- Staging: один общий unlogged-буфер. Перед каждым кварталом TRUNCATE.
CREATE UNLOGGED TABLE IF NOT EXISTS rosreestr_deals_staging (
    deal_count          INT,
    okato               TEXT,
    region_code         SMALLINT,
    district            TEXT,
    city                TEXT,
    quarter_cad_number  TEXT,
    street              TEXT,
    realestate_type_code  TEXT,
    wall_material_code    TEXT,
    year_build            TEXT,
    floor                 TEXT,
    purpose_code          TEXT,
    area                  NUMERIC,
    period_start_date   DATE,
    deal_price          NUMERIC,
    currency            VARCHAR(20),
    doc_type            VARCHAR(8)
);
