Spaces:
Running
Running
Download src/controllers/admin.controller.js from AndreaNotes1/auth-app-api: direct link, hf CLI and curl.
- Browser
- Download file 5.07 kB
-
https://huggingface.co/spaces/AndreaNotes1/auth-app-api/resolve/main/src/controllers/admin.controller.js
- Command line
-
hf download hf://spaces/AndreaNotes1/auth-app-api/src/controllers/admin.controller.js
-
curl -L -o admin.controller.js https://huggingface.co/spaces/AndreaNotes1/auth-app-api/resolve/main/src/controllers/admin.controller.js
5.07 kB
| const Order = require("../models/Order"); | |
| const User = require("../models/User"); | |
| const AuditLog = require("../models/AuditLog"); | |
| const { sendPaymentRejectedEmail } = require("../utils/email"); | |
| const { confirmOrderAndGrantAccess } = require("../utils/orderConfirmation"); | |
| const logger = require("../utils/logger"); | |
| async function listOrders(req, res, next) { | |
| try { | |
| const { status } = req.query; | |
| const filter = {}; | |
| if (status) filter.status = status; | |
| const orders = await Order.find(filter) | |
| .sort({ createdAt: -1 }) | |
| .populate("user", "name email") | |
| .populate("course", "title"); | |
| res.json({ | |
| orders: orders.map((o) => ({ | |
| ...o.toPublicJSON(), | |
| user: o.user ? { id: o.user._id, name: o.user.name, email: o.user.email } : null, | |
| })), | |
| }); | |
| } catch (err) { | |
| next(err); | |
| } | |
| } | |
| /** Admin views the decrypted payment reference only when actively reviewing a specific order. */ | |
| async function getOrderDetail(req, res, next) { | |
| try { | |
| const order = await Order.findById(req.params.id) | |
| .select("+paymentReferenceEncrypted +payerNoteEncrypted") | |
| .populate("user", "name email") | |
| .populate("course", "title price"); | |
| if (!order) return res.status(404).json({ error: "Order not found." }); | |
| await AuditLog.create({ | |
| actor: req.user._id, | |
| actorEmail: req.user.email, | |
| action: "admin.order_viewed", | |
| targetType: "Order", | |
| targetId: order._id, | |
| ip: req.ip, | |
| userAgent: req.headers["user-agent"], | |
| }); | |
| res.json({ | |
| order: { | |
| ...order.toPublicJSON({ includeSensitive: true }), | |
| user: order.user ? { id: order.user._id, name: order.user.name, email: order.user.email } : null, | |
| }, | |
| }); | |
| } catch (err) { | |
| next(err); | |
| } | |
| } | |
| /** | |
| * Confirms a payment: marks the order confirmed, grants course access to | |
| * the user, and emails the customer. Wrapped in a transaction so a | |
| * partial failure can't leave the order confirmed without access | |
| * granted (or vice versa). | |
| */ | |
| async function confirmOrder(req, res, next) { | |
| try { | |
| const existing = await Order.findById(req.params.id); | |
| if (!existing) return res.status(404).json({ error: "Order not found." }); | |
| if (existing.status === "confirmed") return res.status(409).json({ error: "Order already confirmed." }); | |
| const { order } = await confirmOrderAndGrantAccess({ | |
| orderId: req.params.id, | |
| confirmedBy: req.user._id, | |
| ip: req.ip, | |
| userAgent: req.headers["user-agent"], | |
| }); | |
| res.json({ order: order.toPublicJSON() }); | |
| } catch (err) { | |
| next(err); | |
| } | |
| } | |
| async function rejectOrder(req, res, next) { | |
| try { | |
| const { reason } = req.body; | |
| const order = await Order.findById(req.params.id).populate("user", "name email"); | |
| if (!order) return res.status(404).json({ error: "Order not found." }); | |
| if (order.status === "confirmed") { | |
| return res.status(409).json({ error: "A confirmed order cannot be rejected. Consider revoking access separately." }); | |
| } | |
| order.status = "rejected"; | |
| order.rejectionReason = reason || null; | |
| await order.save(); | |
| await AuditLog.create({ | |
| actor: req.user._id, | |
| actorEmail: req.user.email, | |
| action: "admin.order_rejected", | |
| targetType: "Order", | |
| targetId: order._id, | |
| ip: req.ip, | |
| userAgent: req.headers["user-agent"], | |
| metadata: { reason: reason || null }, | |
| }); | |
| if (order.user) { | |
| sendPaymentRejectedEmail({ | |
| to: order.user.email, | |
| name: order.user.name, | |
| order, | |
| courseTitle: order.courseTitleSnapshot, | |
| reason, | |
| }).catch((err) => logger.error("Payment-rejected email failed", { error: err.message })); | |
| } | |
| res.json({ order: order.toPublicJSON() }); | |
| } catch (err) { | |
| next(err); | |
| } | |
| } | |
| async function dashboardStats(req, res, next) { | |
| try { | |
| const [pendingCount, confirmedCount, rejectedCount, totalUsers, revenueAgg] = await Promise.all([ | |
| Order.countDocuments({ status: "awaiting_confirmation" }), | |
| Order.countDocuments({ status: "confirmed" }), | |
| Order.countDocuments({ status: "rejected" }), | |
| User.countDocuments({ role: "user" }), | |
| Order.aggregate([{ $match: { status: "confirmed" } }, { $group: { _id: "$currency", total: { $sum: "$amount" } } }]), | |
| ]); | |
| res.json({ | |
| pendingOrders: pendingCount, | |
| confirmedOrders: confirmedCount, | |
| rejectedOrders: rejectedCount, | |
| totalUsers, | |
| revenueByCurrency: revenueAgg.map((r) => ({ currency: r._id, total: r.total })), | |
| }); | |
| } catch (err) { | |
| next(err); | |
| } | |
| } | |
| async function listUsers(req, res, next) { | |
| try { | |
| const users = await User.find({}).sort({ createdAt: -1 }).limit(500); | |
| res.json({ users: users.map((u) => u.toSafeJSON()) }); | |
| } catch (err) { | |
| next(err); | |
| } | |
| } | |
| module.exports = { listOrders, getOrderDetail, confirmOrder, rejectOrder, dashboardStats, listUsers }; | |