generate_products.js (7272B)
1 #!/usr/bin/env node 2 3 /** 4 * Generate 2000 product records for the products service 5 * Outputs SQL INSERT statements to schemas/data/products_data.sql 6 */ 7 8 const fs = require('fs'); 9 const path = require('path'); 10 11 // Product categories 12 const categories = [ 13 'Electronics', 'Accessories', 'Gaming', 'Office', 14 'Audio', 'Computers', 'Mobile', 'Wearables', 15 'Smart Home', 'Camera', 'Networking', 'Storage' 16 ]; 17 18 // Product name templates 19 const productTypes = { 20 Electronics: [ 21 'Monitor', 'Laptop', 'Desktop', 'Tablet', 'E-Reader', 22 'TV', 'Projector', 'Smart Display', 'Graphics Card', 'Motherboard' 23 ], 24 Accessories: [ 25 'USB-C Cable', 'HDMI Cable', 'Power Adapter', 'Phone Case', 26 'Screen Protector', 'Cable Organizer', 'Laptop Sleeve', 'USB Hub' 27 ], 28 Gaming: [ 29 'Gaming Mouse', 'Gaming Keyboard', 'Gaming Headset', 'Controller', 30 'Gaming Chair', 'Mouse Pad', 'VR Headset', 'Gaming Monitor', 'Capture Card' 31 ], 32 Office: [ 33 'Desk Lamp', 'Office Chair', 'Standing Desk', 'Whiteboard', 34 'Desk Organizer', 'Notebook', 'Pen Set', 'Stapler', 'Paper Shredder' 35 ], 36 Audio: [ 37 'Bluetooth Speaker', 'Headphones', 'Earbuds', 'Microphone', 38 'Sound Bar', 'Subwoofer', 'Audio Interface', 'Studio Monitor' 39 ], 40 Computers: [ 41 'Keyboard', 'Mouse', 'Webcam', 'External Drive', 'RAM Module', 42 'SSD', 'CPU', 'Cooling Fan', 'Power Supply', 'PC Case' 43 ], 44 Mobile: [ 45 'Smartphone', 'Phone Charger', 'Wireless Charger', 'Car Mount', 46 'Selfie Stick', 'Phone Stand', 'PopSocket', 'Battery Pack' 47 ], 48 Wearables: [ 49 'Smart Watch', 'Fitness Tracker', 'Smart Ring', 'Smart Glasses', 50 'Heart Rate Monitor', 'GPS Watch', 'Sleep Tracker' 51 ], 52 'Smart Home': [ 53 'Smart Bulb', 'Smart Plug', 'Security Camera', 'Video Doorbell', 54 'Smart Lock', 'Smart Thermostat', 'Motion Sensor', 'Smart Switch' 55 ], 56 Camera: [ 57 'DSLR Camera', 'Mirrorless Camera', 'Action Camera', 'Camera Lens', 58 'Tripod', 'Camera Bag', 'SD Card', 'Flash', 'Gimbal' 59 ], 60 Networking: [ 61 'Router', 'WiFi Extender', 'Network Switch', 'Modem', 62 'Ethernet Cable', 'Powerline Adapter', 'Access Point' 63 ], 64 Storage: [ 65 'External SSD', 'External HDD', 'NAS Drive', 'USB Flash Drive', 66 'SD Card Reader', 'Hard Drive Enclosure', 'Cloud Storage Device' 67 ] 68 }; 69 70 // Adjectives for product variations 71 const adjectives = [ 72 'Pro', 'Plus', 'Max', 'Ultra', 'Premium', 'Elite', 'Advanced', 73 'Deluxe', 'Professional', 'HD', '4K', 'Wireless', 'Portable', 74 'Compact', 'Mini', 'XL', 'RGB', 'Ergonomic', 'Mechanical' 75 ]; 76 77 // Brands 78 const brands = [ 79 'TechPro', 'InnovateTech', 'SmartGear', 'ProElectronics', 'EliteTech', 80 'DigitalWave', 'FutureTech', 'PrimeTech', 'CoreTech', 'NexGen', 81 'PowerMax', 'UltraGear', 'SwiftTech', 'PrecisionTech', 'VisionTech', 82 'SonicWave', 'FlexTech', 'SpeedTech', 'ImpactTech', 'ApexTech' 83 ]; 84 85 /** 86 * Generate a random integer between min and max (inclusive) 87 */ 88 function randomInt(min, max) { 89 return Math.floor(Math.random() * (max - min + 1)) + min; 90 } 91 92 /** 93 * Pick a random element from an array 94 */ 95 function randomChoice(array) { 96 return array[Math.floor(Math.random() * array.length)]; 97 } 98 99 /** 100 * Generate a realistic price 101 */ 102 function generatePrice() { 103 const prices = [ 104 9.99, 12.99, 14.99, 19.99, 24.99, 29.99, 34.99, 39.99, 105 49.99, 59.99, 69.99, 79.99, 89.99, 99.99, 119.99, 149.99, 106 199.99, 249.99, 299.99, 349.99, 399.99, 449.99, 499.99, 107 599.99, 699.99, 799.99, 899.99, 999.99, 1299.99, 1499.99, 108 1999.99, 2499.99 109 ]; 110 return randomChoice(prices); 111 } 112 113 /** 114 * Generate a product description 115 */ 116 function generateDescription(productName, category) { 117 const templates = [ 118 `High-quality ${productName.toLowerCase()} designed for ${category.toLowerCase()} enthusiasts.`, 119 `Premium ${productName.toLowerCase()} with advanced features and superior performance.`, 120 `Professional-grade ${productName.toLowerCase()} perfect for work and play.`, 121 `Innovative ${productName.toLowerCase()} combining style and functionality.`, 122 `Top-rated ${productName.toLowerCase()} with excellent build quality and durability.`, 123 `Feature-rich ${productName.toLowerCase()} offering exceptional value for money.`, 124 `Cutting-edge ${productName.toLowerCase()} with the latest technology.`, 125 `Reliable ${productName.toLowerCase()} backed by industry-leading warranty.`, 126 `Versatile ${productName.toLowerCase()} suitable for both professionals and beginners.`, 127 `Award-winning ${productName.toLowerCase()} with outstanding reviews.` 128 ]; 129 return randomChoice(templates); 130 } 131 132 /** 133 * Generate a single product 134 */ 135 function generateProduct(index) { 136 const category = randomChoice(categories); 137 const productType = randomChoice(productTypes[category] || productTypes.Electronics); 138 const adjective = Math.random() > 0.4 ? randomChoice(adjectives) + ' ' : ''; 139 const variant = randomInt(1000, 9999); 140 141 const name = `${adjective}${productType} ${variant}`; 142 const brand = randomChoice(brands); 143 const description = generateDescription(productType, category); 144 const price = generatePrice(); 145 const stock = randomInt(0, 500); 146 147 return { 148 name, 149 description, 150 price, 151 category, 152 stock_quantity: stock 153 }; 154 } 155 156 /** 157 * Escape single quotes for SQL 158 */ 159 function escapeSql(str) { 160 if (!str) return str; 161 return str.replace(/'/g, "''"); 162 } 163 164 /** 165 * Generate SQL INSERT statements 166 */ 167 function generateSQL(products) { 168 const lines = [ 169 '-- Generated products data', 170 '-- Total products: ' + products.length, 171 '-- Generated at: ' + new Date().toISOString(), 172 '', 173 'SET search_path TO products, public;', 174 '', 175 '-- Insert products in batches for better performance', 176 'INSERT INTO products (name, description, price, category, stock_quantity) VALUES' 177 ]; 178 179 const valueLines = products.map((product, index) => { 180 const isLast = index === products.length - 1; 181 const name = escapeSql(product.name); 182 const desc = escapeSql(product.description); 183 const category = escapeSql(product.category); 184 185 return ` ('${name}', '${desc}', ${product.price}, '${category}', ${product.stock_quantity})${isLast ? ';' : ','}`; 186 }); 187 188 return lines.concat(valueLines).join('\n'); 189 } 190 191 /** 192 * Main function 193 */ 194 function main() { 195 console.log('Generating 2000 products...'); 196 197 const products = []; 198 for (let i = 0; i < 2000; i++) { 199 products.push(generateProduct(i)); 200 if ((i + 1) % 500 === 0) { 201 console.log(`Generated ${i + 1} products...`); 202 } 203 } 204 205 console.log('Generating SQL...'); 206 const sql = generateSQL(products); 207 208 const outputPath = path.join(__dirname, 'data', 'products_data.sql'); 209 fs.writeFileSync(outputPath, sql, 'utf8'); 210 211 console.log(`✓ Successfully generated ${products.length} products`); 212 console.log(`✓ SQL file saved to: ${outputPath}`); 213 console.log(`✓ File size: ${(sql.length / 1024).toFixed(2)} KB`); 214 } 215 216 // Run the script 217 main();