Files
gridpilot.gg/apps/website/app/api/payments/prizes/route.ts
2025-12-10 12:38:55 +01:00

180 lines
4.3 KiB
TypeScript

import { NextRequest, NextResponse } from 'next/server';
// Alpha: In-memory prize storage
const prizes: Map<string, {
id: string;
leagueId: string;
seasonId: string;
position: number;
name: string;
amount: number;
type: 'cash' | 'merchandise' | 'other';
description?: string;
awarded: boolean;
awardedTo?: string;
awardedAt?: Date;
createdAt: Date;
}> = new Map();
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const leagueId = searchParams.get('leagueId');
const seasonId = searchParams.get('seasonId');
if (!leagueId) {
return NextResponse.json(
{ error: 'leagueId is required' },
{ status: 400 }
);
}
let results = Array.from(prizes.values()).filter(p => p.leagueId === leagueId);
if (seasonId) {
results = results.filter(p => p.seasonId === seasonId);
}
results.sort((a, b) => a.position - b.position);
return NextResponse.json({ prizes: results });
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { leagueId, seasonId, position, name, amount, type, description } = body;
if (!leagueId || !seasonId || !position || !name || amount === undefined || !type) {
return NextResponse.json(
{ error: 'Missing required fields: leagueId, seasonId, position, name, amount, type' },
{ status: 400 }
);
}
if (!['cash', 'merchandise', 'other'].includes(type)) {
return NextResponse.json(
{ error: 'Type must be \"cash\", \"merchandise\", or \"other\"' },
{ status: 400 }
);
}
// Check for duplicate position
const existingPrize = Array.from(prizes.values()).find(
p => p.leagueId === leagueId && p.seasonId === seasonId && p.position === position
);
if (existingPrize) {
return NextResponse.json(
{ error: `Prize for position ${position} already exists` },
{ status: 409 }
);
}
const id = `prize-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
const prize = {
id,
leagueId,
seasonId,
position,
name,
amount,
type,
description: description || undefined,
awarded: false,
createdAt: new Date(),
};
prizes.set(id, prize);
return NextResponse.json({ prize }, { status: 201 });
} catch (err) {
console.error('Prize creation failed:', err);
return NextResponse.json(
{ error: 'Failed to create prize' },
{ status: 500 }
);
}
}
// Award a prize
export async function PATCH(request: NextRequest) {
try {
const body = await request.json();
const { prizeId, driverId } = body;
if (!prizeId || !driverId) {
return NextResponse.json(
{ error: 'Missing required fields: prizeId, driverId' },
{ status: 400 }
);
}
const prize = prizes.get(prizeId);
if (!prize) {
return NextResponse.json(
{ error: 'Prize not found' },
{ status: 404 }
);
}
if (prize.awarded) {
return NextResponse.json(
{ error: 'Prize has already been awarded' },
{ status: 400 }
);
}
prize.awarded = true;
prize.awardedTo = driverId;
prize.awardedAt = new Date();
prizes.set(prizeId, prize);
return NextResponse.json({ prize });
} catch (err) {
console.error('Prize awarding failed:', err);
return NextResponse.json(
{ error: 'Failed to award prize' },
{ status: 500 }
);
}
}
export async function DELETE(request: NextRequest) {
try {
const { searchParams } = new URL(request.url);
const prizeId = searchParams.get('prizeId');
if (!prizeId) {
return NextResponse.json(
{ error: 'prizeId is required' },
{ status: 400 }
);
}
const prize = prizes.get(prizeId);
if (!prize) {
return NextResponse.json(
{ error: 'Prize not found' },
{ status: 404 }
);
}
if (prize.awarded) {
return NextResponse.json(
{ error: 'Cannot delete an awarded prize' },
{ status: 400 }
);
}
prizes.delete(prizeId);
return NextResponse.json({ success: true });
} catch (err) {
console.error('Prize deletion failed:', err);
return NextResponse.json(
{ error: 'Failed to delete prize' },
{ status: 500 }
);
}
}