214 lines
3.8 KiB
JavaScript
214 lines
3.8 KiB
JavaScript
import mongoose from "mongoose";
|
|
|
|
const itemSchema = new mongoose.Schema(
|
|
{
|
|
// Basic Item Information
|
|
name: {
|
|
type: String,
|
|
required: true,
|
|
trim: true,
|
|
},
|
|
description: {
|
|
type: String,
|
|
default: "",
|
|
},
|
|
image: {
|
|
type: String,
|
|
required: true,
|
|
},
|
|
|
|
// Game Information
|
|
game: {
|
|
type: String,
|
|
required: true,
|
|
enum: ["cs2", "rust"],
|
|
},
|
|
|
|
// Category
|
|
category: {
|
|
type: String,
|
|
required: true,
|
|
enum: [
|
|
"rifles",
|
|
"pistols",
|
|
"knives",
|
|
"gloves",
|
|
"stickers",
|
|
"cases",
|
|
"smgs",
|
|
"other",
|
|
],
|
|
},
|
|
|
|
// Rarity
|
|
rarity: {
|
|
type: String,
|
|
required: true,
|
|
enum: [
|
|
"common",
|
|
"uncommon",
|
|
"rare",
|
|
"mythical",
|
|
"legendary",
|
|
"ancient",
|
|
"exceedingly",
|
|
],
|
|
},
|
|
|
|
// Wear Condition (for CS2 items)
|
|
wear: {
|
|
type: String,
|
|
enum: ["fn", "mw", "ft", "ww", "bs", null],
|
|
default: null,
|
|
},
|
|
|
|
// Float Value (for CS2 items)
|
|
float: {
|
|
type: Number,
|
|
min: 0,
|
|
max: 1,
|
|
default: null,
|
|
},
|
|
|
|
// Phase (for Doppler, Gamma Doppler, etc.)
|
|
phase: {
|
|
type: String,
|
|
enum: [
|
|
"Phase 1",
|
|
"Phase 2",
|
|
"Phase 3",
|
|
"Phase 4",
|
|
"Ruby",
|
|
"Sapphire",
|
|
"Black Pearl",
|
|
"Emerald",
|
|
null,
|
|
],
|
|
default: null,
|
|
},
|
|
|
|
// Special Properties
|
|
statTrak: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
souvenir: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
|
|
// Price (seller's listing price)
|
|
price: {
|
|
type: Number,
|
|
required: true,
|
|
min: 0,
|
|
},
|
|
|
|
// Market Price (from SteamAPIs.com)
|
|
marketPrice: {
|
|
type: Number,
|
|
default: null,
|
|
},
|
|
|
|
// Last price update timestamp
|
|
priceUpdatedAt: {
|
|
type: Date,
|
|
default: null,
|
|
},
|
|
|
|
// Price Override (admin-set custom price)
|
|
priceOverride: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
|
|
// Seller Information
|
|
seller: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: "User",
|
|
required: true,
|
|
},
|
|
|
|
// Status
|
|
status: {
|
|
type: String,
|
|
enum: ["active", "sold", "removed"],
|
|
default: "active",
|
|
},
|
|
|
|
// Timestamps
|
|
listedAt: {
|
|
type: Date,
|
|
default: Date.now,
|
|
},
|
|
soldAt: {
|
|
type: Date,
|
|
default: null,
|
|
},
|
|
|
|
// Buyer (if sold)
|
|
buyer: {
|
|
type: mongoose.Schema.Types.ObjectId,
|
|
ref: "User",
|
|
default: null,
|
|
},
|
|
|
|
// Featured
|
|
featured: {
|
|
type: Boolean,
|
|
default: false,
|
|
},
|
|
|
|
// Views counter
|
|
views: {
|
|
type: Number,
|
|
default: 0,
|
|
},
|
|
},
|
|
{
|
|
timestamps: true,
|
|
}
|
|
);
|
|
|
|
// Indexes for better query performance
|
|
itemSchema.index({ game: 1, status: 1 });
|
|
itemSchema.index({ category: 1, status: 1 });
|
|
itemSchema.index({ rarity: 1, status: 1 });
|
|
itemSchema.index({ price: 1, status: 1 });
|
|
itemSchema.index({ seller: 1, status: 1 });
|
|
itemSchema.index({ featured: 1, status: 1 });
|
|
itemSchema.index({ listedAt: -1 });
|
|
itemSchema.index({ phase: 1 });
|
|
itemSchema.index({ name: 1 }); // For price updates
|
|
|
|
// Virtual for seller details
|
|
itemSchema.virtual("sellerDetails", {
|
|
ref: "User",
|
|
localField: "seller",
|
|
foreignField: "_id",
|
|
justOne: true,
|
|
});
|
|
|
|
// Methods
|
|
itemSchema.methods.markAsSold = function (buyerId) {
|
|
this.status = "sold";
|
|
this.soldAt = new Date();
|
|
this.buyer = buyerId;
|
|
return this.save();
|
|
};
|
|
|
|
itemSchema.methods.incrementViews = function () {
|
|
this.views += 1;
|
|
return this.save();
|
|
};
|
|
|
|
itemSchema.methods.updateMarketPrice = function (newPrice) {
|
|
this.marketPrice = newPrice;
|
|
this.priceUpdatedAt = new Date();
|
|
return this.save();
|
|
};
|
|
|
|
const Item = mongoose.model("Item", itemSchema);
|
|
|
|
export default Item;
|