first commit

This commit is contained in:
2026-01-10 04:57:43 +00:00
parent 16a76a2cd6
commit 232968de1e
131 changed files with 43262 additions and 0 deletions

180
models/MarketPrice.js Normal file
View File

@@ -0,0 +1,180 @@
import mongoose from "mongoose";
/**
* MarketPrice Model
* Stores reference prices from Steam market for quick lookups
* Used when loading inventory or updating item prices
*/
const marketPriceSchema = new mongoose.Schema(
{
// Item name (market_name from Steam API)
name: {
type: String,
required: true,
index: true,
},
// Game identifier
game: {
type: String,
required: true,
enum: ["cs2", "rust"],
index: true,
},
// Steam App ID
appId: {
type: Number,
required: true,
index: true,
},
// Market hash name (unique identifier from Steam)
marketHashName: {
type: String,
required: true,
unique: true,
},
// Price in USD
price: {
type: Number,
required: true,
min: 0,
},
// Type of price used (safe, median, mean, avg, latest)
priceType: {
type: String,
enum: ["safe", "median", "mean", "avg", "latest"],
default: "safe",
},
// Item image URL
image: {
type: String,
default: null,
},
// Border color (rarity indicator)
borderColor: {
type: String,
default: null,
},
// Steam name ID
nameId: {
type: Number,
default: null,
},
// Last updated timestamp
lastUpdated: {
type: Date,
default: Date.now,
index: true,
},
},
{
timestamps: true,
collection: "marketprices",
}
);
// Compound indexes for fast lookups
marketPriceSchema.index({ game: 1, name: 1 });
marketPriceSchema.index({ game: 1, marketHashName: 1 });
marketPriceSchema.index({ game: 1, price: -1 }); // For sorting by price
marketPriceSchema.index({ lastUpdated: -1 }); // For finding outdated prices
// Static method to find price by market hash name
marketPriceSchema.statics.findByMarketHashName = async function (
marketHashName,
game = null
) {
const query = { marketHashName };
if (game) query.game = game;
return await this.findOne(query);
};
// Static method to find price by name (partial match)
marketPriceSchema.statics.findByName = async function (name, game = null) {
const query = {
$or: [
{ name: name },
{ name: { $regex: name, $options: "i" } },
{ marketHashName: name },
{ marketHashName: { $regex: name, $options: "i" } },
],
};
if (game) query.game = game;
return await this.find(query).limit(10);
};
// Static method to get items by game
marketPriceSchema.statics.getByGame = async function (game, options = {}) {
const { limit = 100, skip = 0, minPrice = 0, maxPrice = null } = options;
const query = { game };
if (minPrice > 0) query.price = { $gte: minPrice };
if (maxPrice) {
query.price = query.price || {};
query.price.$lte = maxPrice;
}
return await this.find(query)
.sort({ price: -1 })
.limit(limit)
.skip(skip);
};
// Static method to get price statistics
marketPriceSchema.statics.getStats = async function (game = null) {
const match = game ? { game } : {};
const stats = await this.aggregate([
{ $match: match },
{
$group: {
_id: null,
count: { $sum: 1 },
avgPrice: { $avg: "$price" },
minPrice: { $min: "$price" },
maxPrice: { $max: "$price" },
totalValue: { $sum: "$price" },
},
},
]);
return stats[0] || {
count: 0,
avgPrice: 0,
minPrice: 0,
maxPrice: 0,
totalValue: 0,
};
};
// Instance method to check if price is outdated
marketPriceSchema.methods.isOutdated = function (hours = 24) {
const now = new Date();
const diff = now - this.lastUpdated;
const hoursDiff = diff / (1000 * 60 * 60);
return hoursDiff > hours;
};
// Instance method to update price
marketPriceSchema.methods.updatePrice = async function (newPrice, priceType) {
this.price = newPrice;
if (priceType) this.priceType = priceType;
this.lastUpdated = new Date();
return await this.save();
};
const MarketPrice = mongoose.model("MarketPrice", marketPriceSchema);
export default MarketPrice;