-- R1 Sammlung: collection_items, favorite_games, bgg_links. Alles ist privat (Entscheidung O3). create table public.collection_items ( id uuid primary key default gen_random_uuid(), owner_id uuid not null references public.profiles (id) on delete cascade, game_id uuid not null references public.games (id), variant_id uuid, list text not null default 'owned' check (list in ('owned', 'wishlist', 'shopping')), note text check (char_length(note) <= 1000), acquired_on date, created_at timestamptz not null default now(), updated_at timestamptz not null default now(), -- Ein Eintrag je Spiel und Nutzer (O8); Editionen laufen über variant_id (O4). unique (owner_id, game_id), -- Die Variante muss zum Spiel gehören. foreign key (variant_id, game_id) references public.game_variants (id, game_id) ); create index collection_items_game_id_idx on public.collection_items (game_id); create table public.favorite_games ( id uuid primary key default gen_random_uuid(), profile_id uuid not null references public.profiles (id) on delete cascade, game_id uuid not null references public.games (id) on delete cascade, position smallint not null check (position between 1 and 5), created_at timestamptz not null default now(), updated_at timestamptz not null default now(), unique (profile_id, position), unique (profile_id, game_id) ); create index favorite_games_game_id_idx on public.favorite_games (game_id); create table public.bgg_links ( id uuid primary key default gen_random_uuid(), profile_id uuid not null unique references public.profiles (id) on delete cascade, bgg_username text not null check (char_length(bgg_username) between 1 and 100), last_import_at timestamptz, created_at timestamptz not null default now(), updated_at timestamptz not null default now() ); create trigger set_updated_at before update on public.collection_items for each row execute function public.set_updated_at(); create trigger set_updated_at before update on public.favorite_games for each row execute function public.set_updated_at(); create trigger set_updated_at before update on public.bgg_links for each row execute function public.set_updated_at(); alter table public.collection_items enable row level security; alter table public.favorite_games enable row level security; alter table public.bgg_links enable row level security; revoke all on public.collection_items, public.favorite_games, public.bgg_links from anon, authenticated; grant select, insert, update, delete on public.collection_items, public.favorite_games, public.bgg_links to authenticated; -- Nur der Eigentümer sieht und ändert seine Zeilen. Neue Zeilen dürfen nur auf Spiele zeigen, -- die der Nutzer selbst sehen darf (Katalog oder eigene private Spiele). create policy collection_items_own on public.collection_items for all to authenticated using (owner_id = (select auth.uid())) with check ( owner_id = (select auth.uid()) and exists (select 1 from public.games g where g.id = game_id) ); create policy favorite_games_own on public.favorite_games for all to authenticated using (profile_id = (select auth.uid())) with check ( profile_id = (select auth.uid()) and exists (select 1 from public.games g where g.id = game_id) ); create policy bgg_links_own on public.bgg_links for all to authenticated using (profile_id = (select auth.uid())) with check (profile_id = (select auth.uid()));