349 lines
12 KiB
JavaScript
349 lines
12 KiB
JavaScript
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();
|