import mongoose from "mongoose"; import dotenv from "dotenv"; // Load environment variables dotenv.config(); /** * Price Diagnostic Script * Checks database for items and their pricing status * * Usage: node check-prices.js */ const MONGODB_URI = process.env.MONGODB_URI || "mongodb://localhost:27017/turbotrades"; async function main() { console.log("\n╔═══════════════════════════════════════════════╗"); console.log("║ TurboTrades Price Diagnostic Tool ║"); console.log("╚═══════════════════════════════════════════════╝\n"); try { // Connect to MongoDB console.log("🔌 Connecting to MongoDB..."); await mongoose.connect(MONGODB_URI); console.log("✅ Connected to database\n"); // Import Item model const Item = (await import("./models/Item.js")).default; console.log("─────────────────────────────────────────────────\n"); // Check API Key Configuration console.log("🔑 API KEY CONFIGURATION\n"); const steamApisKey = process.env.STEAM_APIS_KEY; const steamApiKey = process.env.STEAM_API_KEY; if (steamApisKey) { console.log(" ✅ STEAM_APIS_KEY: Configured"); console.log(` Value: ${steamApisKey.substring(0, 10)}...`); } else { console.log(" ⚠️ STEAM_APIS_KEY: Not set"); } if (steamApiKey) { console.log(" ✅ STEAM_API_KEY: Configured"); console.log(` Value: ${steamApiKey.substring(0, 10)}...`); } else { console.log(" ⚠️ STEAM_API_KEY: Not set"); } if (!steamApisKey && !steamApiKey) { console.log("\n ❌ ERROR: No API key configured!"); console.log(" Get your key from: https://steamapis.com/"); console.log(" Add to .env: STEAM_APIS_KEY=your_key_here\n"); } console.log("\n─────────────────────────────────────────────────\n"); // Get item counts console.log("📦 DATABASE ITEMS\n"); const totalItems = await Item.countDocuments(); const activeItems = await Item.countDocuments({ status: "active" }); const soldItems = await Item.countDocuments({ status: "sold" }); const removedItems = await Item.countDocuments({ status: "removed" }); console.log(` Total Items: ${totalItems}`); console.log(` Active: ${activeItems}`); console.log(` Sold: ${soldItems}`); console.log(` Removed: ${removedItems}\n`); // Game breakdown const cs2Items = await Item.countDocuments({ game: "cs2", status: "active" }); const rustItems = await Item.countDocuments({ game: "rust", status: "active" }); console.log(" By Game:"); console.log(` 🎮 CS2: ${cs2Items} active items`); console.log(` 🔧 Rust: ${rustItems} active items\n`); if (totalItems === 0) { console.log(" ⚠️ WARNING: No items in database!"); console.log(" You need to list items before updating prices.\n"); } console.log("─────────────────────────────────────────────────\n"); // Check pricing status console.log("💰 PRICING STATUS\n"); const itemsWithPrices = await Item.countDocuments({ status: "active", marketPrice: { $ne: null, $exists: true } }); const itemsWithoutPrices = await Item.countDocuments({ status: "active", $or: [ { marketPrice: null }, { marketPrice: { $exists: false }} ] }); const itemsOverridden = await Item.countDocuments({ status: "active", priceOverride: true }); console.log(` Items with prices: ${itemsWithPrices}`); console.log(` Items without prices: ${itemsWithoutPrices}`); console.log(` Admin overridden: ${itemsOverridden}\n`); if (activeItems > 0) { const pricePercentage = ((itemsWithPrices / activeItems) * 100).toFixed(1); console.log(` Coverage: ${pricePercentage}%\n`); if (pricePercentage < 50) { console.log(" ⚠️ Low price coverage detected!"); console.log(" Run: node update-prices-now.js\n"); } else if (pricePercentage === "100.0") { console.log(" ✅ All items have prices!\n"); } } // CS2 Pricing const cs2WithPrices = await Item.countDocuments({ game: "cs2", status: "active", marketPrice: { $ne: null, $exists: true } }); const cs2WithoutPrices = await Item.countDocuments({ game: "cs2", status: "active", $or: [ { marketPrice: null }, { marketPrice: { $exists: false }} ] }); console.log(" CS2 Breakdown:"); console.log(` ✅ With prices: ${cs2WithPrices}`); console.log(` ⚠️ Without prices: ${cs2WithoutPrices}\n`); // Rust Pricing const rustWithPrices = await Item.countDocuments({ game: "rust", status: "active", marketPrice: { $ne: null, $exists: true } }); const rustWithoutPrices = await Item.countDocuments({ game: "rust", status: "active", $or: [ { marketPrice: null }, { marketPrice: { $exists: false }} ] }); console.log(" Rust Breakdown:"); console.log(` ✅ With prices: ${rustWithPrices}`); console.log(` ⚠️ Without prices: ${rustWithoutPrices}\n`); console.log("─────────────────────────────────────────────────\n"); // Show sample items without prices if (itemsWithoutPrices > 0) { console.log("📋 SAMPLE ITEMS WITHOUT PRICES\n"); const sampleMissing = await Item.find({ status: "active", $or: [ { marketPrice: null }, { marketPrice: { $exists: false }} ] }) .limit(10) .select("name game category rarity wear phase"); sampleMissing.forEach((item, index) => { console.log(` ${index + 1}. [${item.game.toUpperCase()}] ${item.name}`); if (item.wear) console.log(` Wear: ${item.wear}`); if (item.phase) console.log(` Phase: ${item.phase}`); if (item.rarity) console.log(` Rarity: ${item.rarity}`); console.log(); }); if (itemsWithoutPrices > 10) { console.log(` ... and ${itemsWithoutPrices - 10} more\n`); } } // Show sample items with prices if (itemsWithPrices > 0) { console.log("─────────────────────────────────────────────────\n"); console.log("💎 SAMPLE ITEMS WITH PRICES\n"); const sampleWithPrices = await Item.find({ status: "active", marketPrice: { $ne: null, $exists: true } }) .sort({ marketPrice: -1 }) .limit(5) .select("name game marketPrice priceUpdatedAt priceOverride"); sampleWithPrices.forEach((item, index) => { console.log(` ${index + 1}. [${item.game.toUpperCase()}] ${item.name}`); console.log(` Market Price: $${item.marketPrice.toFixed(2)}`); if (item.priceUpdatedAt) { console.log(` Updated: ${new Date(item.priceUpdatedAt).toLocaleString()}`); } if (item.priceOverride) { console.log(` 🔧 Admin Override: Yes`); } console.log(); }); } console.log("─────────────────────────────────────────────────\n"); // Show price statistics if (itemsWithPrices > 0) { console.log("📊 PRICE STATISTICS\n"); const priceStats = await Item.aggregate([ { $match: { status: "active", marketPrice: { $ne: null, $exists: true } } }, { $group: { _id: null, avgPrice: { $avg: "$marketPrice" }, minPrice: { $min: "$marketPrice" }, maxPrice: { $max: "$marketPrice" }, totalValue: { $sum: "$marketPrice" } } } ]); if (priceStats.length > 0) { const stats = priceStats[0]; console.log(` Average Price: $${stats.avgPrice.toFixed(2)}`); console.log(` Minimum Price: $${stats.minPrice.toFixed(2)}`); console.log(` Maximum Price: $${stats.maxPrice.toFixed(2)}`); console.log(` Total Value: $${stats.totalValue.toFixed(2)}\n`); } console.log("─────────────────────────────────────────────────\n"); } // Recommendations console.log("💡 RECOMMENDATIONS\n"); if (!steamApisKey && !steamApiKey) { console.log(" 1. ❌ Configure API key in .env file"); } else { console.log(" 1. ✅ API key is configured"); } if (totalItems === 0) { console.log(" 2. ⚠️ Add items to the database (list items on sell page)"); } else { console.log(" 2. ✅ Items exist in database"); } if (itemsWithoutPrices > 0 && (steamApisKey || steamApiKey)) { console.log(" 3. 🔄 Run: node update-prices-now.js"); console.log(" This will fetch and update market prices"); } else if (itemsWithPrices > 0) { console.log(" 3. ✅ Prices are populated"); } if (itemsWithoutPrices > 0) { console.log(" 4. 🔧 Use Admin Panel to manually override missing prices"); console.log(" Navigate to: /admin → Items tab → Edit Prices"); } console.log("\n─────────────────────────────────────────────────\n"); // Automatic updates check console.log("⏰ AUTOMATIC UPDATES\n"); const enablePriceUpdates = process.env.ENABLE_PRICE_UPDATES; const nodeEnv = process.env.NODE_ENV || "development"; console.log(` Environment: ${nodeEnv}`); console.log(` ENABLE_PRICE_UPDATES: ${enablePriceUpdates || "not set"}\n`); if (nodeEnv === "production") { console.log(" ✅ Automatic updates enabled in production"); console.log(" Updates run every 60 minutes"); } else if (enablePriceUpdates === "true") { console.log(" ✅ Automatic updates enabled in development"); console.log(" Updates run every 60 minutes"); } else { console.log(" ⚠️ Automatic updates disabled in development"); console.log(" Set ENABLE_PRICE_UPDATES=true to enable"); } console.log("\n═════════════════════════════════════════════════\n"); console.log("✅ Diagnostic complete!\n"); // Disconnect await mongoose.disconnect(); console.log("👋 Disconnected from database\n"); process.exit(0); } catch (error) { console.error("\n❌ ERROR:"); console.error(` ${error.message}\n`); if (error.message.includes("ECONNREFUSED")) { console.error("🔌 MongoDB Connection Failed:"); console.error(" - Is MongoDB running?"); console.error(" - Check MONGODB_URI in .env"); console.error(` - Current URI: ${MONGODB_URI}\n`); } console.error("Stack trace:"); console.error(error.stack); console.error(); 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⚠️ Diagnostic interrupted by user"); if (mongoose.connection.readyState === 1) { await mongoose.disconnect(); console.log("👋 Disconnected from database"); } process.exit(0); }); // Run the script main();