-- Monaco USA Portal - Supabase Schema Initialization -- This MUST run before any other migrations to create required schemas for Supabase -- The auth and storage schemas are required by GoTrue and Storage API -- Create extensions schema for PostgreSQL extensions CREATE SCHEMA IF NOT EXISTS extensions; -- Create auth schema for GoTrue (authentication) CREATE SCHEMA IF NOT EXISTS auth; -- Create storage schema for Storage API CREATE SCHEMA IF NOT EXISTS storage; -- Create realtime schema for Realtime subscriptions CREATE SCHEMA IF NOT EXISTS _realtime; -- Create graphql_public schema for GraphQL CREATE SCHEMA IF NOT EXISTS graphql_public; -- Enable required extensions CREATE EXTENSION IF NOT EXISTS "uuid-ossp" WITH SCHEMA extensions; CREATE EXTENSION IF NOT EXISTS pgcrypto WITH SCHEMA extensions; -- Grant necessary permissions GRANT USAGE ON SCHEMA auth TO postgres, anon, authenticated, service_role; GRANT USAGE ON SCHEMA storage TO postgres, anon, authenticated, service_role; GRANT USAGE ON SCHEMA extensions TO postgres, anon, authenticated, service_role; -- Create the roles if they don't exist (for fresh installations) DO $$ BEGIN IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'anon') THEN CREATE ROLE anon NOLOGIN NOINHERIT; END IF; IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'authenticated') THEN CREATE ROLE authenticated NOLOGIN NOINHERIT; END IF; IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'service_role') THEN CREATE ROLE service_role NOLOGIN NOINHERIT BYPASSRLS; END IF; IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'supabase_admin') THEN CREATE ROLE supabase_admin NOLOGIN NOINHERIT BYPASSRLS; END IF; IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'supabase_auth_admin') THEN CREATE ROLE supabase_auth_admin NOLOGIN NOINHERIT; END IF; IF NOT EXISTS (SELECT FROM pg_catalog.pg_roles WHERE rolname = 'supabase_storage_admin') THEN CREATE ROLE supabase_storage_admin NOLOGIN NOINHERIT; END IF; END $$; -- Grant auth schema ownership to auth admin ALTER SCHEMA auth OWNER TO supabase_auth_admin; GRANT ALL ON SCHEMA auth TO supabase_auth_admin; GRANT ALL ON SCHEMA auth TO postgres; -- Grant storage schema ownership to storage admin ALTER SCHEMA storage OWNER TO supabase_storage_admin; GRANT ALL ON SCHEMA storage TO supabase_storage_admin; GRANT ALL ON SCHEMA storage TO postgres; -- Create auth.users table structure needed by GoTrue -- GoTrue will manage this table and run its own migrations CREATE TABLE IF NOT EXISTS auth.users ( id UUID PRIMARY KEY DEFAULT extensions.uuid_generate_v4(), instance_id UUID, aud VARCHAR(255), role VARCHAR(255), email VARCHAR(255) UNIQUE, encrypted_password VARCHAR(255), email_confirmed_at TIMESTAMPTZ, invited_at TIMESTAMPTZ, confirmation_token VARCHAR(255), confirmation_sent_at TIMESTAMPTZ, recovery_token VARCHAR(255), recovery_sent_at TIMESTAMPTZ, email_change_token_new VARCHAR(255), email_change VARCHAR(255), email_change_sent_at TIMESTAMPTZ, last_sign_in_at TIMESTAMPTZ, raw_app_meta_data JSONB, raw_user_meta_data JSONB, is_super_admin BOOLEAN, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW(), phone VARCHAR(15) UNIQUE, phone_confirmed_at TIMESTAMPTZ, phone_change VARCHAR(15), phone_change_token VARCHAR(255), phone_change_sent_at TIMESTAMPTZ, confirmed_at TIMESTAMPTZ GENERATED ALWAYS AS (LEAST(email_confirmed_at, phone_confirmed_at)) STORED, email_change_token_current VARCHAR(255), email_change_confirm_status SMALLINT DEFAULT 0, banned_until TIMESTAMPTZ, reauthentication_token VARCHAR(255), reauthentication_sent_at TIMESTAMPTZ, is_sso_user BOOLEAN DEFAULT FALSE NOT NULL, deleted_at TIMESTAMPTZ, is_anonymous BOOLEAN DEFAULT FALSE NOT NULL ); -- Indexes for auth.users CREATE INDEX IF NOT EXISTS users_instance_id_idx ON auth.users(instance_id); CREATE INDEX IF NOT EXISTS users_email_idx ON auth.users(email); -- Grant permissions on auth.users GRANT ALL ON auth.users TO supabase_auth_admin; GRANT ALL ON auth.users TO postgres; GRANT SELECT ON auth.users TO anon, authenticated; -- Set search path to include both public and auth ALTER DATABASE postgres SET search_path TO public, extensions;