-- RBAC Schema Migration -- Creates the foundational tables for Role-Based Access Control -- Enable necessary extensions CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- Create roles table CREATE TABLE IF NOT EXISTS public.roles ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), name TEXT UNIQUE NOT NULL CHECK (name IN ('admin', 'conductor', 'analyst')), description TEXT NOT NULL, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Create user_profiles table to extend auth.users CREATE TABLE IF NOT EXISTS public.user_profiles ( id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE, email TEXT NOT NULL, role_id UUID NOT NULL REFERENCES public.roles(id), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- Create indexes for better performance CREATE INDEX IF NOT EXISTS idx_user_profiles_role_id ON public.user_profiles(role_id); CREATE INDEX IF NOT EXISTS idx_user_profiles_email ON public.user_profiles(email); -- Create updated_at trigger function CREATE OR REPLACE FUNCTION public.handle_updated_at() RETURNS TRIGGER AS $$ BEGIN NEW.updated_at = NOW(); RETURN NEW; END; $$ LANGUAGE plpgsql; -- Create triggers for updated_at CREATE TRIGGER set_updated_at_roles BEFORE UPDATE ON public.roles FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at(); CREATE TRIGGER set_updated_at_user_profiles BEFORE UPDATE ON public.user_profiles FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at(); -- Insert the three required roles INSERT INTO public.roles (name, description) VALUES ('admin', 'Full system access with user management capabilities'), ('conductor', 'Operational access for conducting experiments and managing data'), ('analyst', 'Read-only access for data analysis and reporting') ON CONFLICT (name) DO NOTHING;