-- Tom's Java Jive - MySQL Database Schema -- Version: 1.0 -- Compatible with MySQL 8.0+ SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; SET AUTOCOMMIT = 0; START TRANSACTION; SET time_zone = "+00:00"; -- -------------------------------------------------------- -- Database Schema for Tom's Java Jive -- NOTE: Database must already exist in cPanel -- Select your database in phpMyAdmin before importing -- -------------------------------------------------------- -- -------------------------------------------------------- -- Table: settings -- -------------------------------------------------------- CREATE TABLE `settings` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `setting_key` VARCHAR(100) NOT NULL UNIQUE, `setting_value` JSON, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: admin_users -- -------------------------------------------------------- CREATE TABLE `admin_users` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `user_id` VARCHAR(50) NOT NULL UNIQUE, `email` VARCHAR(255) NOT NULL UNIQUE, `password_hash` VARCHAR(255) DEFAULT NULL, `name` VARCHAR(255) DEFAULT NULL, `picture` VARCHAR(500) DEFAULT NULL, `is_admin` TINYINT(1) DEFAULT 1, `is_master` TINYINT(1) DEFAULT 0, `permissions` JSON DEFAULT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `last_login` TIMESTAMP NULL, INDEX `idx_email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: customers -- -------------------------------------------------------- CREATE TABLE `customers` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `customer_id` VARCHAR(50) NOT NULL UNIQUE, `email` VARCHAR(255) NOT NULL UNIQUE, `password_hash` VARCHAR(255) DEFAULT NULL, `name` VARCHAR(255) DEFAULT NULL, `phone` VARCHAR(50) DEFAULT NULL, `shipping_address` JSON DEFAULT NULL, `billing_address` JSON DEFAULT NULL, `wallet_balance` DECIMAL(10,2) DEFAULT 0.00, `reward_points` INT DEFAULT 0, `is_guest` TINYINT(1) DEFAULT 0, `created_via` VARCHAR(50) DEFAULT 'web', `email_verified` TINYINT(1) DEFAULT 0, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_email` (`email`), INDEX `idx_customer_id` (`customer_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: products -- -------------------------------------------------------- CREATE TABLE `products` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `product_id` VARCHAR(50) NOT NULL UNIQUE, `name` VARCHAR(255) NOT NULL, `description` TEXT, `price` DECIMAL(10,2) NOT NULL, `sale_price` DECIMAL(10,2) DEFAULT NULL, `cost_price` DECIMAL(10,2) DEFAULT NULL, `sku` VARCHAR(100) DEFAULT NULL, `barcode` VARCHAR(100) DEFAULT NULL, `category` VARCHAR(100) DEFAULT NULL, `tags` JSON DEFAULT NULL, `images` JSON DEFAULT NULL, `stock` INT DEFAULT 0, `low_stock_threshold` INT DEFAULT 10, `weight` DECIMAL(10,2) DEFAULT NULL, `dimensions` JSON DEFAULT NULL, `is_active` TINYINT(1) DEFAULT 1, `is_featured` TINYINT(1) DEFAULT 0, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_product_id` (`product_id`), INDEX `idx_category` (`category`), INDEX `idx_is_active` (`is_active`), FULLTEXT INDEX `idx_search` (`name`, `description`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: orders -- -------------------------------------------------------- CREATE TABLE `orders` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `order_id` VARCHAR(50) NOT NULL UNIQUE, `order_number` VARCHAR(20) NOT NULL UNIQUE, `customer_id` VARCHAR(50) DEFAULT NULL, `customer_email` VARCHAR(255) NOT NULL, `customer_name` VARCHAR(255) DEFAULT NULL, `customer_phone` VARCHAR(50) DEFAULT NULL, `items` JSON NOT NULL, `subtotal` DECIMAL(10,2) NOT NULL, `shipping_cost` DECIMAL(10,2) DEFAULT 0.00, `tax` DECIMAL(10,2) DEFAULT 0.00, `discount` DECIMAL(10,2) DEFAULT 0.00, `gift_card_discount` DECIMAL(10,2) DEFAULT 0.00, `wallet_amount_used` DECIMAL(10,2) DEFAULT 0.00, `total` DECIMAL(10,2) NOT NULL, `shipping_address` JSON DEFAULT NULL, `billing_address` JSON DEFAULT NULL, `shipping_method` VARCHAR(50) DEFAULT NULL, `payment_method` VARCHAR(50) DEFAULT NULL, `payment_status` ENUM('pending', 'paid', 'failed', 'refunded', 'partially_refunded') DEFAULT 'pending', `order_status` ENUM('pending', 'confirmed', 'processing', 'shipped', 'delivered', 'cancelled', 'refunded') DEFAULT 'pending', `stripe_session_id` VARCHAR(255) DEFAULT NULL, `stripe_payment_intent` VARCHAR(255) DEFAULT NULL, `tracking_number` VARCHAR(100) DEFAULT NULL, `tracking_url` VARCHAR(500) DEFAULT NULL, `notes` TEXT DEFAULT NULL, `is_pos_order` TINYINT(1) DEFAULT 0, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_order_id` (`order_id`), INDEX `idx_customer_id` (`customer_id`), INDEX `idx_customer_email` (`customer_email`), INDEX `idx_order_status` (`order_status`), INDEX `idx_payment_status` (`payment_status`), INDEX `idx_created_at` (`created_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: order_items (normalized for reporting) -- -------------------------------------------------------- CREATE TABLE `order_items` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `order_id` VARCHAR(50) NOT NULL, `product_id` VARCHAR(50) NOT NULL, `name` VARCHAR(255) NOT NULL, `price` DECIMAL(10,2) NOT NULL, `quantity` INT NOT NULL, `total` DECIMAL(10,2) NOT NULL, INDEX `idx_order_id` (`order_id`), INDEX `idx_product_id` (`product_id`), FOREIGN KEY (`order_id`) REFERENCES `orders`(`order_id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: gift_cards -- -------------------------------------------------------- CREATE TABLE `gift_cards` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `gift_card_id` VARCHAR(50) NOT NULL UNIQUE, `code` VARCHAR(20) NOT NULL UNIQUE, `initial_balance` DECIMAL(10,2) NOT NULL, `current_balance` DECIMAL(10,2) NOT NULL, `purchaser_email` VARCHAR(255) DEFAULT NULL, `recipient_email` VARCHAR(255) DEFAULT NULL, `recipient_name` VARCHAR(255) DEFAULT NULL, `message` TEXT DEFAULT NULL, `is_active` TINYINT(1) DEFAULT 1, `expires_at` TIMESTAMP NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_code` (`code`), INDEX `idx_is_active` (`is_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: gift_card_transactions -- -------------------------------------------------------- CREATE TABLE `gift_card_transactions` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `gift_card_id` VARCHAR(50) NOT NULL, `order_id` VARCHAR(50) DEFAULT NULL, `amount` DECIMAL(10,2) NOT NULL, `balance_after` DECIMAL(10,2) NOT NULL, `type` ENUM('purchase', 'redemption', 'refund') NOT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_gift_card_id` (`gift_card_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: wallet_transactions -- -------------------------------------------------------- CREATE TABLE `wallet_transactions` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `transaction_id` VARCHAR(50) NOT NULL UNIQUE, `customer_id` VARCHAR(50) NOT NULL, `amount` DECIMAL(10,2) NOT NULL, `balance_after` DECIMAL(10,2) NOT NULL, `type` ENUM('deposit', 'withdrawal', 'purchase', 'refund', 'reward') NOT NULL, `description` VARCHAR(255) DEFAULT NULL, `order_id` VARCHAR(50) DEFAULT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_customer_id` (`customer_id`), INDEX `idx_type` (`type`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: reviews -- -------------------------------------------------------- CREATE TABLE `reviews` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `review_id` VARCHAR(50) NOT NULL UNIQUE, `product_id` VARCHAR(50) NOT NULL, `customer_id` VARCHAR(50) DEFAULT NULL, `customer_name` VARCHAR(255) NOT NULL, `customer_email` VARCHAR(255) NOT NULL, `rating` INT NOT NULL CHECK (rating >= 1 AND rating <= 5), `title` VARCHAR(255) DEFAULT NULL, `comment` TEXT, `is_verified_purchase` TINYINT(1) DEFAULT 0, `is_approved` TINYINT(1) DEFAULT 0, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_product_id` (`product_id`), INDEX `idx_is_approved` (`is_approved`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: email_campaigns -- -------------------------------------------------------- CREATE TABLE `email_campaigns` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `campaign_id` VARCHAR(50) NOT NULL UNIQUE, `name` VARCHAR(255) NOT NULL, `subject` VARCHAR(255) NOT NULL, `content` TEXT NOT NULL, `recipient_type` ENUM('all', 'customers_only', 'subscribers_only') DEFAULT 'all', `status` ENUM('draft', 'scheduled', 'sent', 'cancelled') DEFAULT 'draft', `scheduled_at` TIMESTAMP NULL, `sent_at` TIMESTAMP NULL, `recipients_count` INT DEFAULT 0, `opened_count` INT DEFAULT 0, `clicked_count` INT DEFAULT 0, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_status` (`status`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: email_subscribers -- -------------------------------------------------------- CREATE TABLE `email_subscribers` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `email` VARCHAR(255) NOT NULL UNIQUE, `name` VARCHAR(255) DEFAULT NULL, `is_active` TINYINT(1) DEFAULT 1, `source` VARCHAR(50) DEFAULT 'website', `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_is_active` (`is_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: abandoned_carts -- -------------------------------------------------------- CREATE TABLE `abandoned_carts` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `cart_id` VARCHAR(50) NOT NULL UNIQUE, `customer_id` VARCHAR(50) DEFAULT NULL, `customer_email` VARCHAR(255) DEFAULT NULL, `items` JSON NOT NULL, `subtotal` DECIMAL(10,2) NOT NULL, `recovery_email_sent` TINYINT(1) DEFAULT 0, `recovered` TINYINT(1) DEFAULT 0, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_customer_email` (`customer_email`), INDEX `idx_recovered` (`recovered`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: referrals -- -------------------------------------------------------- CREATE TABLE `referrals` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `referral_id` VARCHAR(50) NOT NULL UNIQUE, `referrer_customer_id` VARCHAR(50) NOT NULL, `referral_code` VARCHAR(20) NOT NULL UNIQUE, `referred_customer_id` VARCHAR(50) DEFAULT NULL, `referred_email` VARCHAR(255) DEFAULT NULL, `status` ENUM('pending', 'completed', 'expired') DEFAULT 'pending', `reward_amount` DECIMAL(10,2) DEFAULT 5.00, `reward_given` TINYINT(1) DEFAULT 0, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_referral_code` (`referral_code`), INDEX `idx_referrer` (`referrer_customer_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: visitor_sessions -- -------------------------------------------------------- CREATE TABLE `visitor_sessions` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `session_id` VARCHAR(100) NOT NULL UNIQUE, `visitor_id` VARCHAR(50) NOT NULL, `ip_address` VARCHAR(45) DEFAULT NULL, `user_agent` TEXT DEFAULT NULL, `current_page` VARCHAR(500) DEFAULT NULL, `referrer` VARCHAR(500) DEFAULT NULL, `country` VARCHAR(100) DEFAULT NULL, `city` VARCHAR(100) DEFAULT NULL, `is_active` TINYINT(1) DEFAULT 1, `page_views` INT DEFAULT 1, `started_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `last_activity` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_is_active` (`is_active`), INDEX `idx_last_activity` (`last_activity`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: categories -- -------------------------------------------------------- CREATE TABLE `categories` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `category_id` VARCHAR(50) NOT NULL UNIQUE, `name` VARCHAR(255) NOT NULL, `slug` VARCHAR(255) NOT NULL UNIQUE, `description` TEXT DEFAULT NULL, `image` VARCHAR(500) DEFAULT NULL, `parent_id` VARCHAR(50) DEFAULT NULL, `sort_order` INT DEFAULT 0, `is_active` TINYINT(1) DEFAULT 1, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX `idx_slug` (`slug`), INDEX `idx_is_active` (`is_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: coupons -- -------------------------------------------------------- CREATE TABLE `coupons` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `coupon_id` VARCHAR(50) NOT NULL UNIQUE, `code` VARCHAR(50) NOT NULL UNIQUE, `discount_type` ENUM('percentage', 'fixed') NOT NULL DEFAULT 'percentage', `discount_value` DECIMAL(10,2) NOT NULL, `min_order_amount` DECIMAL(10,2) DEFAULT NULL, `max_uses` INT DEFAULT NULL, `times_used` INT DEFAULT 0, `is_active` TINYINT(1) DEFAULT 1, `starts_at` TIMESTAMP NULL, `expires_at` TIMESTAMP NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_code` (`code`), INDEX `idx_is_active` (`is_active`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: password_reset_tokens -- -------------------------------------------------------- CREATE TABLE `password_reset_tokens` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `email` VARCHAR(255) NOT NULL, `token` VARCHAR(255) NOT NULL, `user_type` ENUM('admin', 'customer') NOT NULL, `expires_at` TIMESTAMP NOT NULL, `used` TINYINT(1) DEFAULT 0, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, INDEX `idx_token` (`token`), INDEX `idx_email` (`email`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Table: sessions -- -------------------------------------------------------- CREATE TABLE `sessions` ( `id` INT AUTO_INCREMENT PRIMARY KEY, `session_id` VARCHAR(128) NOT NULL UNIQUE, `user_id` VARCHAR(50) DEFAULT NULL, `user_type` ENUM('admin', 'customer') DEFAULT NULL, `data` TEXT, `ip_address` VARCHAR(45) DEFAULT NULL, `user_agent` VARCHAR(255) DEFAULT NULL, `created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, `expires_at` TIMESTAMP NOT NULL, INDEX `idx_session_id` (`session_id`), INDEX `idx_expires_at` (`expires_at`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci; -- -------------------------------------------------------- -- Insert default settings -- -------------------------------------------------------- INSERT INTO `settings` (`setting_key`, `setting_value`) VALUES ('store_name', '"Tom\'s Java Jive"'), ('store_email', '"support@tomsjavajive.com"'), ('store_phone', '""'), ('store_address', '""'), ('currency', '"USD"'), ('currency_symbol', '"$"'), ('tax_rate', '0'), ('shipping', '{"flat_rate_enabled": true, "flat_rate_amount": 5.99, "free_shipping_threshold": 50, "weight_based_enabled": false}'), ('payment', '{"stripe_enabled": true, "paypal_enabled": false, "cod_enabled": false}'), ('email', '{"sendgrid_api_key": "", "sender_email": "noreply@tomsjavajive.com", "sender_name": "Tom\'s Java Jive"}'); COMMIT;