ALTER TABLE test_publications ADD COLUMN IF NOT EXISTS target_scope VARCHAR(16) NOT NULL DEFAULT 'internal' CHECK (target_scope IN ('internal', 'external')); UPDATE test_publications AS publication SET target_scope = COALESCE( ( SELECT review.decided_visibility FROM publication_reviews AS review WHERE review.publication_id = publication.id AND review.decision = 'approved' AND review.decided_visibility IN ('internal', 'external') ORDER BY review.created_at DESC, review.id DESC LIMIT 1 ), CASE WHEN item_rule.visibility IN ('internal', 'external') THEN item_rule.visibility END, source.visibility ) FROM source_item_versions AS version JOIN source_items AS source ON source.id = version.source_item_id LEFT JOIN source_item_scope_overrides AS item_rule ON item_rule.source_item_id = source.id WHERE publication.source_item_version_id = version.id; CREATE TABLE IF NOT EXISTS processing_confirmations ( id VARCHAR(36) PRIMARY KEY, publication_id VARCHAR(36) NOT NULL REFERENCES test_publications(id) ON DELETE RESTRICT, operator_ref VARCHAR(128) NOT NULL, reason VARCHAR(500) NOT NULL, confirmed_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), UNIQUE (publication_id) ); CREATE INDEX IF NOT EXISTS idx_processing_confirmations_confirmed ON processing_confirmations (confirmed_at DESC, publication_id);