CREATE SCHEMA IF NOT EXISTS source_gis; CREATE TABLE IF NOT EXISTS source_gis.datasets ( dataset_key TEXT PRIMARY KEY, title TEXT NOT NULL, source_date DATE NOT NULL, declared_srid INTEGER, effective_srid INTEGER NOT NULL, coordinate_note TEXT NOT NULL, imported_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS source_gis.layers ( layer_key TEXT PRIMARY KEY, dataset_key TEXT NOT NULL REFERENCES source_gis.datasets(dataset_key) ON DELETE CASCADE, display_name TEXT NOT NULL, source_file TEXT NOT NULL, feature_kind TEXT NOT NULL, geometry_type TEXT NOT NULL, feature_count BIGINT NOT NULL CHECK (feature_count >= 0), imported_at TIMESTAMPTZ NOT NULL DEFAULT NOW() ); CREATE TABLE IF NOT EXISTS source_gis.features ( layer_key TEXT NOT NULL REFERENCES source_gis.layers(layer_key) ON DELETE CASCADE, source_fid BIGINT NOT NULL, source_object_id TEXT, source_keyword TEXT, source_asset_id TEXT, source_diameter DOUBLE PRECISION, from_node_id TEXT, to_node_id TEXT, attributes JSONB NOT NULL CHECK (jsonb_typeof(attributes) = 'object'), geom geometry(Geometry, 900914) NOT NULL, PRIMARY KEY (layer_key, source_fid) ); ALTER TABLE source_gis.features ADD COLUMN IF NOT EXISTS source_diameter DOUBLE PRECISION; CREATE TABLE IF NOT EXISTS source_gis.element_links ( element_type TEXT NOT NULL, element_id TEXT NOT NULL, layer_key TEXT NOT NULL, source_fid BIGINT NOT NULL, match_method TEXT NOT NULL, distance_m DOUBLE PRECISION, PRIMARY KEY (element_type, element_id, layer_key), FOREIGN KEY (layer_key, source_fid) REFERENCES source_gis.features(layer_key, source_fid) ON DELETE CASCADE ); CREATE INDEX IF NOT EXISTS idx_source_gis_layers_dataset ON source_gis.layers(dataset_key); CREATE INDEX IF NOT EXISTS idx_source_gis_features_object_id ON source_gis.features(layer_key, source_object_id); CREATE INDEX IF NOT EXISTS idx_source_gis_features_nodes ON source_gis.features(layer_key, from_node_id, to_node_id); CREATE INDEX IF NOT EXISTS idx_source_gis_features_nodes_reverse ON source_gis.features(layer_key, to_node_id, from_node_id); CREATE INDEX IF NOT EXISTS idx_source_gis_features_geom ON source_gis.features USING GIST (geom); CREATE INDEX IF NOT EXISTS idx_source_gis_element_links_lookup ON source_gis.element_links(element_type, element_id); COMMENT ON SCHEMA source_gis IS 'Imported source GIS inventories retained separately from the hydraulic model.'; COMMENT ON COLUMN source_gis.datasets.declared_srid IS 'SRID declared by the source file, which may be incorrect.'; COMMENT ON COLUMN source_gis.datasets.effective_srid IS 'SRID assigned after validating source coordinates against the project model.'; COMMENT ON COLUMN source_gis.features.attributes IS 'Original non-geometry GIS fields, including null values, preserved as JSONB.';