BEGIN; CREATE OR REPLACE FUNCTION public.handle_new_user() RETURNS trigger LANGUAGE plpgsql SECURITY DEFINER SET search_path = public AS $$ DECLARE user_role TEXT; metadata_role TEXT; user_email TEXT := NEW.email; user_name TEXT; ak_user_id UUID; has_user_roles BOOLEAN := FALSE; has_delivery_staff BOOLEAN := FALSE; BEGIN metadata_role := NULLIF(TRIM(COALESCE(NEW.raw_user_meta_data ->> 'user_role', '')), ''); user_role := CASE WHEN metadata_role IN ('customer', 'merchant', 'delivery', 'service', 'admin') THEN metadata_role WHEN user_email ILIKE '%@admin.%' THEN 'admin' ELSE 'customer' END; IF user_email IS NOT NULL AND POSITION('@' IN user_email) > 1 THEN user_name := SPLIT_PART(user_email, '@', 1); ELSE user_name := 'user_' || SUBSTRING(NEW.id::text, 1, 8); END IF; INSERT INTO public.ak_users (auth_id, email, username, role) VALUES (NEW.id, user_email, user_name, user_role) ON CONFLICT (auth_id) DO UPDATE SET email = COALESCE(EXCLUDED.email, public.ak_users.email), username = COALESCE(EXCLUDED.username, public.ak_users.username), role = COALESCE(NULLIF(public.ak_users.role, ''), EXCLUDED.role), updated_at = now() RETURNING id INTO ak_user_id; IF user_role = 'delivery' THEN SELECT EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'ml_delivery_staff' ) INTO has_delivery_staff; IF has_delivery_staff THEN INSERT INTO public.ml_delivery_staff ( uid, nickname, phone, status, is_active ) SELECT ak_user_id, user_name, '', 1, TRUE WHERE NOT EXISTS ( SELECT 1 FROM public.ml_delivery_staff WHERE uid = ak_user_id ); END IF; END IF; SELECT EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'user_roles' ) INTO has_user_roles; IF has_user_roles THEN BEGIN INSERT INTO public.user_roles (user_id, role, created_by) VALUES (NEW.id, user_role, NEW.id) ON CONFLICT DO NOTHING; EXCEPTION WHEN check_violation THEN RAISE NOTICE '[handle_new_user_v4] WARNING: Skipped user_roles insert due to check violation. user_id: %, role: %', NEW.id, user_role; WHEN not_null_violation THEN RAISE NOTICE '[handle_new_user_v4] WARNING: Failed to INSERT into user_roles due to NOT NULL violation. user_id: %, role: %', NEW.id, user_role; WHEN others THEN RAISE NOTICE '[handle_new_user_v4] WARNING: Skipped user_roles insert due to unexpected error. user_id: %, role: %, err: %', NEW.id, user_role, SQLERRM; END; END IF; UPDATE auth.users SET raw_user_meta_data = COALESCE(raw_user_meta_data, '{}'::jsonb) || jsonb_build_object('user_role', user_role) WHERE id = NEW.id; RETURN NEW; END; $$; UPDATE public.ak_users SET role = 'delivery', updated_at = now() WHERE email = 'test20@163.com'; DO $$ BEGIN IF EXISTS ( SELECT 1 FROM information_schema.tables WHERE table_schema = 'public' AND table_name = 'ml_delivery_staff' ) THEN INSERT INTO public.ml_delivery_staff ( uid, nickname, phone, status, is_active ) SELECT u.id, COALESCE(NULLIF(u.username, ''), SPLIT_PART(u.email, '@', 1), 'delivery_user'), '', 1, TRUE FROM public.ak_users u WHERE u.email = 'test20@163.com' AND u.role = 'delivery' AND NOT EXISTS ( SELECT 1 FROM public.ml_delivery_staff s WHERE s.uid = u.id ); END IF; END $$; COMMIT;