← back to Handbag Auth Nextjs
src/app/api/admin/dashboard/route.ts
80 lines
import { NextRequest, NextResponse } from 'next/server'
import { PrismaClient } from '@prisma/client'
import { requireAuth, UserRole } from '@/lib/auth'
import { addSecurityHeaders } from '@/lib/securityHeaders'
import { rateLimit, getClientIp } from '@/lib/rateLimit'
const prisma = new PrismaClient()
export async function GET(request: NextRequest) {
// Apply rate limiting for admin endpoints
const clientIp = getClientIp(request)
const rateLimitResult = rateLimit(clientIp, {
windowMs: 60 * 1000,
maxRequests: 30, // Stricter rate limit for admin endpoints
})
if (!rateLimitResult.allowed) {
const response = NextResponse.json(
{ success: false, error: 'Rate limit exceeded' },
{ status: 429 }
)
addSecurityHeaders(response)
return response
}
// Require admin authentication
const authResult = await requireAuth(request, UserRole.ADMIN)
if (authResult instanceof NextResponse) {
return authResult // Return auth error response
}
try {
// Mock real-time metrics for demo
// In production, these would come from actual database queries
const stats = {
totalGMV: 247500,
monthlyGMV: 45000,
totalUsers: 5234,
activeInvestors: 523,
premiumSubscribers: 78,
totalRevenue: 12750,
affiliateRevenue: 5250,
fractionalRevenue: 4500,
subscriptionRevenue: 3000,
avgLTV: 485,
avgCAC: 127,
ltvcac: 3.82
}
const gmvHistory = [
{ month: 'Jan', gmv: 12500, revenue: 875 },
{ month: 'Feb', gmv: 18700, revenue: 1309 },
{ month: 'Mar', gmv: 25300, revenue: 1771 },
{ month: 'Apr', gmv: 32100, revenue: 2247 },
{ month: 'May', gmv: 45000, revenue: 3150 },
{ month: 'Jun (Proj)', gmv: 62000, revenue: 4340 }
]
const response = NextResponse.json({
success: true,
stats,
gmvHistory,
user: authResult // Include user info in response
})
addSecurityHeaders(response)
return response
} catch (error) {
console.error('Admin dashboard error:', error)
const response = NextResponse.json(
{ success: false, error: 'Failed to fetch dashboard data' },
{ status: 500 }
)
addSecurityHeaders(response)
return response
}
}