From 4db9d836345eb78f194932a776fef5bd14e1a949 Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Thu, 11 Jun 2026 12:38:17 -0500 Subject: [PATCH 1/2] =?UTF-8?q?fix(database):=20song=5Fidentifiers=20uniqu?= =?UTF-8?q?eness=20per=20song=20=E2=80=94=20albums=20map=20to=20many=20son?= =?UTF-8?q?gs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The (platform, identifier_type, value) unique constraint capped every album at one mapped song (chat#1794: playcounts served 1/18). Uniqueness moves to (song, platform, identifier_type, value); reverse lookup keeps a non-unique index. Co-Authored-By: Claude Fable 5 --- ..._fix_song_identifiers_album_uniqueness.sql | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 supabase/migrations/20260611120000_fix_song_identifiers_album_uniqueness.sql diff --git a/supabase/migrations/20260611120000_fix_song_identifiers_album_uniqueness.sql b/supabase/migrations/20260611120000_fix_song_identifiers_album_uniqueness.sql new file mode 100644 index 0000000..6bc6797 --- /dev/null +++ b/supabase/migrations/20260611120000_fix_song_identifiers_album_uniqueness.sql @@ -0,0 +1,19 @@ +-- Fix (recoupable/chat#1794): the unique constraint on song_identifiers was +-- (platform, identifier_type, value), which is right for track ids (one +-- external id = one recording) but wrong for album ids — an album contains +-- many songs, so (spotify, album_id, ) must exist once PER SONG. +-- The old constraint silently capped every album at one mapped song, which is +-- why GET /playcounts served 1 of 18 tracks. +-- +-- New uniqueness: one mapping per (song, platform, identifier_type, value). +-- Reverse lookups (value -> songs) keep an index, now non-unique. + +ALTER TABLE public.song_identifiers + DROP CONSTRAINT song_identifiers_platform_type_value_unique; + +ALTER TABLE public.song_identifiers + ADD CONSTRAINT song_identifiers_song_platform_type_value_unique + UNIQUE (song, platform, identifier_type, value); + +CREATE INDEX idx_song_identifiers_lookup + ON public.song_identifiers (platform, identifier_type, value); From 88d87ef4c18c7d096ab723f07bc685fc8ec96421 Mon Sep 17 00:00:00 2001 From: Sweets Sweetman Date: Thu, 11 Jun 2026 12:52:12 -0500 Subject: [PATCH 2/2] fix(database): drop the old unique constraint by catalog lookup, not name MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The constraint was declared inline in 20260610010000, so its name is Postgres-generated (…_key) — the explicit-name DROP failed on the preview branch (SQLSTATE 42704). Co-Authored-By: Claude Fable 5 --- ..._fix_song_identifiers_album_uniqueness.sql | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/supabase/migrations/20260611120000_fix_song_identifiers_album_uniqueness.sql b/supabase/migrations/20260611120000_fix_song_identifiers_album_uniqueness.sql index 6bc6797..46e8077 100644 --- a/supabase/migrations/20260611120000_fix_song_identifiers_album_uniqueness.sql +++ b/supabase/migrations/20260611120000_fix_song_identifiers_album_uniqueness.sql @@ -5,15 +5,29 @@ -- The old constraint silently capped every album at one mapped song, which is -- why GET /playcounts served 1 of 18 tracks. -- --- New uniqueness: one mapping per (song, platform, identifier_type, value). --- Reverse lookups (value -> songs) keep an index, now non-unique. +-- The old constraint was declared inline in 20260610010000, so its name is +-- Postgres-generated — drop the table's (single) unique constraint by lookup +-- instead of by name. -ALTER TABLE public.song_identifiers - DROP CONSTRAINT song_identifiers_platform_type_value_unique; +DO $$ +DECLARE + old_constraint text; +BEGIN + SELECT conname INTO old_constraint + FROM pg_constraint + WHERE conrelid = 'public.song_identifiers'::regclass + AND contype = 'u'; + IF old_constraint IS NOT NULL THEN + EXECUTE format('ALTER TABLE public.song_identifiers DROP CONSTRAINT %I', old_constraint); + END IF; +END $$; + +-- New uniqueness: one mapping per (song, platform, identifier_type, value). ALTER TABLE public.song_identifiers ADD CONSTRAINT song_identifiers_song_platform_type_value_unique UNIQUE (song, platform, identifier_type, value); +-- Reverse lookups (value -> songs) keep an index, now non-unique. CREATE INDEX idx_song_identifiers_lookup ON public.song_identifiers (platform, identifier_type, value);