-- Create superuser lock management functions -- Function to allow superusers to force-release any lock CREATE OR REPLACE FUNCTION public.superuser_release_lock( p_submission_id UUID, p_superuser_id UUID ) RETURNS BOOLEAN LANGUAGE plpgsql SECURITY DEFINER SET search_path = public AS $$ DECLARE v_is_superuser BOOLEAN; v_original_moderator UUID; v_submission_type TEXT; v_user_id UUID; BEGIN -- Verify caller is actually a superuser SELECT EXISTS ( SELECT 1 FROM user_roles WHERE user_id = p_superuser_id AND role = 'superuser' ) INTO v_is_superuser; IF NOT v_is_superuser THEN RAISE EXCEPTION 'Unauthorized: Only superusers can force-release locks'; END IF; -- Capture original moderator and submission details for audit logging SELECT assigned_to, submission_type, user_id INTO v_original_moderator, v_submission_type, v_user_id FROM content_submissions WHERE id = p_submission_id; -- Release the lock UPDATE content_submissions SET assigned_to = NULL, assigned_at = NULL, locked_until = NULL WHERE id = p_submission_id AND assigned_to IS NOT NULL; -- Log the forced release if a lock was actually released IF FOUND THEN PERFORM log_admin_action( p_superuser_id, v_user_id, 'submission_lock_force_released', jsonb_build_object( 'submission_id', p_submission_id, 'submission_type', v_submission_type, 'original_moderator', v_original_moderator, 'forced_release', true ) ); END IF; RETURN FOUND; END; $$; -- Function to allow superusers to clear all active locks CREATE OR REPLACE FUNCTION public.superuser_release_all_locks( p_superuser_id UUID ) RETURNS INTEGER LANGUAGE plpgsql SECURITY DEFINER SET search_path = public AS $$ DECLARE v_is_superuser BOOLEAN; v_released_count INTEGER; v_released_locks JSONB; BEGIN -- Verify caller is actually a superuser SELECT EXISTS ( SELECT 1 FROM user_roles WHERE user_id = p_superuser_id AND role = 'superuser' ) INTO v_is_superuser; IF NOT v_is_superuser THEN RAISE EXCEPTION 'Unauthorized: Only superusers can release all locks'; END IF; -- Capture all locked submissions for audit SELECT jsonb_agg( jsonb_build_object( 'submission_id', id, 'assigned_to', assigned_to, 'locked_until', locked_until, 'submission_type', submission_type ) ) INTO v_released_locks FROM content_submissions WHERE assigned_to IS NOT NULL AND locked_until > NOW(); -- Release all active locks UPDATE content_submissions SET assigned_to = NULL, assigned_at = NULL, locked_until = NULL WHERE assigned_to IS NOT NULL AND locked_until > NOW() AND status IN ('pending', 'partially_approved'); GET DIAGNOSTICS v_released_count = ROW_COUNT; -- Log the bulk release IF v_released_count > 0 THEN PERFORM log_admin_action( p_superuser_id, NULL, -- No specific target user 'submission_locks_bulk_released', jsonb_build_object( 'released_count', v_released_count, 'released_locks', v_released_locks, 'bulk_operation', true ) ); END IF; RETURN v_released_count; END; $$;