|
|
|
|
@@ -3,7 +3,8 @@
|
|
|
|
|
|
|
|
|
|
ALTER TABLE education_question_collection
|
|
|
|
|
ADD COLUMN publication_status VARCHAR(16) NOT NULL DEFAULT 'ACTIVE',
|
|
|
|
|
ADD COLUMN authoring_version INTEGER NOT NULL DEFAULT 0;
|
|
|
|
|
ADD COLUMN authoring_version INTEGER NOT NULL DEFAULT 0,
|
|
|
|
|
ADD COLUMN membership_version INTEGER NOT NULL DEFAULT 0;
|
|
|
|
|
|
|
|
|
|
UPDATE education_question_collection
|
|
|
|
|
SET publication_status = CASE WHEN is_active AND NOT is_hidden THEN 'ACTIVE' ELSE 'ARCHIVED' END,
|
|
|
|
|
@@ -15,6 +16,7 @@ SET publication_status = CASE WHEN is_active AND NOT is_hidden THEN 'ACTIVE' ELS
|
|
|
|
|
ALTER TABLE education_question_collection
|
|
|
|
|
ADD CONSTRAINT ck_education_question_collection_publication_status CHECK (publication_status IN ('DRAFT','ACTIVE','ARCHIVED')),
|
|
|
|
|
ADD CONSTRAINT ck_education_question_collection_authoring_version CHECK (authoring_version >= 0),
|
|
|
|
|
ADD CONSTRAINT ck_education_question_collection_membership_version CHECK (membership_version >= 0),
|
|
|
|
|
ADD CONSTRAINT ck_education_question_collection_lifecycle_consistent CHECK (
|
|
|
|
|
(publication_status = 'ACTIVE' AND is_active AND NOT is_hidden) OR
|
|
|
|
|
(publication_status IN ('DRAFT','ARCHIVED') AND NOT is_active AND is_hidden));
|
|
|
|
|
@@ -51,7 +53,7 @@ BEGIN
|
|
|
|
|
IF NEW.scope='PUBLIC' THEN
|
|
|
|
|
IF NEW.publication_status<>'ACTIVE' OR NOT NEW.is_active OR NEW.is_hidden OR NEW.authoring_version<>0 THEN
|
|
|
|
|
RAISE EXCEPTION 'PUBLIC collection writes are not tenant authoring' USING ERRCODE='23514'; END IF;
|
|
|
|
|
ELSIF NEW.scope='TENANT_OWNED' AND (NEW.collection_type<>'MANUAL' OR NEW.publication_status<>'DRAFT' OR NEW.is_active OR NOT NEW.is_hidden OR NEW.authoring_version<>0 OR NEW.question_count<>0) THEN
|
|
|
|
|
ELSIF NEW.scope='TENANT_OWNED' AND (NEW.collection_type<>'MANUAL' OR NEW.publication_status<>'DRAFT' OR NEW.is_active OR NOT NEW.is_hidden OR NEW.authoring_version<>0 OR NEW.membership_version<>0 OR NEW.question_count<>0) THEN
|
|
|
|
|
RAISE EXCEPTION 'tenant collection must start empty DRAFT' USING ERRCODE='23514'; END IF;
|
|
|
|
|
RETURN NEW;
|
|
|
|
|
END IF;
|
|
|
|
|
@@ -62,13 +64,17 @@ BEGIN
|
|
|
|
|
IF NEW.authoring_version<>OLD.authoring_version+1 THEN RAISE EXCEPTION 'collection authoring version must advance exactly once' USING ERRCODE='23514'; END IF;
|
|
|
|
|
IF OLD.publication_status<>'DRAFT' AND (NEW.entry_id IS DISTINCT FROM OLD.entry_id OR NEW.node_id IS DISTINCT FROM OLD.node_id OR
|
|
|
|
|
NEW.name IS DISTINCT FROM OLD.name OR NEW.title IS DISTINCT FROM OLD.title OR NEW.collection_type IS DISTINCT FROM OLD.collection_type OR
|
|
|
|
|
NEW.question_count IS DISTINCT FROM OLD.question_count OR NEW.duration_minutes IS DISTINCT FROM OLD.duration_minutes OR
|
|
|
|
|
NEW.question_count IS DISTINCT FROM OLD.question_count OR NEW.membership_version IS DISTINCT FROM OLD.membership_version OR NEW.duration_minutes IS DISTINCT FROM OLD.duration_minutes OR
|
|
|
|
|
NEW.access_rules IS DISTINCT FROM OLD.access_rules OR NEW.sort_order IS DISTINCT FROM OLD.sort_order OR NEW.metadata IS DISTINCT FROM OLD.metadata) THEN
|
|
|
|
|
RAISE EXCEPTION 'active collection content is immutable' USING ERRCODE='23514'; END IF;
|
|
|
|
|
IF NEW.publication_status IS NOT DISTINCT FROM OLD.publication_status AND OLD.publication_status='DRAFT'
|
|
|
|
|
AND NEW.question_count IS DISTINCT FROM OLD.question_count THEN
|
|
|
|
|
IF NEW.membership_version IS DISTINCT FROM OLD.membership_version THEN
|
|
|
|
|
IF OLD.publication_status<>'DRAFT' OR NEW.publication_status<>'DRAFT' OR NEW.membership_version<>OLD.membership_version+1 THEN
|
|
|
|
|
RAISE EXCEPTION 'collection membership version must advance exactly once in DRAFT' USING ERRCODE='23514';
|
|
|
|
|
END IF;
|
|
|
|
|
EXECUTE format('INSERT INTO %I.education_question_collection_membership_token VALUES ($1,$2,$3,$4)',TG_TABLE_SCHEMA)
|
|
|
|
|
USING pg_current_xact_id()::text::BIGINT,NEW.tenant_id,NEW.id,NEW.authoring_version;
|
|
|
|
|
ELSIF NEW.question_count IS DISTINCT FROM OLD.question_count THEN
|
|
|
|
|
RAISE EXCEPTION 'collection question_count requires membership version advance' USING ERRCODE='23514';
|
|
|
|
|
END IF;
|
|
|
|
|
IF NEW.publication_status IS DISTINCT FROM OLD.publication_status THEN
|
|
|
|
|
PERFORM pg_advisory_xact_lock(NEW.id);
|
|
|
|
|
@@ -174,7 +180,7 @@ CREATE TRIGGER trg_education_collection_membership_mutation BEFORE INSERT OR UPD
|
|
|
|
|
CREATE TRIGGER trg_education_question_active_collection_archive BEFORE UPDATE OF status ON education_question FOR EACH ROW EXECUTE FUNCTION education_block_active_collection_question_archive();
|
|
|
|
|
CREATE TRIGGER trg_education_question_collection_audit_validate BEFORE INSERT ON education_question_collection_lifecycle_audit FOR EACH ROW EXECUTE FUNCTION education_validate_question_collection_audit();
|
|
|
|
|
CREATE TRIGGER trg_education_question_collection_audit_immutable BEFORE UPDATE OR DELETE ON education_question_collection_lifecycle_audit FOR EACH ROW EXECUTE FUNCTION education_prevent_question_collection_audit_mutation();
|
|
|
|
|
CREATE CONSTRAINT TRIGGER trg_education_question_collection_membership_count AFTER UPDATE OF question_count ON education_question_collection DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION education_require_question_collection_membership_count();
|
|
|
|
|
CREATE CONSTRAINT TRIGGER trg_education_question_collection_membership_count AFTER UPDATE OF membership_version ON education_question_collection DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION education_require_question_collection_membership_count();
|
|
|
|
|
CREATE CONSTRAINT TRIGGER trg_education_question_collection_audit_required AFTER UPDATE OF publication_status ON education_question_collection DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE FUNCTION education_require_question_collection_audit();
|
|
|
|
|
|
|
|
|
|
DO $$ DECLARE installed INTEGER; BEGIN
|
|
|
|
|
|