ai-wpa/app/api/admin/users/route.ts

164 lines
4.7 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server'
import { withAdminAuth } from '@/lib/admin-middleware'
import { connectDB } from '@/lib/mongodb'
import { User } from '@/models/user'
import { z } from 'zod'
const UserUpdateSchema = z.object({
name: z.string().min(1).optional(),
email: z.string().email().optional(),
role: z.enum(['user', 'admin']).optional(),
isVerified: z.boolean().optional(),
balance: z.number().min(0).optional(),
})
const UserCreateSchema = z.object({
name: z.string().min(1),
email: z.string().email(),
password: z.string().min(6),
role: z.enum(['user', 'admin']).default('user'),
isVerified: z.boolean().default(false),
balance: z.number().min(0).default(0),
})
export async function GET(request: NextRequest) {
return withAdminAuth(request, async (req, admin) => {
try {
await connectDB()
const { searchParams } = new URL(request.url)
const page = parseInt(searchParams.get('page') || '1')
const limit = parseInt(searchParams.get('limit') || '20')
const search = searchParams.get('search') || ''
const role = searchParams.get('role') || ''
const verified = searchParams.get('verified') || ''
const skip = (page - 1) * limit
// Build filter query
const filter: any = {}
if (search) {
filter.$or = [
{ name: { $regex: search, $options: 'i' } },
{ email: { $regex: search, $options: 'i' } },
{ siliconId: { $regex: search, $options: 'i' } },
]
}
if (role && role !== 'all') {
filter.role = role
}
if (verified && verified !== 'all') {
filter.isVerified = verified === 'true'
}
const [users, totalUsers] = await Promise.all([
User.find(filter)
.select('-password -refreshToken')
.sort({ createdAt: -1 })
.skip(skip)
.limit(limit),
User.countDocuments(filter),
])
const totalPages = Math.ceil(totalUsers / limit)
return NextResponse.json({
users,
pagination: {
currentPage: page,
totalPages,
totalUsers,
hasNext: page < totalPages,
hasPrev: page > 1,
},
})
} catch (error) {
console.error('Admin users fetch error:', error)
return NextResponse.json({ error: 'Failed to fetch users' }, { status: 500 })
}
})
}
export async function POST(request: NextRequest) {
return withAdminAuth(request, async (req, admin) => {
try {
await connectDB()
const body = await request.json()
const { action, userId, data } = body
if (action === 'update') {
const validatedData = UserUpdateSchema.parse(data)
const user = await User.findByIdAndUpdate(userId, validatedData, {
new: true,
runValidators: true,
}).select('-password -refreshToken')
if (!user) {
return NextResponse.json({ error: 'User not found' }, { status: 404 })
}
return NextResponse.json({ user })
}
if (action === 'create') {
const validatedData = UserCreateSchema.parse(data)
// Check if user already exists
const existingUser = await User.findOne({ email: validatedData.email })
if (existingUser) {
return NextResponse.json(
{ error: 'User with this email already exists' },
{ status: 400 }
)
}
// Generate unique Silicon ID
const generateSiliconId = () => {
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
let result = 'SP'
for (let i = 0; i < 8; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length))
}
return result
}
let siliconId = generateSiliconId()
while (await User.findOne({ siliconId })) {
siliconId = generateSiliconId()
}
const user = new User({
...validatedData,
siliconId,
provider: 'local',
})
await user.save()
const userResponse = await User.findById(user._id).select('-password -refreshToken')
return NextResponse.json({ user: userResponse })
}
if (action === 'delete') {
const user = await User.findByIdAndDelete(userId)
if (!user) {
return NextResponse.json({ error: 'User not found' }, { status: 404 })
}
return NextResponse.json({ message: 'User deleted successfully' })
}
return NextResponse.json({ error: 'Invalid action' }, { status: 400 })
} catch (error) {
console.error('Admin user action error:', error)
return NextResponse.json({ error: 'Failed to perform user action' }, { status: 500 })
}
})
}