Some checks failed
CI Trade-In / changes (pull_request) Successful in 8s
CI / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Failing after 1m56s
CI / backend-tests (pull_request) Successful in 14m37s
Ранний сигнал future-supply: разрешения на строительство появляются в ГИСОГД до проектных деклараций ЕИСЖС. Старый minstroy-путь мёртв (WAF), портал gisogd66.midural.ru отдаёт открытый JSON-API без авторизации. Миграция 187_gisogd_permits (RS+RV, UNIQUE(doc_group,doc_num), GIST geom 4326, GIN cad_nums) + инкрементальный httpx-лоадер (схемы agate_ekbgo + agate_sverdregion, сверка по (source_key,date_reg), карточки только для новых/изменённых, SAVEPOINT per-row, WHERE-гейт предпочтения позднего date_reg) + Celery weekly (вт 06:30 МСК, limit 3600/3300) + on-demand admin-триггер + freshness-реестр (data-table, 14/45). Refs #2367
99 lines
7.5 KiB
PL/PgSQL
99 lines
7.5 KiB
PL/PgSQL
-- 187_gisogd_permits.sql
|
||
-- Forgejo #2367 PR-1 (Schema) — реестр разрешений на строительство (РНС) и ввод
|
||
-- в эксплуатацию (РВЭ) Свердловской области из ОТКРЫТОГО API ГИСОГД-СО.
|
||
--
|
||
-- Одна таблица gisogd_permits: карточки документов раздела 13 («Сведения о
|
||
-- документах в деле о земельном участке») региональной ГИС органов гос. власти
|
||
-- Свердловской области (gisogd66.midural.ru). Открытый JSON-API без авторизации.
|
||
--
|
||
-- Источник (карточки/списки) отдаёт данные без гео-блокировки (bare curl 200), но
|
||
-- код лоадера всё равно держим устойчивым к отсутствию полей (spatialUnit / geometry
|
||
-- у части документов отсутствуют — hasGeometry=false).
|
||
--
|
||
-- Две схемы источника:
|
||
-- agate_ekbgo — ЕКБ, самая свежая выгрузка;
|
||
-- agate_sverdregion — регион-агрегат, отстаёт ~неделю.
|
||
-- Один документ может встретиться в ОБЕИХ схемах → бизнес-ключ = (doc_group, doc_num);
|
||
-- при конфликте предпочитаем запись с более поздним date_reg (лоадер, PR-2).
|
||
--
|
||
-- doc_group:
|
||
-- 'RS' — Разрешение на строительство (группа источника DocRS);
|
||
-- 'RV' — Разрешение на ввод в эксплуатацию (группа источника DocRV).
|
||
--
|
||
-- cad_nums — распарсенный spatialUnit (может быть НЕСКОЛЬКО кадастровых номеров
|
||
-- через запятую, может отсутствовать → пустой массив). geom — из infosetGeoJson
|
||
-- (GeoJSON Polygon WGS84 lon/lat, лоадер приводит к MultiPolygon), NULL когда
|
||
-- hasGeometry=false. source_schema/source_key фиксируют, откуда прилетела запись
|
||
-- (для инкрементальной сверки по (source_schema, source_key, date_reg)).
|
||
--
|
||
-- Порядок применения: миграция ПЕРЕД деплоем кода (schema-first, sql.md).
|
||
-- Таблица НОВАЯ → deploy.yml гоняет всё в одной транзакции; CREATE INDEX
|
||
-- CONCURRENTLY здесь не нужен (и запрещён внутри транзакции).
|
||
|
||
BEGIN;
|
||
|
||
-- ── gisogd_permits ────────────────────────────────────────────────────────────
|
||
CREATE TABLE IF NOT EXISTS gisogd_permits (
|
||
id BIGSERIAL PRIMARY KEY,
|
||
doc_group TEXT NOT NULL, -- 'RS' (РНС) | 'RV' (РВЭ) — см. CHECK
|
||
doc_num TEXT NOT NULL, -- № документа, напр. «66-45-08-2026» (strip'нут)
|
||
doc_name TEXT, -- name карточки, напр. «Разрешение на строительство № … от …»
|
||
date_doc DATE, -- dateDoc — дата выдачи документа
|
||
date_reg DATE, -- dateReg — дата регистрации в реестре (для conflict-резолва)
|
||
approved_organization TEXT, -- approvedOrganization — выдавший орган
|
||
source_schema TEXT NOT NULL, -- 'agate_ekbgo' | 'agate_sverdregion'
|
||
source_key TEXT NOT NULL, -- key карточки в схеме источника (для инкрементальной сверки)
|
||
cad_nums TEXT[] NOT NULL DEFAULT '{}', -- распарсенный spatialUnit ('{}' если нет)
|
||
geom GEOMETRY(MultiPolygon, 4326), -- из infosetGeoJson; NULL если hasGeometry=false
|
||
fetched_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||
|
||
-- Только 'RS'/'RV' допустимы (защита от опечаток в лоадере).
|
||
CONSTRAINT chk_gisogd_permits_doc_group CHECK (doc_group IN ('RS', 'RV')),
|
||
|
||
-- Бизнес-ключ: один документ (группа + номер) хранится ОДНОЙ строкой, даже если
|
||
-- прилетел из обеих схем. Лоадер UPSERT-ит по нему, предпочитая поздний date_reg.
|
||
UNIQUE (doc_group, doc_num)
|
||
);
|
||
|
||
-- Пространственный индекс — §-запросы «РНС/РВЭ рядом с участком».
|
||
CREATE INDEX IF NOT EXISTS gist_gisogd_permits_geom
|
||
ON gisogd_permits USING GIST (geom);
|
||
|
||
-- GIN по массиву кадастровых номеров — матч «разрешение на этом участке».
|
||
CREATE INDEX IF NOT EXISTS gin_gisogd_permits_cad_nums
|
||
ON gisogd_permits USING GIN (cad_nums);
|
||
|
||
-- Дата документа — фильтры/сортировки по свежести разрешений.
|
||
CREATE INDEX IF NOT EXISTS idx_gisogd_permits_date_doc
|
||
ON gisogd_permits (date_doc DESC);
|
||
|
||
COMMENT ON TABLE gisogd_permits IS
|
||
'Реестр разрешений на строительство (РНС) и ввод в эксплуатацию (РВЭ) '
|
||
'Свердловской области из открытого API ГИСОГД-СО (gisogd66.midural.ru, раздел 13). '
|
||
'Бизнес-ключ (doc_group, doc_num); при конфликте двух схем источника '
|
||
'(agate_ekbgo / agate_sverdregion) предпочитается поздний date_reg. Refresh: weekly '
|
||
'/ on-demand. Forgejo #2367.';
|
||
|
||
COMMENT ON COLUMN gisogd_permits.doc_group IS
|
||
'''RS'' = разрешение на строительство (группа источника DocRS), '
|
||
'''RV'' = разрешение на ввод в эксплуатацию (группа источника DocRV).';
|
||
|
||
COMMENT ON COLUMN gisogd_permits.cad_nums IS
|
||
'Распарсенный spatialUnit карточки: список кадастровых номеров (несколько через '
|
||
'запятую в источнике). Пустой массив ''{}'' когда spatialUnit отсутствует или все '
|
||
'значения не прошли валидацию формата кадастрового номера.';
|
||
|
||
COMMENT ON COLUMN gisogd_permits.geom IS
|
||
'MultiPolygon (WGS84) из infosetGeoJson карточки (Polygon приведён к MultiPolygon '
|
||
'лоадером). NULL когда hasGeometry=false / infosetGeoJson отсутствует.';
|
||
|
||
COMMENT ON COLUMN gisogd_permits.source_schema IS
|
||
'Схема источника, из которой прилетела запись: ''agate_ekbgo'' (ЕКБ, свежая) или '
|
||
'''agate_sverdregion'' (регион-агрегат, отстаёт ~неделю).';
|
||
|
||
COMMENT ON COLUMN gisogd_permits.source_key IS
|
||
'key карточки в схеме источника. Вместе с (source_schema, date_reg) используется '
|
||
'лоадером для инкрементальной сверки: карточки тянутся только для новых/изменённых.';
|
||
|
||
COMMIT;
|