refactor(*):Address PR comments

This commit is contained in:
Josh Creek
2025-07-26 19:42:04 +01:00
parent bc9ce84615
commit fa38fa69ca
22 changed files with 749 additions and 412 deletions
+1 -1
View File
@@ -168,7 +168,7 @@ enable_signup = true
# addresses. If disabled, only the new email is required to confirm.
double_confirm_changes = true
# If enabled, users need to confirm their email address before signing in.
enable_confirmations = false
enable_confirmations = true
# If enabled, users will need to reauthenticate or have logged in recently to change their password.
secure_password_change = false
# Controls the minimum amount of time that must pass before sending another signup confirmation or password reset email.
@@ -1,34 +0,0 @@
-- Initial setup migration for LivingDexTracker
-- This sets up any additional schema needed
-- Note: RLS is already enabled on auth.users by default in Supabase
-- and proper policies are already in place
-- Create a profiles table if we need additional user data
-- This is optional for the current setup since we only use Supabase for auth
-- and store everything else in MongoDB
-- CREATE TABLE profiles (
-- id UUID PRIMARY KEY REFERENCES auth.users(id) ON DELETE CASCADE,
-- username TEXT,
-- avatar_url TEXT,
-- created_at TIMESTAMPTZ DEFAULT NOW(),
-- updated_at TIMESTAMPTZ DEFAULT NOW()
-- );
-- Enable RLS on profiles table
-- ALTER TABLE profiles ENABLE ROW LEVEL SECURITY;
-- Create RLS policies for profiles
-- CREATE POLICY "Users can view own profile"
-- ON profiles
-- FOR SELECT
-- USING (auth.uid() = id);
-- CREATE POLICY "Users can update own profile"
-- ON profiles
-- FOR UPDATE
-- USING (auth.uid() = id);
-- Note: MongoDB collections (pokedexentries, catchrecords) are handled by the app
-- Supabase is only used for authentication in this hybrid setup
@@ -6,102 +6,128 @@
-- Pokemon entries table (replaces pokedexentries MongoDB collection)
CREATE TABLE pokedex_entries (
id BIGSERIAL PRIMARY KEY,
pokedex_number INTEGER NOT NULL,
"pokedexNumber" INTEGER NOT NULL,
pokemon TEXT NOT NULL,
form TEXT,
can_gigantamax BOOLEAN DEFAULT FALSE,
region_to_catch_in TEXT,
games_to_catch_in TEXT[], -- Array of games
region_to_evolve_in TEXT,
evolution_information TEXT,
catch_information TEXT[], -- Array of catch info
"canGigantamax" BOOLEAN DEFAULT FALSE,
"regionToCatchIn" TEXT,
"gamesToCatchIn" TEXT[], -- Array of games
"regionToEvolveIn" TEXT,
"evolutionInformation" TEXT,
"catchInformation" TEXT[], -- Array of catch info
-- Box placement for forms view
box_placement_forms_box INTEGER,
box_placement_forms_row INTEGER,
box_placement_forms_column INTEGER,
"boxPlacementFormsBox" INTEGER,
"boxPlacementFormsRow" INTEGER,
"boxPlacementFormsColumn" INTEGER,
-- Box placement for no-forms view
box_placement_box INTEGER,
box_placement_row INTEGER,
box_placement_column INTEGER,
"boxPlacementBox" INTEGER,
"boxPlacementRow" INTEGER,
"boxPlacementColumn" INTEGER,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
"updatedAt" TIMESTAMPTZ DEFAULT NOW()
);
-- Add unique constraint to prevent duplicate pokemon forms
ALTER TABLE pokedex_entries ADD CONSTRAINT unique_pokemon_form
UNIQUE("pokedexNumber", form);
-- Catch records table (replaces catchrecords MongoDB collection)
CREATE TABLE catch_records (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
pokedex_entry_id BIGINT NOT NULL REFERENCES pokedex_entries(id) ON DELETE CASCADE,
"userId" UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
"pokedexEntryId" BIGINT NOT NULL REFERENCES pokedex_entries(id) ON DELETE CASCADE,
-- Catch status fields
have_to_evolve BOOLEAN DEFAULT FALSE,
"haveToEvolve" BOOLEAN DEFAULT FALSE,
caught BOOLEAN DEFAULT FALSE,
in_home BOOLEAN DEFAULT FALSE,
has_gigantamaxed BOOLEAN DEFAULT FALSE,
personal_notes TEXT,
"inHome" BOOLEAN DEFAULT FALSE,
"hasGigantamaxed" BOOLEAN DEFAULT FALSE,
"personalNotes" TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW(),
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
"updatedAt" TIMESTAMPTZ DEFAULT NOW(),
-- Ensure one record per user per pokemon entry
UNIQUE(user_id, pokedex_entry_id)
UNIQUE("userId", "pokedexEntryId")
);
-- Region/Game mappings table (replaces regiongamemappings MongoDB collection)
-- Region-game mappings table for filtering
CREATE TABLE region_game_mappings (
id BIGSERIAL PRIMARY KEY,
region TEXT NOT NULL,
games TEXT[] NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
game TEXT NOT NULL,
UNIQUE(region, game)
);
-- Pokedex metadata table (replaces pokedexmetadata MongoDB collection)
CREATE TABLE pokedex_metadata (
-- Metadata table for migration tracking
CREATE TABLE metadata (
id BIGSERIAL PRIMARY KEY,
key TEXT UNIQUE NOT NULL,
value JSONB NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
value TEXT,
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
"updatedAt" TIMESTAMPTZ DEFAULT NOW()
);
-- Enable Row Level Security (RLS) for user data isolation
ALTER TABLE catch_records ENABLE ROW LEVEL SECURITY;
-- RLS Policy: Users can only access their own catch records
CREATE POLICY "Users can only access their own catch records"
ON catch_records FOR ALL
USING (auth.uid() = user_id)
WITH CHECK (auth.uid() = user_id);
-- Create indexes for better performance
CREATE INDEX idx_pokedex_entries_pokedex_number ON pokedex_entries(pokedex_number);
CREATE INDEX idx_pokedex_entries_pokedex_number ON pokedex_entries("pokedexNumber");
CREATE INDEX idx_pokedex_entries_pokemon ON pokedex_entries(pokemon);
CREATE INDEX idx_pokedex_entries_box_placement_forms ON pokedex_entries(box_placement_forms_box, box_placement_forms_row, box_placement_forms_column);
CREATE INDEX idx_pokedex_entries_box_placement ON pokedex_entries(box_placement_box, box_placement_row, box_placement_column);
CREATE INDEX idx_pokedex_entries_box_placement_forms ON pokedex_entries("boxPlacementFormsBox", "boxPlacementFormsRow", "boxPlacementFormsColumn");
CREATE INDEX idx_pokedex_entries_box_placement ON pokedex_entries("boxPlacementBox", "boxPlacementRow", "boxPlacementColumn");
CREATE INDEX idx_catch_records_user_id ON catch_records(user_id);
CREATE INDEX idx_catch_records_pokedex_entry_id ON catch_records(pokedex_entry_id);
CREATE INDEX idx_catch_records_user_id ON catch_records("userId");
CREATE INDEX idx_catch_records_pokedex_entry_id ON catch_records("pokedexEntryId");
CREATE INDEX idx_catch_records_caught ON catch_records(caught);
CREATE INDEX idx_catch_records_in_home ON catch_records(in_home);
CREATE INDEX idx_catch_records_in_home ON catch_records("inHome");
CREATE INDEX idx_catch_records_user_caught ON catch_records("userId", caught);
-- Create updated_at trigger function
-- Function to automatically update updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
NEW."updatedAt" = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
$$ LANGUAGE plpgsql;
-- Add updated_at triggers
CREATE TRIGGER update_pokedex_entries_updated_at BEFORE UPDATE ON pokedex_entries
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- Create triggers for updated_at
CREATE TRIGGER update_pokedex_entries_updated_at
BEFORE UPDATE ON pokedex_entries
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_catch_records_updated_at BEFORE UPDATE ON catch_records
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_catch_records_updated_at
BEFORE UPDATE ON catch_records
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_pokedex_metadata_updated_at BEFORE UPDATE ON pokedex_metadata
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- Enable RLS on all tables
ALTER TABLE pokedex_entries ENABLE ROW LEVEL SECURITY;
ALTER TABLE catch_records ENABLE ROW LEVEL SECURITY;
ALTER TABLE region_game_mappings ENABLE ROW LEVEL SECURITY;
ALTER TABLE metadata ENABLE ROW LEVEL SECURITY;
-- RLS policies for pokedex_entries (public read)
CREATE POLICY "Anyone can view pokemon entries" ON pokedex_entries
FOR SELECT USING (true);
-- RLS policies for catch_records (user-specific)
CREATE POLICY "Users can view own catch records" ON catch_records
FOR SELECT USING (auth.uid() = "userId");
CREATE POLICY "Users can insert own catch records" ON catch_records
FOR INSERT WITH CHECK (auth.uid() = "userId");
CREATE POLICY "Users can update own catch records" ON catch_records
FOR UPDATE USING (auth.uid() = "userId");
CREATE POLICY "Users can delete own catch records" ON catch_records
FOR DELETE USING (auth.uid() = "userId");
-- RLS policies for region_game_mappings (public read)
CREATE POLICY "Anyone can view region game mappings" ON region_game_mappings
FOR SELECT USING (true);
-- RLS policies for metadata (public read)
CREATE POLICY "Anyone can view metadata" ON metadata
FOR SELECT USING (true);
@@ -0,0 +1,130 @@
-- Migration: Create PostgreSQL schema for Pokemon data
-- This replaces the M-- Create indexes for better p$$ LANGUAGE plpgsql;
-- Create triggers for updated_at
CREATE TRIGGER update_pokedex_entries_updated_at
BEFORE UPDATE ON pokedex_entries
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_catch_records_updated_at
BEFORE UPDATE ON catch_records
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();ance
CREATE INDEX idx_pokedex_entries_pokedex_number ON pokedex_entries(pokedex_number);
CREATE INDEX idx_pokedex_entries_pokemon ON pokedex_entries(pokemon);
CREATE INDEX idx_pokedex_entries_box_placement_forms ON pokedex_entries(box_placement_forms_box, box_placement_forms_row, box_placement_forms_column);
CREATE INDEX idx_pokedex_entries_box_placement ON pokedex_entries(box_placement_box, box_placement_row, box_placement_column);
CREATE INDEX idx_catch_records_user_id ON catch_records("userId");
CREATE INDEX idx_catch_records_pokedex_entry_id ON catch_records("pokedexEntryId");
CREATE INDEX idx_catch_records_caught ON catch_records(caught);
CREATE INDEX idx_catch_records_in_home ON catch_records("inHome");
CREATE INDEX idx_catch_records_user_caught ON catch_records("userId", caught);lections with proper PostgreSQL tables
-- Note: Using individual columns instead of composite types for simplicity
-- Pokemon entries table (replaces pokedexentries MongoDB collection)
CREATE TABLE pokedex_entries (
id BIGSERIAL PRIMARY KEY,
pokedexNumber INTEGER NOT NULL,
pokemon TEXT NOT NULL,
form TEXT,
canGigantamax BOOLEAN DEFAULT FALSE,
regionToCatchIn TEXT,
gamesToCatchIn TEXT[], -- Array of games
regionToEvolveIn TEXT,
evolutionInformation TEXT,
catchInformation TEXT[], -- Array of catch info
-- Box placement for forms view
boxPlacementFormsBox INTEGER,
boxPlacementFormsRow INTEGER,
boxPlacementFormsColumn INTEGER,
-- Box placement for no-forms view
boxPlacementBox INTEGER,
boxPlacementRow INTEGER,
boxPlacementColumn INTEGER,
createdAt TIMESTAMPTZ DEFAULT NOW(),
updatedAt TIMESTAMPTZ DEFAULT NOW()
);
-- Catch records table (replaces catchrecords MongoDB collection)
CREATE TABLE catch_records (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
"userId" UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
"pokedexEntryId" BIGINT NOT NULL REFERENCES pokedex_entries(id) ON DELETE CASCADE,
-- Catch status fields
"haveToEvolve" BOOLEAN DEFAULT FALSE,
caught BOOLEAN DEFAULT FALSE,
"inHome" BOOLEAN DEFAULT FALSE,
"hasGigantamaxed" BOOLEAN DEFAULT FALSE,
"personalNotes" TEXT,
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
"updatedAt" TIMESTAMPTZ DEFAULT NOW(),
-- Ensure one record per user per pokemon entry
UNIQUE("userId", "pokedexEntryId")
);
-- Region/Game mappings table (replaces regiongamemappings MongoDB collection)
CREATE TABLE region_game_mappings (
id BIGSERIAL PRIMARY KEY,
region TEXT NOT NULL,
games TEXT[] NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Pokedex metadata table (replaces pokedexmetadata MongoDB collection)
CREATE TABLE pokedex_metadata (
id BIGSERIAL PRIMARY KEY,
key TEXT UNIQUE NOT NULL,
value JSONB NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Add unique constraint to prevent duplicate pokemon forms
ALTER TABLE pokedex_entries ADD CONSTRAINT unique_pokemon_form
UNIQUE(pokedex_number, form);
-- Enable Row Level Security (RLS) for user data isolation
ALTER TABLE catch_records ENABLE ROW LEVEL SECURITY;
-- RLS Policy: Users can only access their own catch records
CREATE POLICY "Users can only access their own catch records"
ON catch_records FOR ALL
USING (auth.uid() = userId)
WITH CHECK (auth.uid() = userId);
-- Create indexes for better performance
CREATE INDEX idx_pokedex_entries_pokedex_number ON pokedex_entries(pokedexNumber);
CREATE INDEX idx_pokedex_entries_pokemon ON pokedex_entries(pokemon);
CREATE INDEX idx_pokedex_entries_box_placement_forms ON pokedex_entries(boxPlacementFormsBox, boxPlacementFormsRow, boxPlacementFormsColumn);
CREATE INDEX idx_pokedex_entries_box_placement ON pokedex_entries(boxPlacementBox, boxPlacementRow, boxPlacementColumn);
CREATE INDEX idx_catch_records_user_id ON catch_records(userId);
CREATE INDEX idx_catch_records_pokedex_entry_id ON catch_records(pokedexEntryId);
CREATE INDEX idx_catch_records_caught ON catch_records(caught);
CREATE INDEX idx_catch_records_in_home ON catch_records(inHome);
-- Create updated_at trigger function
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = NOW();
RETURN NEW;
END;
$$ language 'plpgsql';
-- Add updated_at triggers
CREATE TRIGGER update_pokedex_entries_updated_at BEFORE UPDATE ON pokedex_entries
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_catch_records_updated_at BEFORE UPDATE ON catch_records
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_pokedex_metadata_updated_at BEFORE UPDATE ON pokedex_metadata
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
@@ -0,0 +1,133 @@
-- Migration: Create PostgreSQL schema for Pokemon data
-- This replaces the MongoDB collections with proper PostgreSQL tables
-- Note: Using individual columns instead of composite types for simplicity
-- Pokemon entries table (replaces pokedexentries MongoDB collection)
CREATE TABLE pokedex_entries (
id BIGSERIAL PRIMARY KEY,
"pokedexNumber" INTEGER NOT NULL,
pokemon TEXT NOT NULL,
form TEXT,
"canGigantamax" BOOLEAN DEFAULT FALSE,
"regionToCatchIn" TEXT,
"gamesToCatchIn" TEXT[], -- Array of games
"regionToEvolveIn" TEXT,
"evolutionInformation" TEXT,
"catchInformation" TEXT[], -- Array of catch info
-- Box placement for forms view
"boxPlacementFormsBox" INTEGER,
"boxPlacementFormsRow" INTEGER,
"boxPlacementFormsColumn" INTEGER,
-- Box placement for no-forms view
"boxPlacementBox" INTEGER,
"boxPlacementRow" INTEGER,
"boxPlacementColumn" INTEGER,
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
"updatedAt" TIMESTAMPTZ DEFAULT NOW()
);
-- Add unique constraint to prevent duplicate pokemon forms
ALTER TABLE pokedex_entries ADD CONSTRAINT unique_pokemon_form
UNIQUE("pokedexNumber", form);
-- Catch records table (replaces catchrecords MongoDB collection)
CREATE TABLE catch_records (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
"userId" UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
"pokedexEntryId" BIGINT NOT NULL REFERENCES pokedex_entries(id) ON DELETE CASCADE,
-- Catch status fields
"haveToEvolve" BOOLEAN DEFAULT FALSE,
caught BOOLEAN DEFAULT FALSE,
"inHome" BOOLEAN DEFAULT FALSE,
"hasGigantamaxed" BOOLEAN DEFAULT FALSE,
"personalNotes" TEXT,
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
"updatedAt" TIMESTAMPTZ DEFAULT NOW(),
-- Ensure one record per user per pokemon entry
UNIQUE("userId", "pokedexEntryId")
);
-- Region-game mappings table for filtering
CREATE TABLE region_game_mappings (
id BIGSERIAL PRIMARY KEY,
region TEXT NOT NULL,
game TEXT NOT NULL,
UNIQUE(region, game)
);
-- Metadata table for migration tracking
CREATE TABLE metadata (
id BIGSERIAL PRIMARY KEY,
key TEXT UNIQUE NOT NULL,
value TEXT,
"createdAt" TIMESTAMPTZ DEFAULT NOW(),
"updatedAt" TIMESTAMPTZ DEFAULT NOW()
);
-- Create indexes for better performance
CREATE INDEX idx_pokedex_entries_pokedex_number ON pokedex_entries("pokedexNumber");
CREATE INDEX idx_pokedex_entries_pokemon ON pokedex_entries(pokemon);
CREATE INDEX idx_pokedex_entries_box_placement_forms ON pokedex_entries("boxPlacementFormsBox", "boxPlacementFormsRow", "boxPlacementFormsColumn");
CREATE INDEX idx_pokedex_entries_box_placement ON pokedex_entries("boxPlacementBox", "boxPlacementRow", "boxPlacementColumn");
CREATE INDEX idx_catch_records_user_id ON catch_records("userId");
CREATE INDEX idx_catch_records_pokedex_entry_id ON catch_records("pokedexEntryId");
CREATE INDEX idx_catch_records_caught ON catch_records(caught);
CREATE INDEX idx_catch_records_in_home ON catch_records("inHome");
CREATE INDEX idx_catch_records_user_caught ON catch_records("userId", caught);
-- Function to automatically update updated_at timestamp
CREATE OR REPLACE FUNCTION update_updated_at_column()
RETURNS TRIGGER AS $$
BEGIN
NEW."updatedAt" = NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
-- Create triggers for updated_at
CREATE TRIGGER update_pokedex_entries_updated_at
BEFORE UPDATE ON pokedex_entries
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
CREATE TRIGGER update_catch_records_updated_at
BEFORE UPDATE ON catch_records
FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
-- Enable RLS on all tables
ALTER TABLE pokedex_entries ENABLE ROW LEVEL SECURITY;
ALTER TABLE catch_records ENABLE ROW LEVEL SECURITY;
ALTER TABLE region_game_mappings ENABLE ROW LEVEL SECURITY;
ALTER TABLE metadata ENABLE ROW LEVEL SECURITY;
-- RLS policies for pokedex_entries (public read)
CREATE POLICY "Anyone can view pokemon entries" ON pokedex_entries
FOR SELECT USING (true);
-- RLS policies for catch_records (user-specific)
CREATE POLICY "Users can view own catch records" ON catch_records
FOR SELECT USING (auth.uid() = "userId");
CREATE POLICY "Users can insert own catch records" ON catch_records
FOR INSERT WITH CHECK (auth.uid() = "userId");
CREATE POLICY "Users can update own catch records" ON catch_records
FOR UPDATE USING (auth.uid() = "userId");
CREATE POLICY "Users can delete own catch records" ON catch_records
FOR DELETE USING (auth.uid() = "userId");
-- RLS policies for region_game_mappings (public read)
CREATE POLICY "Anyone can view region game mappings" ON region_game_mappings
FOR SELECT USING (true);
-- RLS policies for metadata (public read)
CREATE POLICY "Anyone can view metadata" ON metadata
FOR SELECT USING (true);
@@ -1,54 +0,0 @@
-- Migration: Seed Pokemon data from TSV
-- This replaces the separate tsv-parser project and MongoDB seeding
-- Insert Pokemon data based on the TSV structure
-- Note: This is a sample of the data structure - you'll need to convert the full TSV
INSERT INTO pokedex_entries (
pokedex_number,
pokemon,
form,
can_gigantamax,
region_to_catch_in,
games_to_catch_in,
region_to_evolve_in,
evolution_information,
box_placement_forms_box,
box_placement_forms_row,
box_placement_forms_column,
box_placement_box,
box_placement_row,
box_placement_column
) VALUES
-- Sample data from the TSV (first few entries)
(1, 'Bulbasaur', NULL, FALSE, 'Kanto', ARRAY['Red','Blue','Yellow','LG: Pikachu','LG: Eevee'], NULL, NULL, 1, 1, 1, 1, 1, 1),
(2, 'Ivysaur', NULL, FALSE, 'Kanto', ARRAY['Red','Blue','Yellow','LG: Pikachu','LG: Eevee'], NULL, NULL, 1, 1, 2, 1, 1, 2),
(3, 'Venusaur', NULL, TRUE, 'Kanto', ARRAY['Red','Blue','Yellow','LG: Pikachu','LG: Eevee'], NULL, NULL, 1, 1, 3, 1, 1, 3),
(3, 'Venusaur', 'Female', FALSE, 'Kanto', ARRAY['Red','Blue','Yellow','LG: Pikachu','LG: Eevee'], NULL, NULL, 1, 1, 4, NULL, NULL, NULL),
(4, 'Charmander', NULL, FALSE, 'Kanto', ARRAY['Red','Blue','Yellow','LG: Pikachu','LG: Eevee'], NULL, NULL, 1, 1, 5, 1, 1, 4),
(5, 'Charmeleon', NULL, FALSE, 'Kanto', ARRAY['Red','Blue','Yellow','LG: Pikachu','LG: Eevee'], NULL, NULL, 1, 1, 6, 1, 1, 5),
(6, 'Charizard', NULL, TRUE, 'Kanto', ARRAY['Red','Blue','Yellow','LG: Pikachu','LG: Eevee'], NULL, NULL, 1, 2, 1, 1, 1, 6),
(7, 'Squirtle', NULL, FALSE, 'Kanto', ARRAY['Red','Blue','Yellow','LG: Pikachu','LG: Eevee'], NULL, NULL, 1, 2, 2, 1, 2, 1),
(8, 'Wartortle', NULL, FALSE, 'Kanto', ARRAY['Red','Blue','Yellow','LG: Pikachu','LG: Eevee'], NULL, NULL, 1, 2, 3, 1, 2, 2);
-- Insert region game mappings
INSERT INTO region_game_mappings (region, games) VALUES
('Kanto', ARRAY['Red', 'Blue', 'Yellow', 'LG: Pikachu', 'LG: Eevee']),
('Johto', ARRAY['Gold', 'Silver', 'Crystal', 'HeartGold', 'SoulSilver']),
('Hoenn', ARRAY['Ruby', 'Sapphire', 'Emerald', 'Omega Ruby', 'Alpha Sapphire']),
('Sinnoh', ARRAY['Diamond', 'Pearl', 'Platinum', 'Brilliant Diamond', 'Shining Pearl']),
('Unova', ARRAY['Black', 'White', 'Black 2', 'White 2']),
('Kalos', ARRAY['X', 'Y']),
('Alola', ARRAY['Sun', 'Moon', 'Ultra Sun', 'Ultra Moon']),
('Galar', ARRAY['Sword', 'Shield']),
('Paldea', ARRAY['Scarlet', 'Violet']);
-- Insert some metadata
INSERT INTO pokedex_metadata (key, value) VALUES
('total_pokemon', '{"count": 1025}'),
('last_updated', '{"timestamp": "2025-01-26T00:00:00Z"}'),
('supported_generations', '{"generations": [1,2,3,4,5,6,7,8,9]}');
-- Note: This is a sample seed. For the full migration, we'll need to:
-- 1. Convert the entire TSV file to SQL inserts
-- 2. Or create a function to import from the TSV data directly
@@ -7,20 +7,20 @@ DELETE FROM pokedex_entries;
-- Insert full Pokemon dataset
INSERT INTO pokedex_entries (
pokedex_number,
"pokedexNumber",
pokemon,
form,
can_gigantamax,
region_to_catch_in,
games_to_catch_in,
region_to_evolve_in,
evolution_information,
box_placement_forms_box,
box_placement_forms_row,
box_placement_forms_column,
box_placement_box,
box_placement_row,
box_placement_column
"canGigantamax",
"regionToCatchIn",
"gamesToCatchIn",
"regionToEvolveIn",
"evolutionInformation",
"boxPlacementFormsBox",
"boxPlacementFormsRow",
"boxPlacementFormsColumn",
"boxPlacementBox",
"boxPlacementRow",
"boxPlacementColumn"
) VALUES
(1, 'Bulbasaur', NULL, false, 'Kanto', ARRAY['Red', 'Blue', 'Yellow', 'LG: Pikachu', 'LG: Eevee'], NULL, NULL, 1, 1, 1, 1, 1, 1),
(2, 'Ivysaur', NULL, false, 'Kanto', ARRAY['Red', 'Blue', 'Yellow', 'LG: Pikachu', 'LG: Eevee'], NULL, NULL, 1, 1, 2, 1, 1, 2),
@@ -344,7 +344,8 @@ INSERT INTO pokedex_entries (
(209, 'Snubbull', NULL, false, 'Johto', ARRAY['Gold', 'Silver', 'Crystal', 'HG', 'SS'], NULL, NULL, 12, 2, 6, 7, 5, 5),
(210, 'Granbull', NULL, false, 'Johto', ARRAY['Gold', 'Silver', 'Crystal', 'HG', 'SS'], NULL, NULL, 12, 3, 1, 7, 5, 6),
(211, 'Qwilfish', NULL, false, 'Johto', ARRAY['Gold', 'Silver', 'Crystal', 'HG', 'SS'], NULL, 'Route 32, Super Rod', 12, 3, 2, 8, 1, 1),
(211, 'Qwilfish', 'Hisuian', false, 'Hisui', ARRAY['PLA'], NULL, 'Obsidian Fieldlands: near Ramanas Island (Hisuian Form)
(211, 'Qwilfish', 'Hisuian', false, 'Hisui', ARRAY['PLA'], NULL, 'Obsidian Fieldlands: near Ramanas Island (Hisuian Form)
Cobalt Coastlands: near Bathers'' Lagoon, near Hideaway Bay, near Tombolo Walk, near Sand''s Reach, Tranquility Cove, Islespy Shore and nearby (additional Alpha icon.png), Lunker''s Lair, near Seagrass Haven, near Firespit Island, massive mass outbreaks (Hisuian Form)', 12, 3, 3, null, null, null),
(212, 'Scizor', NULL, false, 'Kanto', ARRAY['Red', 'Yellow', 'LG: Pikachu'], 'Johto', 'It evolves from Scyther when traded while holding a Metal Coat.', 12, 3, 4, 8, 1, 2),
(212, 'Scizor', 'Female', false, 'Kanto', ARRAY['Red', 'Yellow', 'LG: Pikachu'], 'Johto', 'It evolves from Scyther when traded while holding a Metal Coat.', 12, 3, 5, null, null, null),
(213, 'Shuckle', NULL, false, 'Johto', ARRAY['Gold', 'Silver', 'Crystal', 'HG', 'SS'], NULL, NULL, 12, 3, 6, 8, 1, 3),
@@ -352,8 +353,10 @@ INSERT INTO pokedex_entries (
(214, 'Heracross', 'Female', false, 'Johto', ARRAY['Gold', 'Silver', 'Crystal', 'HG', 'SS'], NULL, NULL, 12, 4, 2, null, null, null),
(215, 'Sneasel', NULL, false, 'Johto', ARRAY['Gold', 'Silver', 'Crystal', 'HG', 'SS'], NULL, 'Ice Path, b3f, 6pm-4am', 12, 4, 3, 8, 1, 5),
(215, 'Sneasel', 'Female', false, 'Johto', ARRAY['Gold', 'Silver', 'Crystal', 'HG', 'SS'], NULL, 'Ice Path, b3f, 6pm-4am', 12, 4, 4, null, null, null),
(215, 'Sneasel', 'Female', false, 'Johto', ARRAY['Gold', 'Silver', 'Crystal', 'HG', 'SS'], NULL, 'Ice Path, b3f, 6pm-4am', 12, 4, 4, null, null, null),
(215, 'Sneasel', 'Hisuian', false, 'Hisui', ARRAY['PLA'], NULL, 'Coronet Highlands: near Celestica Trail, near Primeval Grotto, massive mass outbreaks (Hisuian Form)
(215, 'Sneasel', 'Hisuian', false, 'Hisui', ARRAY['PLA'], NULL, 'Coronet Highlands: near Celestica Trail, near Primeval Grotto, massive mass outbreaks (Hisuian Form)
Alabaster Icelands: near Avalugg''s Legacy (additional Alpha icon.png), Glacier Terrace, near Pearl Settlement (Hisuian Form)', 12, 4, 5, null, null, null),
(215, 'Sneasel', 'Female-Hisuian', false, 'Hisui', ARRAY['PLA'], NULL, 'Coronet Highlands: near Celestica Trail, near Primeval Grotto, massive mass outbreaks (Hisuian Form)
Alabaster Icelands: near Avalugg''s Legacy (additional Alpha icon.png), Glacier Terrace, near Pearl Settlement (Hisuian Form)', 12, 4, 6, null, null, null),
(216, 'Teddiursa', NULL, false, 'Johto', ARRAY['Gold', 'Crystal', 'SS'], NULL, 'Dark Cave, Blackthorn City Entrance, 4am-10am', 12, 5, 1, 8, 1, 6),
(217, 'Ursaring', NULL, false, 'Johto', ARRAY['Gold', 'Crystal', 'SS'], NULL, NULL, 12, 5, 2, 8, 2, 1),
(217, 'Ursaring', 'Female', false, 'Johto', ARRAY['Gold', 'Crystal', 'SS'], NULL, NULL, 12, 5, 3, null, null, null),
@@ -765,7 +768,9 @@ INSERT INTO pokedex_entries (
(549, 'Lilligant', 'Hisuian', false, 'Unova', ARRAY['White', 'White2'], 'Hisui', 'In Hisui, Petilil evolves into Hisuian Lilligant when exposed to a Sun Stone.', 27, 5, 5, null, null, null),
(550, 'Basculin', 'Red-striped', false, 'Unova', ARRAY['Black', 'White', 'Black2', 'White2'], NULL, 'Routes 1, 3, 6, 11, 14, Striaton City, Wellspring Cave, Pinwheel Forest, Dragonspiral Tower, Challenger''s Cave, Victory Road, Village Bridge, Giant Chasm, Abundant Shrine, Lostlorn Forest (Surfing or fishing) (Red-Striped Form) (Rippling water) (Blue-Striped Form)', 27, 5, 6, 19, 2, 4),
(550, 'Basculin', 'Blue-striped', false, 'Unova', ARRAY['Black', 'White', 'Black2', 'White2'], NULL, 'Routes 1, 3, 6, 11, 14, Striaton City, Wellspring Cave, Pinwheel Forest, Dragonspiral Tower, Challenger''s Cave, Victory Road, Village Bridge, Giant Chasm, Abundant Shrine, Lostlorn Forest (Surfing or fishing) (Red-Striped Form) (Rippling water) (Blue-Striped Form)', 28, 1, 1, null, null, null),
(549, 'Lilligant', 'Hisuian', false, 'Unova', ARRAY['White', 'White2'], 'Hisui', 'In Hisui, Petilil evolves into Hisuian Lilligant when exposed to a Sun Stone.', 27, 5, 5, null, null, null),
(550, 'Basculin', 'White-striped', false, 'Hisui', ARRAY['PLA'], NULL, 'Cobalt Coastlands: Tranquility Cove, near Islespy Shore, near Firespit Island, massive mass outbreaks (White-Striped Form)
Coronet Highlands: Fabled Spring (White-Striped Form)
Alabaster Icelands: near Avalugg''s Legacy, Heart''s Crag, Lake Acuity, near Pearl Settlement (White-Striped Form)', 28, 1, 2, null, null, null),
(551, 'Sandile', NULL, false, 'Unova', ARRAY['Black', 'White', 'Black2', 'White2'], NULL, 'Route 4, Desert Resort, Relic Castle', 28, 1, 3, 19, 2, 5),
(552, 'Krokorok', NULL, false, 'Unova', ARRAY['Black', 'White', 'Black2', 'White2'], NULL, 'Evolves from Sandile at level 29', 28, 1, 4, 19, 2, 6),
(553, 'Krookodile', NULL, false, 'Unova', ARRAY['Black', 'White', 'Black2', 'White2'], NULL, 'Evolves from Krokorok at level 40', 28, 1, 5, 19, 3, 1),
@@ -1414,9 +1419,51 @@ INSERT INTO pokedex_entries (
(1025, 'Pecharunt', NULL, false, 'Paldea', ARRAY['Scarlet', 'Violet'], NULL, NULL, 51, 2, 6, 35, 1, 4);
-- Update metadata
(1023, 'Iron Crown', NULL, false, 'Paldea', ARRAY['Violet'], NULL, NULL, 51, 2, 4, 35, 1, 2),
(1024, 'Terapagos', NULL, false, 'Paldea', ARRAY['Scarlet', 'Violet'], NULL, NULL, 51, 2, 5, 35, 1, 3),
UPDATE metadata
SET value = '{"count": 1390}', "updatedAt" = NOW()
WHERE key = 'total_pokemon';
-- Insert region-game mappings if not already present
INSERT INTO region_game_mappings (region, game) VALUES
('Kanto', 'Red'),
('Kanto', 'Blue'),
('Kanto', 'Yellow'),
('Kanto', 'LG: Pikachu'),
('Kanto', 'LG: Eevee'),
('Johto', 'Gold'),
('Johto', 'Silver'),
('Johto', 'Crystal'),
('Hoenn', 'Ruby'),
('Hoenn', 'Sapphire'),
('Hoenn', 'Emerald'),
('Sinnoh', 'Diamond'),
('Sinnoh', 'Pearl'),
('Sinnoh', 'Platinum'),
('Unova', 'Black'),
('Unova', 'White'),
('Unova', 'Black 2'),
('Unova', 'White 2'),
('Kalos', 'X'),
('Kalos', 'Y'),
('Alola', 'Sun'),
('Alola', 'Moon'),
('Alola', 'Ultra Sun'),
('Alola', 'Ultra Moon'),
('Galar', 'Sword'),
('Galar', 'Shield'),
('Paldea', 'Scarlet'),
('Paldea', 'Violet')
ON CONFLICT (region, game) DO NOTHING;
-- Insert metadata
INSERT INTO metadata (key, value) VALUES
('migration_version', '1.0'),
('data_source', 'tsv-parser'),
('last_updated', NOW()::TEXT),
('total_pokemon', '{"count": 1390}')
ON CONFLICT (key) DO UPDATE SET
value = EXCLUDED.value,
"updatedAt" = NOW();
-- Add success message
SELECT 'Successfully loaded 1390 Pokemon entries' as message;
-14
View File
@@ -1,14 +0,0 @@
-- Initial seed data for local development
-- This file is referenced in config.toml and will be loaded during db reset
-- Note: RLS is already enabled on auth.users by default in Supabase
-- No need to modify system tables here
-- Add any application-specific seed data here
-- For now, this file is minimal since we use MongoDB for app data
-- Example: If we had a profiles table, we could seed it here
-- INSERT INTO profiles (id, username) VALUES
-- ('test-user-id', 'testuser');
SELECT 'Local Supabase setup complete' as message;