mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-07-12 18:43:45 +00:00
fix(#64): Address PR comments
This commit is contained in:
@@ -8,6 +8,7 @@ SELECT
|
||||
p.id AS "pokedexId",
|
||||
pe.id AS "pokedexEntryId"
|
||||
FROM pokedexes p
|
||||
LEFT JOIN region_game_mappings rg ON rg.game = p."gameScope"
|
||||
CROSS JOIN pokedex_entries pe
|
||||
WHERE
|
||||
-- Form filter: if isFormDex is false, only include base forms
|
||||
@@ -15,10 +16,8 @@ WHERE
|
||||
(p."isFormDex" = true OR (pe.form IS NULL OR (pe.pokemon = 'Unown' AND pe.form = 'A')))
|
||||
-- Game scope filter: if gameScope is specified, filter by game
|
||||
AND (p."gameScope" IS NULL OR pe."gamesToCatchIn" @> ARRAY[p."gameScope"]::TEXT[])
|
||||
-- Region filter: if gameScope is specified, filter by region
|
||||
AND (p."gameScope" IS NULL OR pe."regionToCatchIn" = (
|
||||
SELECT region FROM region_game_mappings WHERE game = p."gameScope" LIMIT 1
|
||||
))
|
||||
-- Region filter: only enforce when a mapping exists
|
||||
AND (p."gameScope" IS NULL OR rg.region IS NULL OR pe."regionToCatchIn" = rg.region)
|
||||
ON CONFLICT ("pokedexId", "pokedexEntryId") DO NOTHING;
|
||||
|
||||
-- Add comment to document this migration
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
-- Create function to atomically recalculate pokedex entries mapping
|
||||
-- This function replaces the two-step delete+insert process with a single atomic operation
|
||||
-- to prevent orphaned pokedexes if repopulation fails or yields an empty list
|
||||
|
||||
CREATE OR REPLACE FUNCTION recalculate_pokedex_mappings(
|
||||
p_pokedex_id UUID,
|
||||
p_entry_ids BIGINT[]
|
||||
)
|
||||
RETURNS VOID
|
||||
SECURITY DEFINER
|
||||
SET search_path = public, pg_temp
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
-- Validate that entry_ids is not empty to avoid accidental deletion
|
||||
IF p_entry_ids IS NULL OR array_length(p_entry_ids, 1) IS NULL THEN
|
||||
RAISE EXCEPTION 'entry_ids cannot be null or empty';
|
||||
END IF;
|
||||
|
||||
-- Delete old mappings and insert new mappings in a single transaction
|
||||
-- This ensures atomicity - either both operations succeed or both fail
|
||||
DELETE FROM pokedex_entries_mapping
|
||||
WHERE "pokedexId" = p_pokedex_id;
|
||||
|
||||
INSERT INTO pokedex_entries_mapping ("pokedexId", "pokedexEntryId")
|
||||
SELECT p_pokedex_id, unnest(p_entry_ids);
|
||||
END;
|
||||
$$;
|
||||
@@ -0,0 +1,16 @@
|
||||
-- Fix RLS SELECT policy on pokedex_entries_mapping to restrict reads to owning user
|
||||
-- This prevents exposing all user mappings and ensures consistency with INSERT/DELETE policies
|
||||
|
||||
-- Drop the overly permissive public SELECT policy
|
||||
DROP POLICY IF EXISTS "Anyone can view pokedex entries mapping" ON pokedex_entries_mapping;
|
||||
|
||||
-- Create a new SELECT policy that restricts reads to the owning user
|
||||
CREATE POLICY "Users can view own pokedex entries mapping"
|
||||
ON pokedex_entries_mapping
|
||||
FOR SELECT USING (
|
||||
EXISTS (
|
||||
SELECT 1 FROM pokedexes
|
||||
WHERE pokedexes.id = pokedex_entries_mapping."pokedexId"
|
||||
AND pokedexes."userId" = auth.uid()
|
||||
)
|
||||
);
|
||||
Reference in New Issue
Block a user