chore: final solana purge
This commit is contained in:
+141
-183
@@ -1,193 +1,151 @@
|
||||
import { Router } from 'express';
|
||||
import { authenticate, AuthenticatedRequest, requireAdmin } from '../middleware/auth';
|
||||
import { prisma } from '../utils/prisma';
|
||||
import { asyncHandler } from '../middleware/errorHandler';
|
||||
import { Router } from "express";
|
||||
import {
|
||||
type AuthenticatedRequest,
|
||||
authenticate,
|
||||
requireAdmin,
|
||||
} from "../middleware/auth";
|
||||
import { asyncHandler } from "../middleware/errorHandler";
|
||||
import { prisma } from "../utils/prisma";
|
||||
|
||||
const router = Router();
|
||||
|
||||
// Get user's transactions
|
||||
router.get('/',
|
||||
authenticate,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const { page = '1', limit = '20', type } = req.query;
|
||||
|
||||
const pageNum = parseInt(page as string);
|
||||
const limitNum = Math.min(parseInt(limit as string), 100);
|
||||
const skip = (pageNum - 1) * limitNum;
|
||||
|
||||
const where: any = { userId: req.user!.id };
|
||||
if (type) {
|
||||
where.type = type;
|
||||
}
|
||||
|
||||
const [transactions, total] = await Promise.all([
|
||||
prisma.transaction.findMany({
|
||||
where,
|
||||
orderBy: { createdAt: 'desc' },
|
||||
skip,
|
||||
take: limitNum,
|
||||
include: {
|
||||
watchEvent: {
|
||||
select: {
|
||||
duration: true,
|
||||
percentComplete: true
|
||||
}
|
||||
},
|
||||
request: {
|
||||
select: {
|
||||
mediaType: true,
|
||||
status: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
prisma.transaction.count({ where })
|
||||
]);
|
||||
|
||||
res.json({
|
||||
transactions,
|
||||
pagination: {
|
||||
page: pageNum,
|
||||
limit: limitNum,
|
||||
total,
|
||||
totalPages: Math.ceil(total / limitNum)
|
||||
}
|
||||
});
|
||||
})
|
||||
router.get(
|
||||
"/",
|
||||
authenticate,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const { page = "1", limit = "20", type } = req.query;
|
||||
const pageNum = parseInt(page as string);
|
||||
const limitNum = Math.min(parseInt(limit as string), 100);
|
||||
const skip = (pageNum - 1) * limitNum;
|
||||
const where: any = { userId: req.user!.id };
|
||||
if (type) where.type = type;
|
||||
const [transactions, total] = await Promise.all([
|
||||
prisma.transaction.findMany({
|
||||
where,
|
||||
orderBy: { createdAt: "desc" },
|
||||
skip,
|
||||
take: limitNum,
|
||||
include: {
|
||||
watchEvent: { select: { duration: true, percentComplete: true } },
|
||||
request: { select: { mediaType: true, status: true } },
|
||||
},
|
||||
}),
|
||||
prisma.transaction.count({ where }),
|
||||
]);
|
||||
res.json({
|
||||
transactions,
|
||||
pagination: {
|
||||
page: pageNum,
|
||||
limit: limitNum,
|
||||
total,
|
||||
totalPages: Math.ceil(total / limitNum),
|
||||
},
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
// Get transaction stats
|
||||
router.get('/stats',
|
||||
authenticate,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const thirtyDaysAgo = new Date();
|
||||
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
|
||||
|
||||
const [
|
||||
totalStats,
|
||||
recentStats,
|
||||
byType
|
||||
] = await Promise.all([
|
||||
// All time stats
|
||||
prisma.transaction.groupBy({
|
||||
by: ['type'],
|
||||
where: { userId: req.user!.id },
|
||||
_sum: { amount: true },
|
||||
_count: { id: true }
|
||||
}),
|
||||
// Last 30 days
|
||||
prisma.transaction.groupBy({
|
||||
by: ['type'],
|
||||
where: {
|
||||
userId: req.user!.id,
|
||||
createdAt: { gte: thirtyDaysAgo }
|
||||
},
|
||||
_sum: { amount: true },
|
||||
_count: { id: true }
|
||||
}),
|
||||
// By type breakdown
|
||||
prisma.transaction.findMany({
|
||||
where: { userId: req.user!.id },
|
||||
select: {
|
||||
type: true,
|
||||
amount: true,
|
||||
createdAt: true
|
||||
},
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 100
|
||||
})
|
||||
]);
|
||||
|
||||
// Calculate daily earnings for chart
|
||||
const dailyEarnings = await prisma.$queryRaw`
|
||||
SELECT
|
||||
DATE(created_at) as date,
|
||||
SUM(CASE WHEN type = 'EARN' THEN amount ELSE 0 END) as earned,
|
||||
SUM(CASE WHEN type = 'SPEND' THEN amount ELSE 0 END) as spent
|
||||
FROM transactions
|
||||
WHERE user_id = ${req.user!.id}
|
||||
AND created_at >= ${thirtyDaysAgo}
|
||||
GROUP BY DATE(created_at)
|
||||
ORDER BY date DESC
|
||||
`;
|
||||
|
||||
res.json({
|
||||
total: totalStats,
|
||||
recent: recentStats,
|
||||
dailyEarnings,
|
||||
recentTransactions: byType.slice(0, 10)
|
||||
});
|
||||
})
|
||||
router.get(
|
||||
"/stats",
|
||||
authenticate,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const thirtyDaysAgo = new Date();
|
||||
thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30);
|
||||
const [totalStats, recentStats, byType] = await Promise.all([
|
||||
prisma.transaction.groupBy({
|
||||
by: ["type"],
|
||||
where: { userId: req.user!.id },
|
||||
_sum: { amount: true },
|
||||
_count: { id: true },
|
||||
}),
|
||||
prisma.transaction.groupBy({
|
||||
by: ["type"],
|
||||
where: { userId: req.user!.id, createdAt: { gte: thirtyDaysAgo } },
|
||||
_sum: { amount: true },
|
||||
_count: { id: true },
|
||||
}),
|
||||
prisma.transaction.findMany({
|
||||
where: { userId: req.user!.id },
|
||||
select: { type: true, amount: true, createdAt: true },
|
||||
orderBy: { createdAt: "desc" },
|
||||
take: 100,
|
||||
}),
|
||||
]);
|
||||
const dailyEarnings =
|
||||
await prisma.$queryRaw`SELECT DATE(created_at) as date, SUM(CASE WHEN type = 'EARN' THEN amount ELSE 0 END) as earned, SUM(CASE WHEN type = 'SPEND' THEN amount ELSE 0 END) as spent FROM transactions WHERE user_id = ${req.user!.id} AND created_at >= ${thirtyDaysAgo} GROUP BY DATE(created_at) ORDER BY date DESC`;
|
||||
res.json({
|
||||
total: totalStats,
|
||||
recent: recentStats,
|
||||
dailyEarnings,
|
||||
recentTransactions: byType.slice(0, 10),
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
// Admin: Get all transactions
|
||||
router.get('/admin/all',
|
||||
authenticate,
|
||||
requireAdmin,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const { page = '1', limit = '50', userId, type } = req.query;
|
||||
|
||||
const pageNum = parseInt(page as string);
|
||||
const limitNum = Math.min(parseInt(limit as string), 100);
|
||||
const skip = (pageNum - 1) * limitNum;
|
||||
|
||||
const where: any = {};
|
||||
if (userId) where.userId = userId;
|
||||
if (type) where.type = type;
|
||||
|
||||
const [transactions, total] = await Promise.all([
|
||||
prisma.transaction.findMany({
|
||||
where,
|
||||
orderBy: { createdAt: 'desc' },
|
||||
skip,
|
||||
take: limitNum,
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
plexUsername: true,
|
||||
walletAddress: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}),
|
||||
prisma.transaction.count({ where })
|
||||
]);
|
||||
|
||||
res.json({
|
||||
transactions,
|
||||
pagination: {
|
||||
page: pageNum,
|
||||
limit: limitNum,
|
||||
total,
|
||||
totalPages: Math.ceil(total / limitNum)
|
||||
}
|
||||
});
|
||||
})
|
||||
router.get(
|
||||
"/admin/all",
|
||||
authenticate,
|
||||
requireAdmin,
|
||||
asyncHandler(async (req: AuthenticatedRequest, res) => {
|
||||
const { page = "1", limit = "50", userId, type } = req.query;
|
||||
const pageNum = parseInt(page as string);
|
||||
const limitNum = Math.min(parseInt(limit as string), 100);
|
||||
const skip = (pageNum - 1) * limitNum;
|
||||
const where: any = {};
|
||||
if (userId) where.userId = userId;
|
||||
if (type) where.type = type;
|
||||
const [transactions, total] = await Promise.all([
|
||||
prisma.transaction.findMany({
|
||||
where,
|
||||
orderBy: { createdAt: "desc" },
|
||||
skip,
|
||||
take: limitNum,
|
||||
include: { user: { select: { plexUsername: true } } },
|
||||
}),
|
||||
prisma.transaction.count({ where }),
|
||||
]);
|
||||
res.json({
|
||||
transactions,
|
||||
pagination: {
|
||||
page: pageNum,
|
||||
limit: limitNum,
|
||||
total,
|
||||
totalPages: Math.ceil(total / limitNum),
|
||||
},
|
||||
});
|
||||
}),
|
||||
);
|
||||
|
||||
// Get system-wide stats
|
||||
router.get('/admin/stats',
|
||||
// ... (keeping existing code)
|
||||
router.get(
|
||||
"/admin/stats",
|
||||
authenticate,
|
||||
requireAdmin,
|
||||
asyncHandler(async (_req: AuthenticatedRequest, res) => {
|
||||
const [total, recent] = await Promise.all([
|
||||
prisma.transaction.groupBy({
|
||||
by: ["type"],
|
||||
_sum: { amount: true },
|
||||
_count: { id: true },
|
||||
}),
|
||||
prisma.transaction.groupBy({
|
||||
by: ["type"],
|
||||
where: {
|
||||
createdAt: { gte: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) },
|
||||
},
|
||||
_sum: { amount: true },
|
||||
_count: { id: true },
|
||||
}),
|
||||
]);
|
||||
res.json({ total, recent });
|
||||
}),
|
||||
);
|
||||
|
||||
// Get recent global activity
|
||||
router.get('/recent',
|
||||
authenticate,
|
||||
asyncHandler(async (_req: AuthenticatedRequest, res) => {
|
||||
const transactions = await prisma.transaction.findMany({
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 10,
|
||||
include: {
|
||||
user: {
|
||||
select: {
|
||||
plexUsername: true
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
res.json({ transactions });
|
||||
})
|
||||
router.get(
|
||||
"/recent",
|
||||
authenticate,
|
||||
asyncHandler(async (_req: AuthenticatedRequest, res) => {
|
||||
const transactions = await prisma.transaction.findMany({
|
||||
orderBy: { createdAt: "desc" },
|
||||
take: 10,
|
||||
include: { user: { select: { plexUsername: true } } },
|
||||
});
|
||||
res.json({ transactions });
|
||||
}),
|
||||
);
|
||||
|
||||
export { router as transactionsRouter };
|
||||
|
||||
Reference in New Issue
Block a user