-- Add super admin support to the platform -- This migration adds a super admin role distinction and required functions -- Add super admin role support ALTER TABLE users ADD COLUMN is_super_admin BOOLEAN DEFAULT false; -- Update the first admin user to be super admin UPDATE users SET is_super_admin = true WHERE role = 'admin' AND created_at = ( SELECT MIN(created_at) FROM users WHERE role = 'admin' ); -- Create the make_user_admin function that's referenced in setup scripts CREATE OR REPLACE FUNCTION make_user_admin(user_email TEXT) RETURNS VOID AS $$ BEGIN -- Update the user role to admin UPDATE users SET role = 'admin', is_active = true WHERE email = user_email; -- Log the admin action INSERT INTO audit_logs (user_id, action, resource_type, resource_id, new_values) VALUES ( auth.uid(), 'update', 'user', (SELECT id FROM users WHERE email = user_email), json_build_object('role', 'admin', 'promoted_by', auth.uid()) ); END; $$ LANGUAGE plpgsql SECURITY DEFINER; -- Create function to make user super admin CREATE OR REPLACE FUNCTION make_user_super_admin(user_email TEXT) RETURNS VOID AS $$ BEGIN -- Update the user role to admin and super admin UPDATE users SET role = 'admin', is_super_admin = true, is_active = true WHERE email = user_email; -- Log the super admin action INSERT INTO audit_logs (user_id, action, resource_type, resource_id, new_values) VALUES ( auth.uid(), 'update', 'user', (SELECT id FROM users WHERE email = user_email), json_build_object('role', 'admin', 'is_super_admin', true, 'promoted_by', auth.uid()) ); END; $$ LANGUAGE plpgsql SECURITY DEFINER; -- Create function to check if user is super admin CREATE OR REPLACE FUNCTION is_super_admin(user_uuid UUID DEFAULT auth.uid()) RETURNS BOOLEAN AS $$ BEGIN RETURN EXISTS ( SELECT 1 FROM users WHERE id = user_uuid AND role = 'admin' AND is_super_admin = true AND is_active = true ); END; $$ LANGUAGE plpgsql SECURITY DEFINER; -- Update the existing is_admin function to be more robust CREATE OR REPLACE FUNCTION is_admin(user_uuid UUID DEFAULT auth.uid()) RETURNS BOOLEAN AS $$ BEGIN RETURN EXISTS ( SELECT 1 FROM users WHERE id = user_uuid AND role = 'admin' AND is_active = true ); END; $$ LANGUAGE plpgsql SECURITY DEFINER; -- Create function used by setup scripts CREATE OR REPLACE FUNCTION exec_sql(sql_query TEXT) RETURNS VOID AS $$ BEGIN EXECUTE sql_query; END; $$ LANGUAGE plpgsql SECURITY DEFINER; -- Add RLS policies for super admin access -- Super admins can view all users (including other admins) CREATE POLICY "Super admins can view all users" ON users FOR SELECT USING ( auth.uid() IN (SELECT id FROM users WHERE role = 'admin' AND is_super_admin = true) OR auth.uid() IN (SELECT id FROM users WHERE role = 'admin') OR id = auth.uid() ); -- Super admins can update any user (including other admins) CREATE POLICY "Super admins can update any user" ON users FOR UPDATE USING ( auth.uid() IN (SELECT id FROM users WHERE role = 'admin' AND is_super_admin = true) OR (auth.uid() IN (SELECT id FROM users WHERE role = 'admin') AND id != auth.uid()) OR id = auth.uid() ); -- Update platform_stats view to include super admin info DROP VIEW IF EXISTS platform_stats; CREATE VIEW platform_stats AS SELECT (SELECT COUNT(*) FROM users WHERE role = 'organizer' AND is_active = true) as active_organizers, (SELECT COUNT(*) FROM users WHERE role = 'admin') as admin_users, (SELECT COUNT(*) FROM users WHERE role = 'admin' AND is_super_admin = true) as super_admin_users, (SELECT COUNT(*) FROM organizations) as total_organizations, (SELECT COUNT(*) FROM events) as total_events, (SELECT COUNT(*) FROM events WHERE start_time >= NOW()) as upcoming_events, (SELECT COUNT(*) FROM tickets) as total_tickets_sold, (SELECT COALESCE(SUM(price), 0) FROM tickets) as total_revenue, (SELECT COALESCE(SUM(platform_fee_charged), 0) FROM tickets) as total_platform_fees, (SELECT COUNT(DISTINCT DATE(created_at)) FROM tickets WHERE created_at >= NOW() - INTERVAL '30 days') as active_days_last_30, (SELECT COUNT(*) FROM users WHERE created_at >= NOW() - INTERVAL '7 days') as new_users_last_7_days; -- Add index for super admin queries CREATE INDEX idx_users_is_super_admin ON users(is_super_admin); -- Add comments for clarity COMMENT ON COLUMN users.is_super_admin IS 'Whether the user has super admin privileges'; COMMENT ON FUNCTION make_user_admin(TEXT) IS 'Promotes a user to admin role'; COMMENT ON FUNCTION make_user_super_admin(TEXT) IS 'Promotes a user to super admin role'; COMMENT ON FUNCTION is_super_admin(UUID) IS 'Checks if a user is a super admin'; COMMENT ON FUNCTION exec_sql(TEXT) IS 'Executes arbitrary SQL (for setup scripts)';