system now uses seperate pricing.
All checks were successful
Build Frontend / Build Frontend (push) Successful in 22s

This commit is contained in:
2026-01-11 03:31:54 +00:00
parent 7a32454b83
commit 02d9727a72
3 changed files with 770 additions and 2 deletions

View File

@@ -1,6 +1,7 @@
import { authenticate } from "../middleware/auth.js";
import { authenticate, isAdmin } from "../middleware/auth.js";
import pricingService from "../services/pricing.js";
import Item from "../models/Item.js";
import MarketPrice from "../models/MarketPrice.js";
import Transaction from "../models/Transaction.js";
import User from "../models/User.js";
@@ -1115,4 +1116,242 @@ export default async function adminRoutes(fastify, options) {
}
}
);
// ============================================
// MARKETPRICE MANAGEMENT
// ============================================
// GET /admin/marketprices - Get paginated list of MarketPrice items
fastify.get(
"/marketprices",
{
preHandler: [authenticate, isAdmin],
schema: {
querystring: {
type: "object",
properties: {
page: { type: "integer", minimum: 1, default: 1 },
limit: { type: "integer", minimum: 1, maximum: 100, default: 50 },
game: { type: "string", enum: ["cs2", "rust", ""] },
search: { type: "string" },
sort: { type: "string", default: "name-asc" },
},
},
},
},
async (request, reply) => {
try {
const {
page = 1,
limit = 50,
game = "",
search = "",
sort = "name-asc",
} = request.query;
// Build query
const query = {};
if (game) {
query.game = game;
}
if (search) {
query.$or = [
{ name: { $regex: search, $options: "i" } },
{ marketHashName: { $regex: search, $options: "i" } },
];
}
// Build sort
let sortObj = {};
switch (sort) {
case "name-asc":
sortObj = { name: 1 };
break;
case "name-desc":
sortObj = { name: -1 };
break;
case "price-asc":
sortObj = { price: 1 };
break;
case "price-desc":
sortObj = { price: -1 };
break;
case "updated-desc":
sortObj = { lastUpdated: -1 };
break;
default:
sortObj = { name: 1 };
}
// Get total count
const total = await MarketPrice.countDocuments(query);
// Get items
const items = await MarketPrice.find(query)
.sort(sortObj)
.limit(limit)
.skip((page - 1) * limit)
.lean();
return reply.send({
success: true,
items,
page,
limit,
total,
pages: Math.ceil(total / limit),
});
} catch (error) {
console.error("❌ Failed to get market prices:", error);
return reply.status(500).send({
success: false,
message: "Failed to get market prices",
error: error.message,
});
}
}
);
// GET /admin/marketprices/stats - Get MarketPrice statistics
fastify.get(
"/marketprices/stats",
{
preHandler: [authenticate, isAdmin],
},
async (request, reply) => {
try {
const total = await MarketPrice.countDocuments();
const cs2 = await MarketPrice.countDocuments({ game: "cs2" });
const rust = await MarketPrice.countDocuments({ game: "rust" });
// Get most recent update
const lastItem = await MarketPrice.findOne()
.sort({ lastUpdated: -1 })
.select("lastUpdated")
.lean();
return reply.send({
success: true,
stats: {
total,
cs2,
rust,
lastUpdated: lastItem?.lastUpdated || null,
},
});
} catch (error) {
console.error("❌ Failed to get market price stats:", error);
return reply.status(500).send({
success: false,
message: "Failed to get stats",
error: error.message,
});
}
}
);
// PATCH /admin/marketprices/:id - Update a MarketPrice item
fastify.patch(
"/marketprices/:id",
{
preHandler: [authenticate, isAdmin],
schema: {
params: {
type: "object",
required: ["id"],
properties: {
id: { type: "string" },
},
},
body: {
type: "object",
properties: {
price: { type: "number", minimum: 0 },
},
},
},
},
async (request, reply) => {
try {
const { id } = request.params;
const { price } = request.body;
const item = await MarketPrice.findById(id);
if (!item) {
return reply.status(404).send({
success: false,
message: "Item not found",
});
}
item.price = price;
item.priceType = "manual"; // Mark as manually updated
item.lastUpdated = new Date();
await item.save();
console.log(
`⚙️ Admin ${request.user.username} updated price for ${item.name}: $${price}`
);
return reply.send({
success: true,
message: "Price updated successfully",
item,
});
} catch (error) {
console.error("❌ Failed to update market price:", error);
return reply.status(500).send({
success: false,
message: "Failed to update price",
error: error.message,
});
}
}
);
// DELETE /admin/marketprices/:id - Delete a MarketPrice item
fastify.delete(
"/marketprices/:id",
{
preHandler: [authenticate, isAdmin],
schema: {
params: {
type: "object",
required: ["id"],
properties: {
id: { type: "string" },
},
},
},
},
async (request, reply) => {
try {
const { id } = request.params;
const item = await MarketPrice.findByIdAndDelete(id);
if (!item) {
return reply.status(404).send({
success: false,
message: "Item not found",
});
}
console.log(
`⚙️ Admin ${request.user.username} deleted market price for ${item.name}`
);
return reply.send({
success: true,
message: "Item deleted successfully",
});
} catch (error) {
console.error("❌ Failed to delete market price:", error);
return reply.status(500).send({
success: false,
message: "Failed to delete item",
error: error.message,
});
}
}
);
}