diff --git a/pages/api/setup-database.js b/pages/api/setup-database.js new file mode 100644 index 0000000..c5af2bb --- /dev/null +++ b/pages/api/setup-database.js @@ -0,0 +1,150 @@ +import { sql } from '@vercel/postgres'; + +export default async function handler(req, res) { + // Set CORS headers + res.setHeader('Access-Control-Allow-Origin', '*'); + res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); + res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); + + // Handle preflight requests + if (req.method === 'OPTIONS') { + res.status(200).end(); + return; + } + + if (req.method !== 'POST') { + return res.status(405).json({ error: 'Method not allowed' }); + } + + try { + // Create users table + await sql` + CREATE TABLE IF NOT EXISTS users ( + id SERIAL PRIMARY KEY, + email VARCHAR(255) UNIQUE NOT NULL, + password VARCHAR(255) NOT NULL, + role VARCHAR(50) DEFAULT 'user', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + `; + + // Create cards table + await sql` + 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(50), + game VARCHAR(50) NOT NULL, + mana_cost VARCHAR(50), + cmc INTEGER, + card_type VARCHAR(255), + colors JSONB, + oracle_text TEXT, + power VARCHAR(10), + toughness VARCHAR(10), + image_url TEXT, + stock_image_url TEXT, + current_price DECIMAL(10,2), + market_price DECIMAL(10,2), + scryfall_id VARCHAR(255) UNIQUE, + verified BOOLEAN DEFAULT false, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + `; + + // Create user_cards table (collections) + await sql` + CREATE TABLE IF NOT EXISTS user_cards ( + id SERIAL PRIMARY KEY, + user_id INTEGER REFERENCES users(id) ON DELETE CASCADE, + card_id INTEGER REFERENCES cards(id) ON DELETE CASCADE, + quantity INTEGER DEFAULT 1, + condition VARCHAR(50) DEFAULT 'NM', + is_foil BOOLEAN DEFAULT false, + notes TEXT, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(user_id, card_id, is_foil) + ) + `; + + // Create collections table + await sql` + CREATE TABLE IF NOT EXISTS collections ( + id SERIAL PRIMARY KEY, + user_id INTEGER REFERENCES users(id) ON DELETE CASCADE, + name VARCHAR(255) NOT NULL, + description TEXT, + is_public BOOLEAN DEFAULT false, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + `; + + // Create collection_cards table + await sql` + CREATE TABLE IF NOT EXISTS collection_cards ( + id SERIAL PRIMARY KEY, + collection_id INTEGER REFERENCES collections(id) ON DELETE CASCADE, + card_id INTEGER REFERENCES cards(id) ON DELETE CASCADE, + quantity INTEGER DEFAULT 1, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(collection_id, card_id) + ) + `; + + // Create decks table + await sql` + CREATE TABLE IF NOT EXISTS decks ( + id SERIAL PRIMARY KEY, + user_id INTEGER REFERENCES users(id) ON DELETE CASCADE, + name VARCHAR(255) NOT NULL, + description TEXT, + game VARCHAR(50), + is_public BOOLEAN DEFAULT false, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP + ) + `; + + // Create deck_cards table + await sql` + CREATE TABLE IF NOT EXISTS deck_cards ( + id SERIAL PRIMARY KEY, + deck_id INTEGER REFERENCES decks(id) ON DELETE CASCADE, + card_id INTEGER REFERENCES cards(id) ON DELETE CASCADE, + quantity INTEGER DEFAULT 1, + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + UNIQUE(deck_id, card_id) + ) + `; + + // Create a default admin user + const bcrypt = require('bcryptjs'); + const hashedPassword = await bcrypt.hash('admin123', 12); + + await sql` + INSERT INTO users (email, password, role) + VALUES ('admin@tcgvault.com', ${hashedPassword}, 'admin') + ON CONFLICT (email) DO NOTHING + `; + + res.status(200).json({ + success: true, + message: 'Database setup completed successfully!', + tables: ['users', 'cards', 'user_cards', 'collections', 'collection_cards', 'decks', 'deck_cards'] + }); + + } catch (error) { + console.error('Database setup error:', error); + res.status(500).json({ + error: 'Database setup failed', + details: error.message + }); + } +} \ No newline at end of file