Files
leaudit-platform-backend/scripts/创建sql/schema_tenant_foundation.sql
T

164 lines
6.5 KiB
PL/PgSQL

-- 租户主数据底座
-- 目的:
-- 1. 为“地区 -> 租户”升级提供稳定主数据
-- 2. 为后续入口模块、RAG、文档、模板等模块提供 tenant_code
-- 3. 保持对现有 area / region / tenant_name 的兼容
BEGIN;
CREATE TABLE IF NOT EXISTS sys_tenants (
id BIGSERIAL PRIMARY KEY,
tenant_code VARCHAR(64) NOT NULL UNIQUE,
tenant_name VARCHAR(128) NOT NULL,
tenant_short_name VARCHAR(64) NULL,
tenant_type VARCHAR(32) NOT NULL,
parent_tenant_code VARCHAR(64) NULL,
display_order INT NOT NULL DEFAULT 0,
is_enabled BOOLEAN NOT NULL DEFAULT TRUE,
is_builtin BOOLEAN NOT NULL DEFAULT FALSE,
is_public BOOLEAN NOT NULL DEFAULT FALSE,
can_host_entry_module BOOLEAN NOT NULL DEFAULT TRUE,
can_host_documents BOOLEAN NOT NULL DEFAULT TRUE,
can_host_rag BOOLEAN NOT NULL DEFAULT TRUE,
can_host_templates BOOLEAN NOT NULL DEFAULT TRUE,
ext JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ NULL
);
CREATE INDEX IF NOT EXISTS idx_sys_tenants_enabled_order
ON sys_tenants(is_enabled, display_order, id)
WHERE deleted_at IS NULL;
CREATE TABLE IF NOT EXISTS sys_tenant_aliases (
id BIGSERIAL PRIMARY KEY,
tenant_code VARCHAR(64) NOT NULL,
alias_value VARCHAR(128) NOT NULL,
alias_type VARCHAR(32) NOT NULL,
is_enabled BOOLEAN NOT NULL DEFAULT TRUE,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ NULL,
UNIQUE (tenant_code, alias_value)
);
CREATE INDEX IF NOT EXISTS idx_sys_tenant_aliases_lookup
ON sys_tenant_aliases(alias_value, alias_type)
WHERE deleted_at IS NULL AND is_enabled = TRUE;
CREATE TABLE IF NOT EXISTS sys_tenant_feature_flags (
id BIGSERIAL PRIMARY KEY,
tenant_code VARCHAR(64) NOT NULL,
feature_key VARCHAR(64) NOT NULL,
is_enabled BOOLEAN NOT NULL DEFAULT TRUE,
ext JSONB NOT NULL DEFAULT '{}'::jsonb,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
deleted_at TIMESTAMPTZ NULL,
UNIQUE (tenant_code, feature_key)
);
CREATE INDEX IF NOT EXISTS idx_sys_tenant_features_lookup
ON sys_tenant_feature_flags(tenant_code, feature_key)
WHERE deleted_at IS NULL;
ALTER TABLE sso_users
ADD COLUMN IF NOT EXISTS tenant_code VARCHAR(64) NULL;
CREATE INDEX IF NOT EXISTS idx_sso_users_tenant_code
ON sso_users(tenant_code)
WHERE deleted_at IS NULL;
COMMENT ON TABLE sys_tenants IS '系统租户主数据表';
COMMENT ON TABLE sys_tenant_aliases IS '租户历史别名与展示别名映射表';
COMMENT ON TABLE sys_tenant_feature_flags IS '租户能力开关表';
COMMENT ON COLUMN sso_users.tenant_code IS '用户主归属租户编码,优先于 area 作为租户边界';
INSERT INTO sys_tenants (
tenant_code, tenant_name, tenant_short_name, tenant_type, parent_tenant_code,
display_order, is_enabled, is_builtin, is_public,
can_host_entry_module, can_host_documents, can_host_rag, can_host_templates, ext
)
VALUES
('MZ', '梅州', '梅州', 'LOCAL', NULL, 10, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, '{}'::jsonb),
('YF', '云浮', '云浮', 'LOCAL', NULL, 20, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, '{}'::jsonb),
('JY', '揭阳', '揭阳', 'LOCAL', NULL, 30, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, '{}'::jsonb),
('CZ', '潮州', '潮州', 'LOCAL', NULL, 40, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, '{}'::jsonb),
('PROVINCIAL', '省局', '省局', 'HEADQUARTER', NULL, 90, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, '{}'::jsonb),
('PUBLIC', '公共资源域', '公共', 'PUBLIC', NULL, 100, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, '{}'::jsonb)
ON CONFLICT (tenant_code) DO UPDATE
SET
tenant_name = EXCLUDED.tenant_name,
tenant_short_name = EXCLUDED.tenant_short_name,
tenant_type = EXCLUDED.tenant_type,
parent_tenant_code = EXCLUDED.parent_tenant_code,
display_order = EXCLUDED.display_order,
is_enabled = EXCLUDED.is_enabled,
is_builtin = EXCLUDED.is_builtin,
is_public = EXCLUDED.is_public,
can_host_entry_module = EXCLUDED.can_host_entry_module,
can_host_documents = EXCLUDED.can_host_documents,
can_host_rag = EXCLUDED.can_host_rag,
can_host_templates = EXCLUDED.can_host_templates,
ext = EXCLUDED.ext,
updated_at = NOW();
INSERT INTO sys_tenant_aliases (tenant_code, alias_value, alias_type, is_enabled)
VALUES
('MZ', '梅州', 'LEGACY_AREA', TRUE),
('YF', '云浮', 'LEGACY_AREA', TRUE),
('JY', '揭阳', 'LEGACY_AREA', TRUE),
('CZ', '潮州', 'LEGACY_AREA', TRUE),
('PROVINCIAL', '省局', 'DISPLAY', TRUE),
('PUBLIC', '省级', 'LEGACY_REGION', TRUE),
('PUBLIC', 'default', 'LEGACY_REGION', TRUE),
('PUBLIC', '', 'LEGACY_REGION', TRUE)
ON CONFLICT (tenant_code, alias_value) DO UPDATE
SET
alias_type = EXCLUDED.alias_type,
is_enabled = EXCLUDED.is_enabled,
updated_at = NOW();
INSERT INTO sys_tenant_feature_flags (tenant_code, feature_key, is_enabled)
VALUES
('MZ', 'home.entry_module', TRUE),
('YF', 'home.entry_module', TRUE),
('JY', 'home.entry_module', TRUE),
('CZ', 'home.entry_module', TRUE),
('PROVINCIAL', 'home.entry_module', TRUE),
('PUBLIC', 'home.entry_module', TRUE),
('MZ', 'rag.dataset', TRUE),
('YF', 'rag.dataset', TRUE),
('JY', 'rag.dataset', TRUE),
('CZ', 'rag.dataset', TRUE),
('PROVINCIAL', 'rag.dataset', TRUE),
('PUBLIC', 'rag.dataset', TRUE),
('MZ', 'documents.upload', TRUE),
('YF', 'documents.upload', TRUE),
('JY', 'documents.upload', TRUE),
('CZ', 'documents.upload', TRUE),
('PROVINCIAL', 'documents.upload', TRUE),
('PUBLIC', 'documents.upload', TRUE)
ON CONFLICT (tenant_code, feature_key) DO UPDATE
SET
is_enabled = EXCLUDED.is_enabled,
updated_at = NOW();
UPDATE sso_users u
SET tenant_code = mapped.tenant_code
FROM (
SELECT DISTINCT ON (a.alias_value)
a.alias_value,
a.tenant_code
FROM sys_tenant_aliases a
WHERE a.deleted_at IS NULL
AND a.is_enabled = TRUE
ORDER BY a.alias_value, a.id ASC
) mapped
WHERE u.deleted_at IS NULL
AND COALESCE(BTRIM(u.tenant_code), '') = ''
AND COALESCE(BTRIM(u.area), '') = mapped.alias_value;
COMMIT;