fix(education): validate content node migration

This commit is contained in:
2026-07-30 23:57:07 +08:00
parent f84aecf8f5
commit 2daeb43c5a
2 changed files with 18 additions and 7 deletions

View File

@@ -81,8 +81,7 @@ BEGIN
NEW.name IS DISTINCT FROM OLD.name OR NEW.title IS DISTINCT FROM OLD.title OR
NEW.node_type IS DISTINCT FROM OLD.node_type OR NEW.marker_type IS DISTINCT FROM OLD.marker_type OR
NEW.is_leaf IS DISTINCT FROM OLD.is_leaf OR NEW.is_selectable IS DISTINCT FROM OLD.is_selectable OR
NEW.is_hidden IS DISTINCT FROM OLD.is_hidden OR NEW.sort_order IS DISTINCT FROM OLD.sort_order OR
NEW.metadata IS DISTINCT FROM OLD.metadata) THEN
NEW.sort_order IS DISTINCT FROM OLD.sort_order OR NEW.metadata IS DISTINCT FROM OLD.metadata) THEN
RAISE EXCEPTION 'active content node content is immutable' USING ERRCODE = '23514';
END IF;
RETURN NEW;

View File

@@ -119,7 +119,7 @@ class EducationFlywayMigrationIntegrationTest {
assertThat(queryStrings(schema,
"SELECT COALESCE(version, 'BASELINE') FROM flyway_schema_history ORDER BY installed_rank"))
.containsExactly("4009", "4010", "4020", "4030", "4040", "4050", "4060", "4070", "4080", "4090");
.containsExactly("4009", "4010", "4020", "4030", "4040", "4050", "4060", "4070", "4080", "4090", "4100");
assertThat(queryLong(schema,
"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = current_schema() " +
"AND table_name = 'education_idempotency'"))
@@ -181,7 +181,7 @@ class EducationFlywayMigrationIntegrationTest {
assertThat(queryStrings(schema,
"SELECT version FROM flyway_schema_history WHERE success = TRUE ORDER BY installed_rank"))
.containsExactly("4010", "4020", "4030", "4040", "4050", "4060", "4070", "4080", "4090");
.containsExactly("4010", "4020", "4030", "4040", "4050", "4060", "4070", "4080", "4090", "4100");
assertThat(queryStrings(schema,
"SELECT table_name FROM information_schema.tables " +
"WHERE table_schema = current_schema() AND table_name IN (" +
@@ -405,9 +405,21 @@ class EducationFlywayMigrationIntegrationTest {
(id, tenant_id, scope, entry_key, name, entry_type)
VALUES (100, 10, 'TENANT_OWNED', 'questions', 'Questions', 'question');
INSERT INTO education_content_node
(id, tenant_id, scope, entry_id, name, node_type)
VALUES (200, 10, 'TENANT_OWNED', 100, 'Algebra', 'category'),
(201, 10, 'TENANT_OWNED', 100, 'Geometry', 'category');
(id, tenant_id, scope, entry_id, name, node_type, publication_status, is_active, is_hidden)
VALUES (200, 10, 'TENANT_OWNED', 100, 'Algebra', 'category', 'DRAFT', false, true),
(201, 10, 'TENANT_OWNED', 100, 'Geometry', 'category', 'DRAFT', false, true);
DO $activate_nodes$
BEGIN
UPDATE education_content_node
SET publication_status = 'ACTIVE', is_active = true, is_hidden = false,
authoring_version = 1
WHERE id IN (200, 201);
INSERT INTO education_content_node_lifecycle_audit
(tenant_id, node_id, authoring_version, actor_id, from_status, to_status)
VALUES (10, 200, 1, 7, 'DRAFT', 'ACTIVE'),
(10, 201, 1, 7, 'DRAFT', 'ACTIVE');
END
$activate_nodes$;
INSERT INTO education_question
(id, tenant_id, scope, stem, type, options, correct_answer)
VALUES (300, 10, 'TENANT_OWNED', 'Placed draft', 'text', '[]', 'answer');