mirror of
https://github.com/myronblair/tomsjavajive
synced 2026-06-30 17:50:32 -05:00
Initial commit
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
#!/usr/bin/env python3
|
||||
import subprocess, os
|
||||
|
||||
BASE = '/home/tomsjavajive.com/public_html'
|
||||
|
||||
# ── Fix 1: Remove wholesale and careers from footer ──────────
|
||||
print("[1] Fixing footer...")
|
||||
f = BASE + '/includes/footer.php'
|
||||
with open(f) as fh:
|
||||
c = fh.read()
|
||||
|
||||
before = len(c)
|
||||
c = c.replace(' <li><a href="/wholesale.php">Wholesale</a></li>\n', '')
|
||||
c = c.replace(' <li><a href="/careers.php">Careers</a></li>\n', '')
|
||||
# Also try without leading spaces
|
||||
c = c.replace('<li><a href="/wholesale.php">Wholesale</a></li>\n', '')
|
||||
c = c.replace('<li><a href="/careers.php">Careers</a></li>\n', '')
|
||||
|
||||
with open(f, 'w') as fh:
|
||||
fh.write(c)
|
||||
removed = before - len(c)
|
||||
print(f" Footer: removed {removed} chars (wholesale + careers)")
|
||||
|
||||
# ── Fix 2: Check account pages for errors ───────────────────
|
||||
print("\n[2] Checking account pages...")
|
||||
for page in ['rewards', 'wishlist', 'reviews']:
|
||||
path = f'{BASE}/account/{page}.php'
|
||||
r = subprocess.run(
|
||||
['/usr/local/lsws/lsphp85/bin/php', '-d', 'display_errors=1',
|
||||
'-d', 'error_reporting=32767', path],
|
||||
capture_output=True, text=True
|
||||
)
|
||||
output = r.stdout + r.stderr
|
||||
errors = [l for l in output.split('\n')
|
||||
if any(x in l for x in ['Fatal','Error','Undefined','undefined','Call to'])]
|
||||
if errors:
|
||||
print(f" {page}.php ERRORS:")
|
||||
for e in errors[:3]:
|
||||
print(f" {e[:120]}")
|
||||
else:
|
||||
# Check if page has actual HTML content
|
||||
has_html = '<' in r.stdout and len(r.stdout) > 100
|
||||
print(f" {page}.php: {'OK - has content' if has_html else 'WARNING - minimal output'}")
|
||||
|
||||
# ── Fix 3: Check admin customers Modal ──────────────────────
|
||||
print("\n[3] Checking admin customers...")
|
||||
f2 = BASE + '/admin/customers.php'
|
||||
with open(f2) as fh:
|
||||
c2 = fh.read()
|
||||
|
||||
print(f" Modal.open present: {'Modal.open' in c2}")
|
||||
print(f" openCustomerModal present: {'openCustomerModal' in c2}")
|
||||
print(f" admin.js exists: {os.path.exists(BASE+'/admin/assets/admin.js')}")
|
||||
|
||||
# Check if admin.js has Modal object
|
||||
if os.path.exists(BASE+'/admin/assets/admin.js'):
|
||||
with open(BASE+'/admin/assets/admin.js') as fh:
|
||||
js = fh.read()
|
||||
print(f" Modal object in admin.js: {'Modal' in js}")
|
||||
print(f" admin.js size: {len(js)} chars")
|
||||
else:
|
||||
print(" admin.js MISSING - this is why customer modal doesn't work!")
|
||||
# Create a basic Modal object
|
||||
modal_js = """
|
||||
// Modal helper
|
||||
const Modal = {
|
||||
open: function(id) {
|
||||
const el = document.getElementById(id);
|
||||
if (el) { el.style.display = 'flex'; el.classList.add('active'); }
|
||||
},
|
||||
close: function(id) {
|
||||
const el = document.getElementById(id);
|
||||
if (el) { el.style.display = 'none'; el.classList.remove('active'); }
|
||||
}
|
||||
};
|
||||
document.addEventListener('keydown', function(e) {
|
||||
if (e.key === 'Escape') {
|
||||
document.querySelectorAll('.modal-overlay.active').forEach(m => {
|
||||
m.style.display = 'none'; m.classList.remove('active');
|
||||
});
|
||||
}
|
||||
});
|
||||
document.addEventListener('click', function(e) {
|
||||
if (e.target.classList.contains('modal-overlay')) {
|
||||
e.target.style.display = 'none'; e.target.classList.remove('active');
|
||||
}
|
||||
});
|
||||
"""
|
||||
os.makedirs(BASE+'/admin/assets', exist_ok=True)
|
||||
with open(BASE+'/admin/assets/admin.js', 'w') as fh:
|
||||
fh.write(modal_js)
|
||||
print(" Created admin.js with Modal object")
|
||||
|
||||
# ── Fix 4: Check account page includes ─────────────────────
|
||||
print("\n[4] Checking account page structure...")
|
||||
for page in ['rewards', 'wishlist', 'reviews']:
|
||||
path = f'{BASE}/account/{page}.php'
|
||||
with open(path) as fh:
|
||||
content = fh.read()
|
||||
has_auth = 'CustomerAuth::require' in content
|
||||
has_header = "require_once" in content and 'header' in content
|
||||
has_footer = 'footer' in content
|
||||
print(f" {page}.php: auth={has_auth}, header={has_header}, footer={has_footer}, size={len(content)}")
|
||||
|
||||
print("\nDone!")
|
||||
@@ -0,0 +1,37 @@
|
||||
-- Migration: Add wishlist table and addresses column to customers
|
||||
-- Run this in phpMyAdmin to add the new features
|
||||
|
||||
-- Add addresses column to customers table
|
||||
ALTER TABLE `customers` ADD COLUMN `addresses` JSON DEFAULT NULL AFTER `billing_address`;
|
||||
|
||||
-- Add preferences column to customers table
|
||||
ALTER TABLE `customers` ADD COLUMN `preferences` JSON DEFAULT NULL AFTER `addresses`;
|
||||
|
||||
-- Add is_active column to customers table if not exists
|
||||
ALTER TABLE `customers` ADD COLUMN `is_active` TINYINT(1) DEFAULT 1 AFTER `preferences`;
|
||||
|
||||
-- Create wishlist table
|
||||
CREATE TABLE IF NOT EXISTS `wishlist` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`customer_id` VARCHAR(50) NOT NULL,
|
||||
`product_id` VARCHAR(50) NOT NULL,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY `unique_wishlist` (`customer_id`, `product_id`),
|
||||
INDEX `idx_customer` (`customer_id`),
|
||||
INDEX `idx_product` (`product_id`),
|
||||
FOREIGN KEY (`customer_id`) REFERENCES `customers`(`customer_id`) ON DELETE CASCADE,
|
||||
FOREIGN KEY (`product_id`) REFERENCES `products`(`product_id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Add reorder_level column to products if not exists
|
||||
ALTER TABLE `products` ADD COLUMN `reorder_level` INT DEFAULT 10 AFTER `low_stock_threshold`;
|
||||
|
||||
-- Add slug column to products if not exists
|
||||
ALTER TABLE `products` ADD COLUMN `slug` VARCHAR(255) DEFAULT NULL AFTER `name`;
|
||||
ALTER TABLE `products` ADD INDEX `idx_slug` (`slug`);
|
||||
|
||||
-- Update existing products to have slugs based on name
|
||||
UPDATE `products` SET `slug` = LOWER(REPLACE(REPLACE(REPLACE(`name`, ' ', '-'), "'", ''), '"', '')) WHERE `slug` IS NULL;
|
||||
|
||||
-- Add is_pos_order to orders table
|
||||
ALTER TABLE `orders` ADD COLUMN `is_pos_order` TINYINT(1) DEFAULT 0 AFTER `notes`;
|
||||
@@ -0,0 +1,96 @@
|
||||
-- Migration: Add tables for push notifications, loyalty program, and integration settings
|
||||
-- Run this in phpMyAdmin
|
||||
|
||||
-- Push notification subscriptions
|
||||
CREATE TABLE IF NOT EXISTS `push_subscriptions` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`customer_id` VARCHAR(50) DEFAULT NULL,
|
||||
`endpoint` TEXT NOT NULL,
|
||||
`p256dh_key` VARCHAR(255) NOT NULL,
|
||||
`auth_key` VARCHAR(255) NOT NULL,
|
||||
`is_active` TINYINT(1) DEFAULT 1,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX `idx_customer` (`customer_id`),
|
||||
INDEX `idx_active` (`is_active`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Push notifications queue
|
||||
CREATE TABLE IF NOT EXISTS `push_notifications` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`notification_id` VARCHAR(50) NOT NULL UNIQUE,
|
||||
`subscription_endpoint` TEXT NOT NULL,
|
||||
`payload` TEXT NOT NULL,
|
||||
`status` ENUM('pending', 'sent', 'failed') DEFAULT 'pending',
|
||||
`error_message` TEXT DEFAULT NULL,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
`sent_at` TIMESTAMP NULL DEFAULT NULL,
|
||||
INDEX `idx_status` (`status`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Loyalty transactions history
|
||||
CREATE TABLE IF NOT EXISTS `loyalty_transactions` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`transaction_id` VARCHAR(50) NOT NULL UNIQUE,
|
||||
`customer_id` VARCHAR(50) NOT NULL,
|
||||
`points` INT NOT NULL,
|
||||
`type` ENUM('earn', 'redeem', 'tier_upgrade', 'birthday_bonus', 'referral_bonus', 'referral_welcome', 'adjustment', 'expiry') NOT NULL,
|
||||
`description` VARCHAR(255) DEFAULT NULL,
|
||||
`reference_amount` DECIMAL(10,2) DEFAULT NULL,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
INDEX `idx_customer` (`customer_id`),
|
||||
INDEX `idx_type` (`type`),
|
||||
INDEX `idx_created` (`created_at`),
|
||||
FOREIGN KEY (`customer_id`) REFERENCES `customers`(`customer_id`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
-- Add lifetime_points and loyalty_tier to customers
|
||||
ALTER TABLE `customers`
|
||||
ADD COLUMN IF NOT EXISTS `lifetime_points` INT DEFAULT 0 AFTER `reward_points`,
|
||||
ADD COLUMN IF NOT EXISTS `loyalty_tier` ENUM('bronze', 'silver', 'gold', 'platinum') DEFAULT 'bronze' AFTER `lifetime_points`,
|
||||
ADD COLUMN IF NOT EXISTS `birthday` DATE DEFAULT NULL AFTER `loyalty_tier`,
|
||||
ADD COLUMN IF NOT EXISTS `referral_code` VARCHAR(20) DEFAULT NULL AFTER `birthday`,
|
||||
ADD COLUMN IF NOT EXISTS `referred_by` VARCHAR(50) DEFAULT NULL AFTER `referral_code`;
|
||||
|
||||
-- Add unique index on referral_code
|
||||
ALTER TABLE `customers` ADD UNIQUE INDEX IF NOT EXISTS `idx_referral_code` (`referral_code`);
|
||||
|
||||
-- Update settings table with integration keys (INSERT IGNORE to not overwrite existing)
|
||||
INSERT IGNORE INTO `settings` (`setting_key`, `setting_value`, `updated_at`) VALUES
|
||||
('sendgrid_api_key', '', NOW()),
|
||||
('sendgrid_from_email', 'noreply@tomsjavajive.com', NOW()),
|
||||
('sendgrid_from_name', 'Tom''s Java Jive', NOW()),
|
||||
('twilio_account_sid', '', NOW()),
|
||||
('twilio_auth_token', '', NOW()),
|
||||
('twilio_phone_number', '', NOW()),
|
||||
('vapid_public_key', '', NOW()),
|
||||
('vapid_private_key', '', NOW()),
|
||||
('loyalty_enabled', '1', NOW()),
|
||||
('email_notifications_enabled', '1', NOW()),
|
||||
('sms_notifications_enabled', '0', NOW()),
|
||||
('push_notifications_enabled', '1', NOW());
|
||||
|
||||
-- Add Stripe checkout session column to orders
|
||||
ALTER TABLE `orders` ADD COLUMN IF NOT EXISTS `stripe_checkout_session` VARCHAR(255) DEFAULT NULL AFTER `stripe_payment_intent`;
|
||||
|
||||
-- Payment transactions table for tracking payment attempts
|
||||
CREATE TABLE IF NOT EXISTS `payment_transactions` (
|
||||
`id` INT AUTO_INCREMENT PRIMARY KEY,
|
||||
`transaction_id` VARCHAR(50) NOT NULL UNIQUE,
|
||||
`order_id` VARCHAR(50) NOT NULL,
|
||||
`customer_id` VARCHAR(50) DEFAULT NULL,
|
||||
`amount` DECIMAL(10,2) NOT NULL,
|
||||
`currency` VARCHAR(3) DEFAULT 'USD',
|
||||
`payment_method` VARCHAR(50) DEFAULT 'stripe',
|
||||
`stripe_session_id` VARCHAR(255) DEFAULT NULL,
|
||||
`stripe_payment_intent` VARCHAR(255) DEFAULT NULL,
|
||||
`status` ENUM('initiated', 'pending', 'processing', 'succeeded', 'failed', 'cancelled', 'refunded') DEFAULT 'initiated',
|
||||
`metadata` JSON DEFAULT NULL,
|
||||
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
INDEX `idx_order` (`order_id`),
|
||||
INDEX `idx_customer` (`customer_id`),
|
||||
INDEX `idx_status` (`status`),
|
||||
INDEX `idx_stripe_session` (`stripe_session_id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||||
|
||||
@@ -0,0 +1,402 @@
|
||||
-- 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;
|
||||
Reference in New Issue
Block a user