import mongoose from "mongoose"; import dotenv from "dotenv"; // Load environment variables FIRST dotenv.config(); /** * Manual Price Update Script * Run this to immediately update all item prices in the database * * Usage: node update-prices-now.js [game] * Examples: * node update-prices-now.js # Update all games * node update-prices-now.js cs2 # Update CS2 only * node update-prices-now.js rust # Update Rust only */ const MONGODB_URI = process.env.MONGODB_URI || "mongodb://localhost:27017/turbotrades"; async function main() { console.log("\n╔═══════════════════════════════════════════════╗"); console.log("║ TurboTrades Price Update Script ║"); console.log("╚═══════════════════════════════════════════════╝\n"); // Get game argument const gameArg = process.argv[2]?.toLowerCase(); const validGames = ["cs2", "rust", "all"]; const game = validGames.includes(gameArg) ? gameArg : "all"; // Check API key from environment const apiKey = process.env.STEAM_APIS_KEY || process.env.STEAM_API_KEY; console.log( `🎯 Target: ${game === "all" ? "All Games" : game.toUpperCase()}` ); console.log(`🔑 API Key: ${apiKey ? "✓ Configured" : "✗ Missing"}`); console.log(`📡 Database: ${MONGODB_URI}\n`); // Check API key if (!apiKey) { console.error("❌ ERROR: Steam API key not configured!"); console.error("\nPlease set one of these environment variables:"); console.error(" - STEAM_APIS_KEY (recommended)"); console.error(" - STEAM_API_KEY (fallback)\n"); console.error("Get your API key from: https://steamapis.com/\n"); console.error("\nCurrent environment variables:"); console.error( ` STEAM_APIS_KEY: ${process.env.STEAM_APIS_KEY ? "SET" : "NOT SET"}` ); console.error( ` STEAM_API_KEY: ${process.env.STEAM_API_KEY ? "SET" : "NOT SET"}\n` ); process.exit(1); } try { // Connect to MongoDB console.log("🔌 Connecting to MongoDB..."); await mongoose.connect(MONGODB_URI); console.log("✅ Connected to database\n"); // Import pricingService dynamically after env vars are loaded const pricingServiceModule = await import("./services/pricing.js"); const pricingService = pricingServiceModule.default; // Verify API key is loaded if (!pricingService.apiKey) { console.error("❌ ERROR: Pricing service didn't load API key!"); console.error( " This is an internal error - please check the pricing service.\n" ); process.exit(1); } // Import Item model const Item = (await import("./models/Item.js")).default; // Get item counts before update const cs2Count = await Item.countDocuments({ game: "cs2", status: "active", }); const rustCount = await Item.countDocuments({ game: "rust", status: "active", }); console.log("📦 Items in database:"); console.log(` CS2: ${cs2Count} active items`); console.log(` Rust: ${rustCount} active items\n`); if (cs2Count === 0 && rustCount === 0) { console.warn("⚠️ WARNING: No items found in database!"); console.warn( " Make sure you have items listed before updating prices.\n" ); } // Run price update console.log("🚀 Starting price update...\n"); console.log("─────────────────────────────────────────────────\n"); let result; if (game === "all") { // Update all games result = await pricingService.updateAllPrices(); console.log("\n─────────────────────────────────────────────────"); console.log("\n📊 UPDATE SUMMARY\n"); // CS2 Results if (result.cs2) { console.log("🎮 Counter-Strike 2:"); console.log(` Total Items: ${result.cs2.total || 0}`); console.log(` ✅ Updated: ${result.cs2.updated || 0}`); console.log(` ⚠️ Not Found: ${result.cs2.notFound || 0}`); console.log(` ❌ Errors: ${result.cs2.errors || 0}`); if (result.cs2.updated > 0) { const percentage = ( (result.cs2.updated / result.cs2.total) * 100 ).toFixed(1); console.log(` 📈 Success: ${percentage}%`); } console.log(); } // Rust Results if (result.rust) { console.log("🔧 Rust:"); console.log(` Total Items: ${result.rust.total || 0}`); console.log(` ✅ Updated: ${result.rust.updated || 0}`); console.log(` ⚠️ Not Found: ${result.rust.notFound || 0}`); console.log(` ❌ Errors: ${result.rust.errors || 0}`); if (result.rust.updated > 0) { const percentage = ( (result.rust.updated / result.rust.total) * 100 ).toFixed(1); console.log(` 📈 Success: ${percentage}%`); } console.log(); } const totalUpdated = (result.cs2?.updated || 0) + (result.rust?.updated || 0); const totalItems = (result.cs2?.total || 0) + (result.rust?.total || 0); console.log("═════════════════════════════════════════════════"); console.log(`\n🎉 Total: ${totalUpdated}/${totalItems} items updated\n`); } else { // Update single game result = await pricingService.updateDatabasePrices(game); console.log("\n─────────────────────────────────────────────────"); console.log("\n📊 UPDATE SUMMARY\n"); console.log(`🎮 ${game.toUpperCase()}:`); console.log(` Total Items: ${result.total || 0}`); console.log(` ✅ Updated: ${result.updated || 0}`); console.log(` ⚠️ Not Found: ${result.notFound || 0}`); console.log(` ❌ Errors: ${result.errors || 0}`); if (result.updated > 0) { const percentage = ((result.updated / result.total) * 100).toFixed(1); console.log(` 📈 Success: ${percentage}%`); } console.log("\n═════════════════════════════════════════════════\n"); } // Show sample of updated items console.log("📋 Sample of updated items:\n"); const updatedItems = await Item.find({ marketPrice: { $ne: null }, priceUpdatedAt: { $ne: null }, }) .sort({ priceUpdatedAt: -1 }) .limit(5) .select("name game marketPrice priceUpdatedAt"); if (updatedItems.length > 0) { updatedItems.forEach((item, index) => { console.log( ` ${index + 1}. [${item.game.toUpperCase()}] ${item.name}` ); console.log(` Price: $${item.marketPrice.toFixed(2)}`); console.log( ` Updated: ${new Date(item.priceUpdatedAt).toLocaleString()}\n` ); }); } else { console.log(" No items with prices found.\n"); } // Check for items still missing prices const missingPrices = await Item.countDocuments({ status: "active", $or: [{ marketPrice: null }, { marketPrice: { $exists: false } }], }); if (missingPrices > 0) { console.log(`⚠️ ${missingPrices} items still missing prices`); console.log( " These items may not exist on Steam market or have different names.\n" ); console.log( " 💡 Tip: Use the Admin Panel to manually set prices for these items.\n" ); } console.log("✅ Price update completed successfully!\n"); // Disconnect await mongoose.disconnect(); console.log("👋 Disconnected from database\n"); process.exit(0); } catch (error) { console.error("\n❌ ERROR during price update:"); console.error(` ${error.message}\n`); if (error.message.includes("API key")) { console.error("🔑 API Key Issue:"); console.error(" - Check your .env file"); console.error(" - Verify STEAM_APIS_KEY or STEAM_API_KEY is set"); console.error(" - Get a key from: https://steamapis.com/\n"); } else if (error.message.includes("rate limit")) { console.error("⏱️ Rate Limit:"); console.error(" - You've exceeded the API rate limit"); console.error(" - Wait a few minutes and try again"); console.error(" - Consider upgrading your API plan\n"); } else if ( error.message.includes("ECONNREFUSED") || error.message.includes("connect") ) { console.error("🔌 Connection Issue:"); console.error(" - Check MongoDB is running"); console.error(" - Verify MONGODB_URI in .env"); console.error(" - Check your internet connection\n"); } console.error("Stack trace:"); console.error(error.stack); console.error(); // Disconnect if connected if (mongoose.connection.readyState === 1) { await mongoose.disconnect(); console.log("👋 Disconnected from database\n"); } process.exit(1); } } // Handle ctrl+c gracefully process.on("SIGINT", async () => { console.log("\n\n⚠️ Update interrupted by user"); if (mongoose.connection.readyState === 1) { await mongoose.disconnect(); console.log("👋 Disconnected from database"); } process.exit(0); }); // Run the script main();