85 lines
3.6 KiB
PL/PgSQL
85 lines
3.6 KiB
PL/PgSQL
-- 元数据只保存结构模具与绑定,不保存任何业务实例值。
|
|
CREATE SCHEMA metadata AUTHORIZATION muse_maint;
|
|
GRANT USAGE ON SCHEMA metadata TO muse_app, muse_eval;
|
|
|
|
CREATE TABLE metadata.type_registry (
|
|
type_id text PRIMARY KEY,
|
|
definition jsonb NOT NULL,
|
|
content_hash text NOT NULL,
|
|
state text NOT NULL DEFAULT 'candidate' CHECK (state IN ('candidate', 'published')),
|
|
policy_revision bigint NOT NULL DEFAULT 0 CHECK (policy_revision >= 0)
|
|
);
|
|
CREATE TABLE metadata.schema_version (
|
|
schema_id text NOT NULL,
|
|
schema_version bigint NOT NULL CHECK (schema_version > 0),
|
|
type_id text NOT NULL REFERENCES metadata.type_registry(type_id),
|
|
definition jsonb NOT NULL,
|
|
content_hash text NOT NULL,
|
|
state text NOT NULL CHECK (state IN ('candidate', 'published')),
|
|
PRIMARY KEY (schema_id, schema_version)
|
|
);
|
|
CREATE TABLE metadata.work_extension (
|
|
work_id text NOT NULL,
|
|
schema_id text NOT NULL,
|
|
base_version bigint NOT NULL,
|
|
extension_version bigint NOT NULL CHECK (extension_version > 0),
|
|
definition jsonb NOT NULL,
|
|
content_hash text NOT NULL,
|
|
state text NOT NULL CHECK (state IN ('candidate', 'published')),
|
|
PRIMARY KEY (work_id, schema_id, base_version, extension_version),
|
|
FOREIGN KEY (schema_id, base_version)
|
|
REFERENCES metadata.schema_version(schema_id, schema_version)
|
|
);
|
|
CREATE TABLE metadata.policy_version (
|
|
type_id text NOT NULL REFERENCES metadata.type_registry(type_id),
|
|
version bigint NOT NULL CHECK (version > 0),
|
|
definition jsonb NOT NULL,
|
|
content_hash text NOT NULL,
|
|
PRIMARY KEY (type_id, version)
|
|
);
|
|
CREATE TABLE metadata.schema_binding (
|
|
target_ref text PRIMARY KEY,
|
|
work_id text NOT NULL,
|
|
type_id text NOT NULL REFERENCES metadata.type_registry(type_id),
|
|
schema_id text NOT NULL,
|
|
base_version bigint NOT NULL,
|
|
extension_version bigint,
|
|
effective_schema_hash text NOT NULL,
|
|
revision bigint NOT NULL CHECK (revision > 0),
|
|
FOREIGN KEY (schema_id, base_version)
|
|
REFERENCES metadata.schema_version(schema_id, schema_version),
|
|
FOREIGN KEY (work_id, schema_id, base_version, extension_version)
|
|
REFERENCES metadata.work_extension(work_id, schema_id, base_version, extension_version)
|
|
);
|
|
CREATE TABLE metadata.activation_receipt (
|
|
command_id text PRIMARY KEY,
|
|
request_hash text NOT NULL,
|
|
result jsonb NOT NULL,
|
|
reviewed_by text NOT NULL,
|
|
change_scope text NOT NULL,
|
|
created_at timestamptz NOT NULL DEFAULT current_timestamp
|
|
);
|
|
|
|
-- 候选修改也必须产生新版本;发布只允许改变状态,正文定义永远不可原地覆盖。
|
|
CREATE FUNCTION metadata.immutable_definition() RETURNS trigger LANGUAGE plpgsql AS $$
|
|
BEGIN
|
|
IF TG_OP = 'DELETE' THEN
|
|
RAISE EXCEPTION '元数据历史版本不可删除';
|
|
END IF;
|
|
IF NEW.definition IS DISTINCT FROM OLD.definition
|
|
OR NEW.content_hash IS DISTINCT FROM OLD.content_hash THEN
|
|
RAISE EXCEPTION '元数据定义不可修改,必须新增版本';
|
|
END IF;
|
|
RETURN NEW;
|
|
END;
|
|
$$;
|
|
CREATE TRIGGER schema_immutable BEFORE UPDATE OR DELETE ON metadata.schema_version
|
|
FOR EACH ROW EXECUTE FUNCTION metadata.immutable_definition();
|
|
CREATE TRIGGER extension_immutable BEFORE UPDATE OR DELETE ON metadata.work_extension
|
|
FOR EACH ROW EXECUTE FUNCTION metadata.immutable_definition();
|
|
CREATE TRIGGER policy_immutable BEFORE UPDATE OR DELETE ON metadata.policy_version
|
|
FOR EACH ROW EXECUTE FUNCTION metadata.immutable_definition();
|
|
|
|
GRANT SELECT, INSERT, UPDATE ON ALL TABLES IN SCHEMA metadata TO muse_app;
|
|
GRANT SELECT ON ALL TABLES IN SCHEMA metadata TO muse_eval;
|