Add saved starter words for signed-in players

Players can save up to 3 favorite opening words and tap one to fill the
current row. Words are stored on profiles.starter_words and saved through
the set_starter_words RPC, which validates them against the dictionary.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Zakaria
2026-10-28 10:39:32 -04:00
parent e4d0d3b55c
commit 6daf3237e8
5 changed files with 427 additions and 4 deletions
+54 -1
View File
@@ -18,7 +18,15 @@ create table if not exists public.profiles (
);
alter table public.profiles
add column if not exists username text;
add column if not exists username text,
add column if not exists starter_words text[] not null default '{}';
alter table public.profiles
drop constraint if exists profiles_starter_words_limit;
alter table public.profiles
add constraint profiles_starter_words_limit
check (cardinality(starter_words) <= 3);
create unique index if not exists profiles_username_key
on public.profiles (lower(username))
@@ -490,6 +498,50 @@ begin
end;
$$;
create or replace function public.set_starter_words(words text[])
returns text[]
language plpgsql
security definer
set search_path = public
as $$
declare
normalized_words text[];
begin
if auth.uid() is null then
raise exception 'Sign in to save starter words';
end if;
select coalesce(array_agg(word order by first_position), '{}')
into normalized_words
from (
select lower(trim(candidate)) as word, min(position) as first_position
from unnest(coalesce(words, '{}')) with ordinality as input(candidate, position)
where nullif(trim(candidate), '') is not null
group by lower(trim(candidate))
) deduped;
if cardinality(normalized_words) > 3 then
raise exception 'You can save up to 3 starter words';
end if;
if exists (
select 1
from unnest(normalized_words) as candidate(word)
where candidate.word !~ '^[a-z]{5}$'
or not exists (select 1 from public.wordle_dictionary dictionary where dictionary.word = candidate.word)
) then
raise exception 'Not in word list';
end if;
update public.profiles
set starter_words = normalized_words,
updated_at = now()
where id = auth.uid();
return normalized_words;
end;
$$;
create or replace function public.get_player_current_streak(target_user_id uuid)
returns integer
language plpgsql
@@ -743,6 +795,7 @@ grant select, update on public.profiles to authenticated;
grant select on public.wordle_rounds to authenticated;
grant select on public.wordle_guesses to authenticated;
grant execute on function public.is_username_available(text) to anon, authenticated;
grant execute on function public.set_starter_words(text[]) to authenticated;
grant execute on function public.require_confirmed_email() to authenticated;
grant execute on function public.start_hourly_round() to authenticated;
grant execute on function public.submit_guess(uuid, text) to authenticated;