118 lines
4 KiB
TypeScript
118 lines
4 KiB
TypeScript
import { NextRequest, NextResponse } from 'next/server'
|
|
import { getServerSession } from 'next-auth'
|
|
import { authOptions } from '@/lib/auth'
|
|
import { connectToDatabase } from '@/lib/mongodb'
|
|
import { ObjectId } from 'mongodb'
|
|
import { checkRateLimit } from '@/lib/rate-limit'
|
|
|
|
export async function POST(request: NextRequest) {
|
|
try {
|
|
const session = await getServerSession(authOptions)
|
|
if (!session?.user?.id) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
}
|
|
|
|
if (checkRateLimit(session.user.id, 'rain', 1, 60000 * 2)) { // 1 rain every 2 minutes
|
|
return NextResponse.json({ error: 'Rate limit exceeded. Please wait before starting another rain.' }, { status: 429 })
|
|
}
|
|
|
|
const { db } = await connectToDatabase()
|
|
const body = await request.json()
|
|
const { amount } = body
|
|
const numAmount = parseFloat(amount)
|
|
|
|
if (isNaN(numAmount) || numAmount <= 0) {
|
|
return NextResponse.json({ error: 'Invalid amount' }, { status: 400 })
|
|
}
|
|
|
|
// Check for existing active rain
|
|
const existingRain = await db.collection('rains').findOne({ active: true })
|
|
if (existingRain) {
|
|
return NextResponse.json({ error: 'A rain event is already active!' }, { status: 409 })
|
|
}
|
|
|
|
const userToCheck = await db.collection('users').findOne({ _id: new ObjectId(session.user.id) })
|
|
if (!userToCheck || userToCheck.balance < numAmount) {
|
|
return NextResponse.json({ error: 'Insufficient balance' }, { status: 400 })
|
|
}
|
|
|
|
// Deduct balance
|
|
await db.collection('users').updateOne(
|
|
{ _id: userToCheck._id },
|
|
{ $inc: { balance: -numAmount } }
|
|
)
|
|
|
|
// Create Rain
|
|
// ! DEV MODE: 2 minutes instead of 10
|
|
const rain = {
|
|
amount: numAmount,
|
|
hostId: userToCheck._id.toString(),
|
|
hostName: userToCheck.name,
|
|
createdAt: new Date(),
|
|
endsAt: new Date(Date.now() + 2 * 60 * 1000),
|
|
participants: [],
|
|
active: true
|
|
}
|
|
|
|
await db.collection('rains').insertOne(rain)
|
|
|
|
return NextResponse.json({ success: true, rain })
|
|
} catch (error: any) {
|
|
console.error('Rain create error:', error)
|
|
return NextResponse.json({ error: error.message || 'Internal server error' }, { status: 500 })
|
|
}
|
|
}
|
|
|
|
export async function PUT(request: NextRequest) {
|
|
try {
|
|
const session = await getServerSession(authOptions)
|
|
if (!session?.user?.id) {
|
|
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
|
|
}
|
|
|
|
const { db } = await connectToDatabase()
|
|
|
|
// Find active rain
|
|
const activeRain = await db.collection('rains').findOne({ active: true })
|
|
if (!activeRain) {
|
|
return NextResponse.json({ error: 'No active rain to join' }, { status: 404 })
|
|
}
|
|
|
|
// Check if already joined
|
|
if (activeRain.participants.includes(session.user.id)) {
|
|
return NextResponse.json({ error: 'Already joined' }, { status: 400 })
|
|
}
|
|
|
|
// Add to participants
|
|
await db.collection('rains').updateOne(
|
|
{ _id: activeRain._id },
|
|
{ $addToSet: { participants: session.user.id } }
|
|
)
|
|
|
|
return NextResponse.json({ success: true })
|
|
} catch (error: any) {
|
|
console.error('Rain join error:', error)
|
|
return NextResponse.json({ error: error.message || 'Internal server error' }, { status: 500 })
|
|
}
|
|
}
|
|
|
|
export async function GET(request: NextRequest) {
|
|
try {
|
|
const { db } = await connectToDatabase()
|
|
const activeRain = await db.collection('rains').findOne({ active: true })
|
|
|
|
if (activeRain && activeRain.participants && activeRain.participants.length > 0) {
|
|
const participantIds = activeRain.participants.map((id: string) => new ObjectId(id))
|
|
const users = await db.collection('users').find({ _id: { $in: participantIds } }, { projection: { name: 1, image: 1 } }).toArray()
|
|
activeRain.participants = users.map(user => ({
|
|
id: user._id.toString(),
|
|
name: user.name,
|
|
image: user.image
|
|
}))
|
|
}
|
|
|
|
return NextResponse.json({ rain: activeRain })
|
|
} catch (error: any) {
|
|
return NextResponse.json({ error: error.message || 'Internal server error' }, { status: 500 })
|
|
}
|
|
}
|