Files
next-tjwater-server/resources/sql/005_metadata_project_configuration.sql
T
jiang 26fa5d1909
Generic Container CI/CD / test-build-publish (push) Successful in 3m39s
Server CI/CD v2 / build-test-publish-and-deploy (push) Successful in 3m39s
feat(scada): add project monitoring replay
2026-11-04 14:27:21 +08:00

79 lines
3.4 KiB
PL/PgSQL

-- Metadata project configuration schema patch.
-- Admin APIs write these tables; operators should not hand-edit encrypted values.
CREATE EXTENSION IF NOT EXISTS pgcrypto;
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = CURRENT_TIMESTAMP;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TABLE IF NOT EXISTS projects (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
name VARCHAR(100) NOT NULL,
code VARCHAR(50) UNIQUE NOT NULL,
description TEXT,
gs_workspace VARCHAR(100) UNIQUE NOT NULL,
map_extent JSONB,
map_config JSONB NOT NULL DEFAULT '{}'::jsonb,
settings JSONB NOT NULL DEFAULT '{}'::jsonb,
status VARCHAR(20) DEFAULT 'active' NOT NULL,
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP NOT NULL,
CONSTRAINT projects_status_check CHECK (status IN ('active', 'inactive', 'archived')),
CONSTRAINT projects_settings_object_check CHECK (jsonb_typeof(settings) = 'object')
);
ALTER TABLE projects ADD COLUMN IF NOT EXISTS map_config JSONB NOT NULL DEFAULT '{}'::jsonb;
ALTER TABLE projects ADD COLUMN IF NOT EXISTS settings JSONB NOT NULL DEFAULT '{}'::jsonb;
COMMENT ON COLUMN projects.settings IS
'项目级通用配置(JSON 对象,不存放密钥);scada_monitoring_interval_seconds 为监测任务间隔秒数。';
COMMENT ON COLUMN projects.map_config IS
'项目级地图配置(JSON);place_search 保存地名搜索启用状态、服务商、行政区编码及区域名称;保留既有图例与坐标参考配置。';
CREATE INDEX IF NOT EXISTS idx_projects_status ON projects(status);
DROP TRIGGER IF EXISTS update_projects_updated_at ON projects;
CREATE TRIGGER update_projects_updated_at
BEFORE UPDATE ON projects
FOR EACH ROW
EXECUTE FUNCTION update_updated_at_column();
CREATE TABLE IF NOT EXISTS user_project_membership (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
project_role VARCHAR(20) DEFAULT 'viewer' NOT NULL,
CONSTRAINT user_project_membership_role_check
CHECK (project_role IN ('member', 'viewer')),
CONSTRAINT user_project_membership_unique UNIQUE (user_id, project_id)
);
-- The unique (user_id, project_id) index already supports user-side lookups.
CREATE INDEX IF NOT EXISTS idx_user_project_membership_project_id
ON user_project_membership(project_id);
CREATE TABLE IF NOT EXISTS project_databases (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
project_id UUID NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
db_role VARCHAR(20) NOT NULL,
db_type VARCHAR(20) NOT NULL,
dsn_encrypted TEXT NOT NULL,
pool_min_size INTEGER DEFAULT 2 NOT NULL,
pool_max_size INTEGER DEFAULT 10 NOT NULL,
CONSTRAINT project_databases_unique_role UNIQUE (project_id, db_role),
CONSTRAINT project_databases_role_check CHECK (db_role IN ('biz_data', 'iot_data')),
CONSTRAINT project_databases_type_check CHECK (db_type IN ('postgresql', 'timescaledb')),
CONSTRAINT project_databases_pool_check CHECK (
pool_min_size >= 1 AND pool_max_size >= pool_min_size
)
);
CREATE INDEX IF NOT EXISTS idx_project_databases_project_id
ON project_databases(project_id);
CREATE INDEX IF NOT EXISTS idx_project_databases_role
ON project_databases(db_role);