ALTER TABLE public.profiles ADD COLUMN IF NOT EXISTS username text; -- Format check: 3-32 chars, alphanumeric + . _ - ALTER TABLE public.profiles DROP CONSTRAINT IF EXISTS profiles_username_format_chk; ALTER TABLE public.profiles ADD CONSTRAINT profiles_username_format_chk CHECK (username IS NULL OR username ~ '^[A-Za-z0-9._-]{3,32}$'); -- Case-insensitive uniqueness CREATE UNIQUE INDEX IF NOT EXISTS profiles_username_lower_unique_idx ON public.profiles (lower(username)) WHERE username IS NOT NULL; -- Lookup email by username (used by the login screen) CREATE OR REPLACE FUNCTION public.lookup_email_by_username(_username text) RETURNS text LANGUAGE sql STABLE SECURITY DEFINER SET search_path TO 'public' AS $$ SELECT p.email FROM public.profiles p WHERE lower(p.username) = lower(_username) LIMIT 1 $$; GRANT EXECUTE ON FUNCTION public.lookup_email_by_username(text) TO anon, authenticated;