Shuffle/supabase/tests/support/startbestand_fixture.inc
cschlaefke 976fbe9fe1 feat(db): startbestand tool reads alt_titles column (KAT-01, 3a)
Parses de:Title;en:Title (';' forbidden in titles, errors with line number),
generates an idempotent reconcile for game_alt_titles, adds an info row to
checks.sql and attaches alternative titles to Testspiel B. Regenerated files.

Refs #3

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-11-04 01:12:25 +01:00

115 lines
6.4 KiB
SQL

-- Erzeugt von supabase/catalog/build_startbestand.ts. Nicht von Hand bearbeiten.
-- Startbestand (KAT-05). Idempotent bis zum Go-live; danach eingefroren (docs/katalog-pflege.md).
-- Reihenfolge: Migrationen, vocabulary.sql, dann diese Datei.
do $guard$
declare
missing text;
begin
select string_agg(n, ', ') into missing from jsonb_array_elements_text('["Testgenre A","Testgenre B"]'::jsonb) as t(n)
where not exists (select 1 from public.genres g where g.name_de = t.n);
if missing is not null then
raise exception 'startbestand: Genre fehlt in der Datenbank (vocabulary.sql eingespielt?): %', missing;
end if;
select string_agg(n, ', ') into missing from jsonb_array_elements_text('["Testmechanik A","Testmechanik B"]'::jsonb) as t(n)
where not exists (select 1 from public.mechanics m where m.name_de = t.n);
if missing is not null then
raise exception 'startbestand: Mechanik fehlt in der Datenbank (vocabulary.sql eingespielt?): %', missing;
end if;
end
$guard$;
-- Verlage
insert into public.publishers (name) values
('Testverlag'),
('Zweiter Testverlag')
on conflict ((lower(name))) do nothing;
-- Spiele (unveränderte Zeilen werden nicht angefasst)
insert into public.games (id, title, description, description_locale, year, min_players, max_players, min_minutes, max_minutes, min_age, visibility) values
('5189ad0e-ab5b-5500-a3e0-a0b3671cdf14', 'Testspiel A', 'Fiktives Testspiel A. Nur für automatische Tests.', 'de', 2020, 2, 4, 30, 60, 8, 'catalog'),
('6577717f-4c1f-5829-af22-ae6bb37c8394', 'Testspiel B', 'Fiktives Testspiel B, mit Komma.', 'de', 2021, 1, 5, 10, 20, 6, 'catalog'),
('c3c6f0fd-43bc-5fb9-b692-3be7770b6cc3', 'Testspiel C: Wo''s lang geht', 'Fiktives Testspiel C mit Apostroph im Titel.', 'de', 1999, 3, 3, 45, 45, 12, 'catalog')
on conflict (id) do update set
title = excluded.title,
description = excluded.description,
description_locale = excluded.description_locale,
year = excluded.year,
min_players = excluded.min_players,
max_players = excluded.max_players,
min_minutes = excluded.min_minutes,
max_minutes = excluded.max_minutes,
min_age = excluded.min_age
where (games.title, games.description, games.description_locale, games.year, games.min_players, games.max_players, games.min_minutes, games.max_minutes, games.min_age)
is distinct from (excluded.title, excluded.description, excluded.description_locale, excluded.year, excluded.min_players, excluded.max_players, excluded.min_minutes, excluded.max_minutes, excluded.min_age);
-- hidden = ja: ausblenden, nichts löschen
update public.games set hidden_at = now()
where hidden_at is null and id = any(array['c3c6f0fd-43bc-5fb9-b692-3be7770b6cc3']::uuid[]);
-- Zuordnung Genre: fehlende anlegen, nicht mehr gewünschte löschen
with want(game_id, term) as (values
('5189ad0e-ab5b-5500-a3e0-a0b3671cdf14'::uuid, 'Testgenre A'),
('5189ad0e-ab5b-5500-a3e0-a0b3671cdf14'::uuid, 'Testgenre B'),
('6577717f-4c1f-5829-af22-ae6bb37c8394'::uuid, 'Testgenre A'),
('c3c6f0fd-43bc-5fb9-b692-3be7770b6cc3'::uuid, 'Testgenre B')
), resolved as (
select w.game_id, t.id as genre_id from want w join public.genres t on t.name_de = w.term
), removed as (
delete from public.game_genres l
where l.game_id = any(array['5189ad0e-ab5b-5500-a3e0-a0b3671cdf14', '6577717f-4c1f-5829-af22-ae6bb37c8394', 'c3c6f0fd-43bc-5fb9-b692-3be7770b6cc3']::uuid[])
and not exists (select 1 from resolved r where r.game_id = l.game_id and r.genre_id = l.genre_id)
)
insert into public.game_genres (game_id, genre_id)
select game_id, genre_id from resolved
on conflict (game_id, genre_id) do nothing;
-- Zuordnung Mechanik: fehlende anlegen, nicht mehr gewünschte löschen
with want(game_id, term) as (values
('5189ad0e-ab5b-5500-a3e0-a0b3671cdf14'::uuid, 'Testmechanik A'),
('6577717f-4c1f-5829-af22-ae6bb37c8394'::uuid, 'Testmechanik A'),
('6577717f-4c1f-5829-af22-ae6bb37c8394'::uuid, 'Testmechanik B'),
('c3c6f0fd-43bc-5fb9-b692-3be7770b6cc3'::uuid, 'Testmechanik B')
), resolved as (
select w.game_id, t.id as mechanic_id from want w join public.mechanics t on t.name_de = w.term
), removed as (
delete from public.game_mechanics l
where l.game_id = any(array['5189ad0e-ab5b-5500-a3e0-a0b3671cdf14', '6577717f-4c1f-5829-af22-ae6bb37c8394', 'c3c6f0fd-43bc-5fb9-b692-3be7770b6cc3']::uuid[])
and not exists (select 1 from resolved r where r.game_id = l.game_id and r.mechanic_id = l.mechanic_id)
)
insert into public.game_mechanics (game_id, mechanic_id)
select game_id, mechanic_id from resolved
on conflict (game_id, mechanic_id) do nothing;
-- Zuordnung Verlag: fehlende anlegen, nicht mehr gewünschte löschen
with want(game_id, term) as (values
('5189ad0e-ab5b-5500-a3e0-a0b3671cdf14'::uuid, 'Testverlag'),
('6577717f-4c1f-5829-af22-ae6bb37c8394'::uuid, 'Testverlag'),
('6577717f-4c1f-5829-af22-ae6bb37c8394'::uuid, 'Zweiter Testverlag'),
('c3c6f0fd-43bc-5fb9-b692-3be7770b6cc3'::uuid, 'TESTVERLAG')
), resolved as (
select w.game_id, t.id as publisher_id from want w join public.publishers t on lower(t.name) = lower(w.term)
), removed as (
delete from public.game_publishers l
where l.game_id = any(array['5189ad0e-ab5b-5500-a3e0-a0b3671cdf14', '6577717f-4c1f-5829-af22-ae6bb37c8394', 'c3c6f0fd-43bc-5fb9-b692-3be7770b6cc3']::uuid[])
and not exists (select 1 from resolved r where r.game_id = l.game_id and r.publisher_id = l.publisher_id)
)
insert into public.game_publishers (game_id, publisher_id)
select game_id, publisher_id from resolved
on conflict (game_id, publisher_id) do nothing;
-- Alternative Titel: fehlende anlegen, geänderte Schreibweise aktualisieren, nicht mehr gewünschte löschen
with want(game_id, locale, title) as (values
('6577717f-4c1f-5829-af22-ae6bb37c8394'::uuid, 'de', 'Testspiel Bravo'),
('6577717f-4c1f-5829-af22-ae6bb37c8394'::uuid, 'en', 'Test Game Bravo')
), removed as (
delete from public.game_alt_titles a
where a.game_id = any(array['5189ad0e-ab5b-5500-a3e0-a0b3671cdf14', '6577717f-4c1f-5829-af22-ae6bb37c8394', 'c3c6f0fd-43bc-5fb9-b692-3be7770b6cc3']::uuid[])
and not exists (select 1 from want w where w.game_id = a.game_id and w.locale = a.locale
and public.search_normalize(w.title) = a.title_search)
)
insert into public.game_alt_titles (game_id, locale, title)
select game_id, locale, title from want
on conflict (game_id, locale, title_search) do update set title = excluded.title
where public.game_alt_titles.title is distinct from excluded.title;