mirror of
https://github.com/jcreek/LivingDexTracker.git
synced 2026-07-13 02:53:45 +00:00
feat(#67): Add support for multiple pokedexes per user
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
-- Create pokedexes table
|
||||
CREATE TABLE pokedexes (
|
||||
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
||||
"userId" UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
|
||||
name TEXT NOT NULL,
|
||||
description TEXT,
|
||||
|
||||
-- Type flags (combinable)
|
||||
"isLivingDex" BOOLEAN DEFAULT FALSE,
|
||||
"isShinyDex" BOOLEAN DEFAULT FALSE,
|
||||
"isOriginDex" BOOLEAN DEFAULT FALSE,
|
||||
"isFormDex" BOOLEAN DEFAULT FALSE,
|
||||
|
||||
-- Scope (NULL = all games, or specific game)
|
||||
"gameScope" TEXT,
|
||||
|
||||
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
|
||||
"updatedAt" TIMESTAMPTZ DEFAULT NOW(),
|
||||
|
||||
-- User can't have duplicate pokédex names
|
||||
UNIQUE("userId", name)
|
||||
);
|
||||
|
||||
-- Create index for performance
|
||||
CREATE INDEX idx_pokedexes_user_id ON pokedexes("userId");
|
||||
|
||||
-- Trigger to automatically update updated_at timestamp
|
||||
CREATE TRIGGER update_pokedexes_updated_at
|
||||
BEFORE UPDATE ON pokedexes
|
||||
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
|
||||
-- Enable RLS
|
||||
ALTER TABLE pokedexes ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- RLS POLICIES - CRITICAL: Users can ONLY access their own pokédexes
|
||||
|
||||
-- Users can ONLY view their own pokédexes
|
||||
CREATE POLICY "Users can view own pokedexes" ON pokedexes
|
||||
FOR SELECT USING (auth.uid() = "userId");
|
||||
|
||||
-- Users can ONLY create pokédexes for themselves
|
||||
CREATE POLICY "Users can create own pokedexes" ON pokedexes
|
||||
FOR INSERT WITH CHECK (auth.uid() = "userId");
|
||||
|
||||
-- Users can ONLY update their own pokédexes
|
||||
CREATE POLICY "Users can update own pokedexes" ON pokedexes
|
||||
FOR UPDATE USING (auth.uid() = "userId");
|
||||
|
||||
-- Users can ONLY delete their own pokédexes
|
||||
CREATE POLICY "Users can delete own pokedexes" ON pokedexes
|
||||
FOR DELETE USING (auth.uid() = "userId");
|
||||
@@ -0,0 +1,74 @@
|
||||
-- Truncate existing catch records (no real users, as confirmed)
|
||||
TRUNCATE TABLE catch_records;
|
||||
|
||||
-- Add pokedexId column
|
||||
ALTER TABLE catch_records
|
||||
ADD COLUMN "pokedexId" UUID REFERENCES pokedexes(id) ON DELETE CASCADE;
|
||||
|
||||
-- Make pokedexId NOT NULL
|
||||
ALTER TABLE catch_records
|
||||
ALTER COLUMN "pokedexId" SET NOT NULL;
|
||||
|
||||
-- Drop old unique constraint (userId, pokedexEntryId)
|
||||
ALTER TABLE catch_records
|
||||
DROP CONSTRAINT IF EXISTS catch_records_userId_pokedexEntryId_key;
|
||||
|
||||
-- Add new unique constraint (userId, pokedexEntryId, pokedexId)
|
||||
ALTER TABLE catch_records
|
||||
ADD CONSTRAINT catch_records_user_pokemon_pokedex_unique
|
||||
UNIQUE("userId", "pokedexEntryId", "pokedexId");
|
||||
|
||||
-- Add index for performance
|
||||
CREATE INDEX idx_catch_records_pokedex_id ON catch_records("pokedexId");
|
||||
|
||||
-- RLS POLICIES - CRITICAL: Users can ONLY access catch records for their own pokédexes
|
||||
|
||||
-- Drop existing RLS policies if they exist
|
||||
DROP POLICY IF EXISTS "Users can view own catch records" ON catch_records;
|
||||
DROP POLICY IF EXISTS "Users can insert own catch records" ON catch_records;
|
||||
DROP POLICY IF EXISTS "Users can update own catch records" ON catch_records;
|
||||
DROP POLICY IF EXISTS "Users can delete own catch records" ON catch_records;
|
||||
|
||||
-- Users can ONLY view catch records for their own pokédexes
|
||||
CREATE POLICY "Users can view own catch records" ON catch_records
|
||||
FOR SELECT USING (
|
||||
auth.uid() = "userId" AND
|
||||
EXISTS (
|
||||
SELECT 1 FROM pokedexes
|
||||
WHERE pokedexes.id = catch_records."pokedexId"
|
||||
AND pokedexes."userId" = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
-- Users can ONLY insert catch records for their own pokédexes
|
||||
CREATE POLICY "Users can insert own catch records" ON catch_records
|
||||
FOR INSERT WITH CHECK (
|
||||
auth.uid() = "userId" AND
|
||||
EXISTS (
|
||||
SELECT 1 FROM pokedexes
|
||||
WHERE pokedexes.id = catch_records."pokedexId"
|
||||
AND pokedexes."userId" = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
-- Users can ONLY update catch records for their own pokédexes
|
||||
CREATE POLICY "Users can update own catch records" ON catch_records
|
||||
FOR UPDATE USING (
|
||||
auth.uid() = "userId" AND
|
||||
EXISTS (
|
||||
SELECT 1 FROM pokedexes
|
||||
WHERE pokedexes.id = catch_records."pokedexId"
|
||||
AND pokedexes."userId" = auth.uid()
|
||||
)
|
||||
);
|
||||
|
||||
-- Users can ONLY delete catch records for their own pokédexes
|
||||
CREATE POLICY "Users can delete own catch records" ON catch_records
|
||||
FOR DELETE USING (
|
||||
auth.uid() = "userId" AND
|
||||
EXISTS (
|
||||
SELECT 1 FROM pokedexes
|
||||
WHERE pokedexes.id = catch_records."pokedexId"
|
||||
AND pokedexes."userId" = auth.uid()
|
||||
)
|
||||
);
|
||||
@@ -0,0 +1,25 @@
|
||||
-- Add regional dex number columns to pokedex_entries table
|
||||
-- Each region gets its own integer column for better query performance
|
||||
|
||||
ALTER TABLE pokedex_entries
|
||||
ADD COLUMN IF NOT EXISTS kanto_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS johto_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS hoenn_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS sinnoh_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS unova_bw_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS unova_b2w2_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS kalos_central_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS kalos_coastal_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS kalos_mountain_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS alola_sm_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS alola_usum_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS galar_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS galar_isle_of_armor_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS galar_crown_tundra_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS hisui_dex_number INT,
|
||||
ADD COLUMN IF NOT EXISTS paldea_dex_number INT;
|
||||
|
||||
-- Create indexes for better query performance when filtering/ordering by regional dex
|
||||
-- Only indexing Kanto and Johto for now (other regions to be added incrementally)
|
||||
CREATE INDEX IF NOT EXISTS idx_pokedex_entries_kanto_dex ON pokedex_entries(kanto_dex_number) WHERE kanto_dex_number IS NOT NULL;
|
||||
CREATE INDEX IF NOT EXISTS idx_pokedex_entries_johto_dex ON pokedex_entries(johto_dex_number) WHERE johto_dex_number IS NOT NULL;
|
||||
Reference in New Issue
Block a user