forked from wangziqi/ruoyi-vue-pro
fix(education): validate collection adoption history
This commit is contained in:
@@ -6,6 +6,27 @@ ALTER TABLE education_question_collection
|
||||
ADD COLUMN authoring_version INTEGER NOT NULL DEFAULT 0,
|
||||
ADD COLUMN membership_version INTEGER NOT NULL DEFAULT 0;
|
||||
|
||||
DO $$
|
||||
DECLARE bad_collection BIGINT; bad_question BIGINT;
|
||||
BEGIN
|
||||
SELECT collection.id, membership.question_id INTO bad_collection,bad_question
|
||||
FROM education_question_collection collection
|
||||
LEFT JOIN education_content_node node ON node.id=collection.node_id
|
||||
LEFT JOIN education_content_entry entry ON entry.id=node.entry_id
|
||||
LEFT JOIN education_question_collection_question membership ON membership.collection_id=collection.id AND NOT membership.deleted
|
||||
LEFT JOIN education_question question ON question.id=membership.question_id
|
||||
WHERE collection.scope='TENANT_OWNED' AND collection.is_active AND NOT collection.is_hidden AND NOT collection.deleted
|
||||
AND (node.id IS NULL OR node.tenant_id IS DISTINCT FROM collection.tenant_id OR node.scope<>'TENANT_OWNED'
|
||||
OR node.deleted OR NOT node.is_active OR node.is_hidden
|
||||
OR entry.id IS NULL OR entry.deleted OR NOT entry.is_active OR entry.is_hidden
|
||||
OR (membership.id IS NOT NULL AND (question.id IS NULL OR question.tenant_id IS DISTINCT FROM collection.tenant_id
|
||||
OR question.scope<>'TENANT_OWNED' OR question.deleted OR question.status<>'PUBLISHED' OR NOT question.is_published)))
|
||||
ORDER BY collection.id,membership.question_id NULLS FIRST LIMIT 1;
|
||||
IF bad_collection IS NOT NULL THEN
|
||||
RAISE EXCEPTION 'invalid historical active collection % member % blocks V4110',bad_collection,COALESCE(bad_question,0) USING ERRCODE='23514';
|
||||
END IF;
|
||||
END $$;
|
||||
|
||||
UPDATE education_question_collection
|
||||
SET publication_status = CASE WHEN is_active AND NOT is_hidden THEN 'ACTIVE' ELSE 'ARCHIVED' END,
|
||||
is_active = is_active AND NOT is_hidden,
|
||||
@@ -44,6 +65,12 @@ CREATE TABLE education_question_collection_membership_token (
|
||||
PRIMARY KEY(transaction_id,tenant_id,collection_id,authoring_version));
|
||||
REVOKE ALL ON TABLE education_question_collection_membership_token FROM PUBLIC;
|
||||
|
||||
CREATE FUNCTION education_prevent_question_collection_delete() RETURNS TRIGGER LANGUAGE plpgsql SET search_path=pg_catalog,pg_temp AS $$
|
||||
BEGIN
|
||||
IF OLD.scope='TENANT_OWNED' THEN RAISE EXCEPTION 'tenant collection cannot be physically deleted' USING ERRCODE='23514'; END IF;
|
||||
RETURN OLD;
|
||||
END $$;
|
||||
|
||||
CREATE FUNCTION education_enforce_question_collection_authoring() RETURNS TRIGGER
|
||||
LANGUAGE plpgsql SECURITY DEFINER SET search_path=pg_catalog,pg_temp AS $$
|
||||
DECLARE member RECORD;
|
||||
@@ -171,6 +198,7 @@ LANGUAGE plpgsql SET search_path=pg_catalog,pg_temp AS $$ DECLARE n INTEGER; BEG
|
||||
IF n<>1 THEN RAISE EXCEPTION 'collection lifecycle audit required' USING ERRCODE='23514'; END IF; RETURN NULL; END $$;
|
||||
CREATE FUNCTION education_prevent_question_collection_audit_mutation() RETURNS TRIGGER LANGUAGE plpgsql SET search_path=pg_catalog,pg_temp AS $$ BEGIN RAISE EXCEPTION 'collection audit is append-only' USING ERRCODE='23514'; END $$;
|
||||
|
||||
REVOKE ALL ON FUNCTION education_prevent_question_collection_delete() FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION education_enforce_question_collection_authoring() FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION education_enforce_collection_membership_mutation() FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION education_block_active_collection_question_archive() FROM PUBLIC;
|
||||
@@ -178,6 +206,7 @@ REVOKE ALL ON FUNCTION education_validate_question_collection_audit() FROM PUBLI
|
||||
REVOKE ALL ON FUNCTION education_require_question_collection_membership_count() FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION education_require_question_collection_audit() FROM PUBLIC;
|
||||
REVOKE ALL ON FUNCTION education_prevent_question_collection_audit_mutation() FROM PUBLIC;
|
||||
CREATE TRIGGER trg_education_question_collection_delete BEFORE DELETE ON education_question_collection FOR EACH ROW EXECUTE FUNCTION education_prevent_question_collection_delete();
|
||||
CREATE TRIGGER trg_education_question_collection_authoring BEFORE INSERT OR UPDATE ON education_question_collection FOR EACH ROW EXECUTE FUNCTION education_enforce_question_collection_authoring();
|
||||
CREATE TRIGGER trg_education_collection_membership_mutation BEFORE INSERT OR UPDATE OR DELETE ON education_question_collection_question FOR EACH ROW EXECUTE FUNCTION education_enforce_collection_membership_mutation();
|
||||
CREATE TRIGGER trg_education_question_active_collection_archive BEFORE UPDATE OF status, deleted ON education_question FOR EACH ROW EXECUTE FUNCTION education_block_active_collection_question_archive();
|
||||
|
||||
Reference in New Issue
Block a user