gendesign/data/sql/138_ekb_ppt_tep.sql
lekss361 1e53416277
All checks were successful
Deploy / changes (push) Successful in 7s
Deploy / build-backend (push) Successful in 1m29s
Deploy / build-frontend (push) Has been skipped
Deploy / build-worker (push) Successful in 2m27s
Deploy / deploy (push) Successful in 1m21s
feat(sf): ППТ/ПМТ ТЭП-парсер (Табл.11/12/13) → ekb_ppt_tep MVP (#1133)
Co-authored-by: lekss361 <lekss361@gendsgn.local>
Co-committed-by: lekss361 <lekss361@gendsgn.local>
2026-06-07 11:54:40 +00:00

86 lines
5.4 KiB
PL/PgSQL
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.

-- 138_ekb_ppt_tep.sql
-- #1085 (Site Finder v2 / GG-форсайт #1067) — ТЭП из ППТ/ПМТ-пояснительных записок.
--
-- Что/зачем: структурированный контент пояснительных записок ППТ/ПМТ (PDF).
-- Три логических таблицы документа:
-- Табл.11 — баланс территории по зонам (га + %);
-- Табл.12 — основные ТЭП (площади, этажность, плотность, инфраструктура);
-- Табл.13 — очередность строительства (объект/зона/срок/финансирование).
--
-- Линковка к геометрии: doc_ref сопоставляется с planning_projects.source_key /
-- doc_full_name (данные ППТ/ПМТ уже в БД через WFS, #1085). Прямой FK не ставим
-- из-за best-effort nature ссылок (одна пояснительная → несколько границ и наоборот).
--
-- Grain: одна строка = один PDF-документ пояснительной записки.
-- UNIQUE(doc_ref) — не допускает дублей при повторном ingest.
--
-- Deploy: auto-applied deploy.yml через _schema_migrations (ровно один раз по NN).
-- Idempotent: CREATE TABLE/INDEX IF NOT EXISTS + guarded DO-блок для UNIQUE.
-- Без INSERT (данные приходят из ekb_ppt_tep_sync Celery-воркера).
BEGIN;
-- ── 1. Таблица ekb_ppt_tep ────────────────────────────────────────────────────
CREATE TABLE IF NOT EXISTS ekb_ppt_tep (
id BIGSERIAL PRIMARY KEY,
doc_ref TEXT NOT NULL, -- ид/ссылка документа ППТ (для join к planning_projects)
project_type TEXT NOT NULL, -- 'ppt' | 'pmt'
zone_balance JSONB, -- Табл.11: баланс территории по зонам
tep JSONB, -- Табл.12: основные ТЭП
phasing JSONB, -- Табл.13: очередность строительства
raw_tables JSONB, -- сырые таблицы для отладки/re-parse
source_pdf TEXT, -- URL или путь к исходному PDF
fetched_at TIMESTAMPTZ NOT NULL DEFAULT now()
);
COMMENT ON TABLE ekb_ppt_tep IS
'ТЭП из пояснительных записок ППТ/ПМТ (#1085, GG-форсайт #1067). '
'1 строка = 1 PDF-документ. '
'Три JSONB-поля: zone_balance (Табл.11), tep (Табл.12), phasing (Табл.13). '
'Линковка к геометрии: doc_ref → planning_projects.source_key.';
COMMENT ON COLUMN ekb_ppt_tep.doc_ref IS
'Идентификатор/ссылка документа ППТ. Для сопоставления с '
'planning_projects.source_key или doc_full_name.';
COMMENT ON COLUMN ekb_ppt_tep.project_type IS
'''ppt'' — проект планировки территории; ''pmt'' — проект межевания территории.';
COMMENT ON COLUMN ekb_ppt_tep.zone_balance IS
'Баланс территории по зонам (Табл.11): [{no, zone_name, existing_ha, project_ha, ...}]. '
'Пустой массив [] если таблица не найдена в PDF.';
COMMENT ON COLUMN ekb_ppt_tep.tep IS
'Основные ТЭП (Табл.12): [{no, indicator, unit, current, target}]. '
'Пустой массив [] если таблица не найдена.';
COMMENT ON COLUMN ekb_ppt_tep.phasing IS
'Очередность строительства (Табл.13): [{phase, composition, zone, area_ha, '
'funding, program}]. Пустой массив [] если таблица не найдена.';
COMMENT ON COLUMN ekb_ppt_tep.raw_tables IS
'Сырые таблицы из pdfplumber для отладки: [{page, table_index, rows: [[...]]}]. ';
-- ── 2. UNIQUE(doc_ref) — дедуп-ключ для UPSERT воркера ──────────────────────
-- Guard по pg_constraint → idempotent re-apply (прецедент: м.132, 136, 137).
DO $$
BEGIN
IF NOT EXISTS (
SELECT 1 FROM pg_constraint WHERE conname = 'uq_ekb_ppt_tep_doc_ref'
) THEN
ALTER TABLE ekb_ppt_tep
ADD CONSTRAINT uq_ekb_ppt_tep_doc_ref UNIQUE (doc_ref);
END IF;
END
$$;
-- ── 3. Индексы ────────────────────────────────────────────────────────────────
-- Фильтр по типу проекта (ppt/pmt).
CREATE INDEX IF NOT EXISTS idx_ekb_ppt_tep_project_type
ON ekb_ppt_tep (project_type);
-- Свежесть / ORDER BY fetched_at для мониторинга.
CREATE INDEX IF NOT EXISTS idx_ekb_ppt_tep_fetched_at
ON ekb_ppt_tep (fetched_at DESC);
-- GIN-индекс на zone_balance для поиска по зонам (follow-up: @> queries).
CREATE INDEX IF NOT EXISTS idx_ekb_ppt_tep_zone_balance_gin
ON ekb_ppt_tep USING GIN (zone_balance)
WHERE zone_balance IS NOT NULL;
COMMIT;