deckhearth/scripts/setup-database.sql
Randall Stillwell 4fea3d287e Add Neon database integration and migration scripts
- Install @neondatabase/serverless, @vercel/blob, @stackframe/stack
- Add database schema setup script (scripts/setup-database.sql)
- Add JSON to Neon migration script (scripts/migrate-json-to-neon.ts)
- Prepare for user collections, decks, and authentication
- Ready for Neon database population with existing card data
2025-07-21 15:06:43 -05:00

136 lines
No EOL
4.8 KiB
SQL

-- TCG Vault Database Schema for Neon
-- Run this script to set up your database tables
-- Enable UUID extension
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
-- Cards table (migrate from JSON)
CREATE TABLE IF NOT EXISTS cards (
id SERIAL PRIMARY KEY,
name VARCHAR(255) NOT NULL,
set_name VARCHAR(255),
set_code VARCHAR(50),
card_number VARCHAR(50),
rarity VARCHAR(100),
game VARCHAR(50) NOT NULL,
mana_cost VARCHAR(50),
cmc INTEGER,
card_type VARCHAR(100),
colors JSONB,
oracle_text TEXT,
flavor_text TEXT,
power VARCHAR(50),
toughness VARCHAR(50),
loyalty VARCHAR(50),
artist VARCHAR(255),
image_url VARCHAR(500),
stock_image_url VARCHAR(500),
artwork_crop_coords JSONB,
current_price DECIMAL(10,2),
market_price DECIMAL(10,2),
low_price DECIMAL(10,2),
high_price DECIMAL(10,2),
price_last_updated TIMESTAMP,
ocr_confidence DECIMAL(5,2),
ocr_raw_text TEXT,
scryfall_id VARCHAR(100),
tcg_player_id VARCHAR(100),
verified BOOLEAN DEFAULT true,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- User collections
CREATE TABLE IF NOT EXISTS user_collections (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id VARCHAR(255) NOT NULL, -- Stack Auth user ID
name VARCHAR(255) NOT NULL,
description TEXT,
is_public BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Collection cards (many-to-many relationship)
CREATE TABLE IF NOT EXISTS collection_cards (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
collection_id UUID REFERENCES user_collections(id) ON DELETE CASCADE,
card_id INTEGER REFERENCES cards(id),
quantity INTEGER DEFAULT 1,
condition VARCHAR(50) DEFAULT 'near-mint',
notes TEXT,
user_images JSONB, -- Array of Vercel Blob URLs
purchase_price DECIMAL(10,2),
purchase_date DATE,
added_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- User decks
CREATE TABLE IF NOT EXISTS user_decks (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id VARCHAR(255) NOT NULL, -- Stack Auth user ID
name VARCHAR(255) NOT NULL,
description TEXT,
game VARCHAR(50) NOT NULL,
format VARCHAR(100), -- Standard, Modern, Commander, etc.
is_public BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Deck cards (many-to-many relationship)
CREATE TABLE IF NOT EXISTS deck_cards (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
deck_id UUID REFERENCES user_decks(id) ON DELETE CASCADE,
card_id INTEGER REFERENCES cards(id),
quantity INTEGER DEFAULT 1,
is_commander BOOLEAN DEFAULT false,
is_sideboard BOOLEAN DEFAULT false,
added_at TIMESTAMP DEFAULT NOW()
);
-- User preferences and settings
CREATE TABLE IF NOT EXISTS user_preferences (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
user_id VARCHAR(255) UNIQUE NOT NULL, -- Stack Auth user ID
default_view VARCHAR(50) DEFAULT 'card',
items_per_page INTEGER DEFAULT 20,
enable_animations BOOLEAN DEFAULT true,
enable_ocr BOOLEAN DEFAULT true,
theme VARCHAR(50) DEFAULT 'light',
privacy_settings JSONB DEFAULT '{"collections_public": false, "decks_public": false}',
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Shared collections (for sharing with friends)
CREATE TABLE IF NOT EXISTS collection_shares (
id UUID PRIMARY KEY DEFAULT uuid_generate_v4(),
collection_id UUID REFERENCES user_collections(id) ON DELETE CASCADE,
shared_with_user_id VARCHAR(255) NOT NULL, -- Stack Auth user ID
permission_level VARCHAR(50) DEFAULT 'view', -- view, edit
shared_by_user_id VARCHAR(255) NOT NULL,
shared_at TIMESTAMP DEFAULT NOW()
);
-- Create indexes for better performance
CREATE INDEX IF NOT EXISTS idx_cards_name ON cards(name);
CREATE INDEX IF NOT EXISTS idx_cards_game ON cards(game);
CREATE INDEX IF NOT EXISTS idx_cards_set_name ON cards(set_name);
CREATE INDEX IF NOT EXISTS idx_cards_rarity ON cards(rarity);
CREATE INDEX IF NOT EXISTS idx_user_collections_user_id ON user_collections(user_id);
CREATE INDEX IF NOT EXISTS idx_collection_cards_collection_id ON collection_cards(collection_id);
CREATE INDEX IF NOT EXISTS idx_collection_cards_card_id ON collection_cards(card_id);
CREATE INDEX IF NOT EXISTS idx_user_decks_user_id ON user_decks(user_id);
CREATE INDEX IF NOT EXISTS idx_deck_cards_deck_id ON deck_cards(deck_id);
CREATE INDEX IF NOT EXISTS idx_deck_cards_card_id ON deck_cards(card_id);
CREATE INDEX IF NOT EXISTS idx_user_preferences_user_id ON user_preferences(user_id);
CREATE INDEX IF NOT EXISTS idx_collection_shares_collection_id ON collection_shares(collection_id);
CREATE INDEX IF NOT EXISTS idx_collection_shares_shared_with_user_id ON collection_shares(shared_with_user_id);
-- Insert some sample data (migrate from your current JSON)
-- This will be handled by a separate migration script