Files
LivingDexTracker/supabase/migrations/20260914000000_add_pokedex_sharing.sql
T
2026-09-14 14:25:09 +01:00

74 lines
2.2 KiB
PL/PgSQL

-- Stable capability links for read-only Pokédex sharing.
ALTER TABLE pokedexes
ADD COLUMN "shareToken" UUID NOT NULL DEFAULT gen_random_uuid();
ALTER TABLE pokedexes
ADD CONSTRAINT pokedexes_share_token_key UNIQUE ("shareToken");
CREATE OR REPLACE FUNCTION prevent_pokedex_share_token_update()
RETURNS TRIGGER
LANGUAGE plpgsql
SET search_path = public, pg_temp
AS $$
BEGIN
IF NEW."shareToken" IS DISTINCT FROM OLD."shareToken" THEN
RAISE EXCEPTION 'shareToken is immutable';
END IF;
RETURN NEW;
END;
$$;
CREATE TRIGGER prevent_pokedex_share_token_update
BEFORE UPDATE OF "shareToken" ON pokedexes
FOR EACH ROW EXECUTE FUNCTION prevent_pokedex_share_token_update();
-- This is the only anonymous path into user-owned Pokédex data. Keep the returned
-- shape deliberately narrow: no owner identity, row IDs, timestamps, or personal notes.
CREATE OR REPLACE FUNCTION get_shared_pokedex(p_share_token UUID)
RETURNS JSONB
SECURITY DEFINER
STABLE
SET search_path = public, pg_temp
LANGUAGE sql
AS $$
SELECT jsonb_build_object(
'name', p.name,
'description', COALESCE(p.description, ''),
'isLivingDex', COALESCE(p."isLivingDex", false),
'isShinyDex', COALESCE(p."isShinyDex", false),
'isOriginDex', COALESCE(p."isOriginDex", false),
'isFormDex', COALESCE(p."isFormDex", false),
'gameScope', p."gameScope",
'dexScopes', COALESCE(
(
SELECT jsonb_agg(pds."dexId" ORDER BY pds."dexId")
FROM pokedex_dex_scopes pds
WHERE pds."pokedexId" = p.id
),
'[]'::jsonb
),
'catchStatuses', COALESCE(
(
SELECT jsonb_agg(
jsonb_build_object(
'pokemonId', cr."pokemonId"::text,
'caught', COALESCE(cr.caught, false),
'haveToEvolve', COALESCE(cr."haveToEvolve", false),
'inHome', COALESCE(cr."inHome", false),
'hasGigantamaxed', COALESCE(cr."hasGigantamaxed", false)
)
ORDER BY cr."pokemonId"
)
FROM catch_records cr
WHERE cr."pokedexId" = p.id
),
'[]'::jsonb
)
)
FROM pokedexes p
WHERE p."shareToken" = p_share_token;
$$;
REVOKE ALL ON FUNCTION get_shared_pokedex(UUID) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION get_shared_pokedex(UUID) TO anon, authenticated;