271 lines
9.7 KiB
JavaScript
271 lines
9.7 KiB
JavaScript
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();
|