-- Users and Roles -- This migration creates user-related tables with clean separation -- ============================================= -- 1. ROLES TABLE -- ============================================= CREATE TABLE IF NOT EXISTS public.roles ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), name TEXT NOT NULL UNIQUE, description TEXT, created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- ============================================= -- 2. USER PROFILES TABLE -- ============================================= CREATE TABLE IF NOT EXISTS public.user_profiles ( id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE, email TEXT NOT NULL UNIQUE, first_name TEXT, last_name TEXT, status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active', 'inactive', 'suspended')), created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() ); -- ============================================= -- 3. USER ROLES JUNCTION TABLE -- ============================================= CREATE TABLE IF NOT EXISTS public.user_roles ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), user_id UUID NOT NULL REFERENCES public.user_profiles(id) ON DELETE CASCADE, role_id UUID NOT NULL REFERENCES public.roles(id) ON DELETE CASCADE, assigned_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), assigned_by UUID REFERENCES public.user_profiles(id), UNIQUE(user_id, role_id) ); -- ============================================= -- 4. INDEXES FOR PERFORMANCE -- ============================================= CREATE INDEX IF NOT EXISTS idx_user_profiles_email ON public.user_profiles(email); CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON public.user_roles(user_id); CREATE INDEX IF NOT EXISTS idx_user_roles_role_id ON public.user_roles(role_id); -- ============================================= -- 5. TRIGGERS -- ============================================= -- Create trigger for updated_at on user_profiles CREATE TRIGGER set_updated_at_user_profiles BEFORE UPDATE ON public.user_profiles FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at(); -- Create trigger for updated_at on roles CREATE TRIGGER set_updated_at_roles BEFORE UPDATE ON public.roles FOR EACH ROW EXECUTE FUNCTION public.handle_updated_at(); -- ============================================= -- 6. GRANT PERMISSIONS -- ============================================= GRANT ALL ON public.roles TO authenticated; GRANT ALL ON public.user_profiles TO authenticated; GRANT ALL ON public.user_roles TO authenticated; -- ============================================= -- 7. ENABLE ROW LEVEL SECURITY -- ============================================= ALTER TABLE public.roles ENABLE ROW LEVEL SECURITY; ALTER TABLE public.user_profiles ENABLE ROW LEVEL SECURITY; ALTER TABLE public.user_roles ENABLE ROW LEVEL SECURITY; -- ============================================= -- 8. CREATE RLS POLICIES -- ============================================= -- Create RLS policies for roles (read-only for all authenticated users) CREATE POLICY "Roles are viewable by authenticated users" ON public.roles FOR SELECT USING (auth.role() = 'authenticated'); -- Create RLS policies for user_profiles CREATE POLICY "User profiles are viewable by authenticated users" ON public.user_profiles FOR SELECT USING (auth.role() = 'authenticated'); CREATE POLICY "User profiles are insertable by authenticated users" ON public.user_profiles FOR INSERT WITH CHECK (auth.role() = 'authenticated'); CREATE POLICY "User profiles are updatable by authenticated users" ON public.user_profiles FOR UPDATE USING (auth.role() = 'authenticated'); CREATE POLICY "User profiles are deletable by authenticated users" ON public.user_profiles FOR DELETE USING (auth.role() = 'authenticated'); -- Create RLS policies for user_roles CREATE POLICY "User roles are viewable by authenticated users" ON public.user_roles FOR SELECT USING (auth.role() = 'authenticated'); CREATE POLICY "User roles are insertable by authenticated users" ON public.user_roles FOR INSERT WITH CHECK (auth.role() = 'authenticated'); CREATE POLICY "User roles are updatable by authenticated users" ON public.user_roles FOR UPDATE USING (auth.role() = 'authenticated'); CREATE POLICY "User roles are deletable by authenticated users" ON public.user_roles FOR DELETE USING (auth.role() = 'authenticated');