-- Module Licensing System -- Phase 4: Module marketplace and license-module binding -- Module registry (available modules in marketplace) CREATE TABLE modules ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), slug VARCHAR(100) UNIQUE NOT NULL, name VARCHAR(200) NOT NULL, description TEXT, category VARCHAR(50), -- 'loot', 'events', 'economy', 'kits', etc. price_usd DECIMAL(10,2) NOT NULL, preview_image_url TEXT, screenshots JSONB, features JSONB, version VARCHAR(20) NOT NULL, plugin_file_url TEXT, -- Download URL for plugin file created_at TIMESTAMPTZ DEFAULT NOW() ); -- Module purchases (which licenses own which modules) CREATE TABLE module_purchases ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, module_id UUID NOT NULL REFERENCES modules(id) ON DELETE CASCADE, purchased_at TIMESTAMPTZ DEFAULT NOW(), transaction_id VARCHAR(255), -- PayPal transaction ID amount_paid DECIMAL(10,2), UNIQUE(license_id, module_id) ); -- Module installations (deployment status on servers) CREATE TABLE module_installations ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), license_id UUID NOT NULL REFERENCES licenses(id) ON DELETE CASCADE, module_id UUID NOT NULL REFERENCES modules(id) ON DELETE CASCADE, status VARCHAR(50) DEFAULT 'pending', -- 'pending', 'installing', 'installed', 'failed' installed_at TIMESTAMPTZ, error_message TEXT, UNIQUE(license_id, module_id) ); CREATE INDEX idx_module_purchases_license ON module_purchases(license_id); CREATE INDEX idx_module_installations_license ON module_installations(license_id); -- Seed data: Loot Manager module INSERT INTO modules (slug, name, description, category, price_usd, version, features) VALUES ( 'loot-manager', 'Loot Manager', 'Visual loot table editor with drag-and-drop items, spawn rates, and one-click profile switching.', 'loot', 9.99, '1.0.0', '["Visual loot table editor", "Container browser (crates, barrels, NPCs)", "Loot profiles (2x, 10x, etc.)", "One-click profile switching", "Import/export profiles"]'::JSONB );