feat: add tournament type and team support to tournament APIs
Update tournament APIs to support: - tournamentType field (individual/team) - Team creation for team tournaments - Even number validation for team tournaments - Automatic pairing of consecutive players into teams
This commit is contained in:
@@ -36,7 +36,106 @@ export async function POST(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add participants to tournament
|
// Fetch tournament to check type
|
||||||
|
const tournament = await prisma.event.findUnique({
|
||||||
|
where: { id: tournamentId },
|
||||||
|
select: { tournamentType: true },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!tournament) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Tournament not found" },
|
||||||
|
{ status: 404 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const isTeamTournament = tournament.tournamentType === "team";
|
||||||
|
|
||||||
|
// For team tournaments, pair players into teams
|
||||||
|
if (isTeamTournament) {
|
||||||
|
if (playerIds.length % 2 !== 0) {
|
||||||
|
return NextResponse.json(
|
||||||
|
{ error: "Team tournaments require an even number of players" },
|
||||||
|
{ status: 400 }
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create teams from consecutive pairs
|
||||||
|
const teams = [];
|
||||||
|
for (let i = 0; i < playerIds.length; i += 2) {
|
||||||
|
const player1Id = playerIds[i];
|
||||||
|
const player2Id = playerIds[i + 1];
|
||||||
|
|
||||||
|
// Check if team already exists
|
||||||
|
const existingTeam = await prisma.team.findFirst({
|
||||||
|
where: {
|
||||||
|
eventId: tournamentId,
|
||||||
|
OR: [
|
||||||
|
{ AND: [{ player1Id }, { player2Id }] },
|
||||||
|
{ AND: [{ player1Id: player2Id }, { player2Id: player1Id }] },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
let team;
|
||||||
|
if (existingTeam) {
|
||||||
|
team = existingTeam;
|
||||||
|
} else {
|
||||||
|
team = await prisma.team.create({
|
||||||
|
data: {
|
||||||
|
eventId: tournamentId,
|
||||||
|
player1Id,
|
||||||
|
player2Id,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create participants linked to this team
|
||||||
|
const participant1 = await prisma.eventParticipant.upsert({
|
||||||
|
where: {
|
||||||
|
eventId_playerId: {
|
||||||
|
eventId: tournamentId,
|
||||||
|
playerId: player1Id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: { teamId: team.id },
|
||||||
|
create: {
|
||||||
|
eventId: tournamentId,
|
||||||
|
playerId: player1Id,
|
||||||
|
teamId: team.id,
|
||||||
|
status: "registered",
|
||||||
|
registrationDate: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const participant2 = await prisma.eventParticipant.upsert({
|
||||||
|
where: {
|
||||||
|
eventId_playerId: {
|
||||||
|
eventId: tournamentId,
|
||||||
|
playerId: player2Id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
update: { teamId: team.id },
|
||||||
|
create: {
|
||||||
|
eventId: tournamentId,
|
||||||
|
playerId: player2Id,
|
||||||
|
teamId: team.id,
|
||||||
|
status: "registered",
|
||||||
|
registrationDate: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
teams.push({ team, participants: [participant1, participant2] });
|
||||||
|
}
|
||||||
|
|
||||||
|
return NextResponse.json({
|
||||||
|
success: true,
|
||||||
|
teamsCreated: teams.length,
|
||||||
|
teams,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Individual tournament - just add participants
|
||||||
const participants = await Promise.all(
|
const participants = await Promise.all(
|
||||||
playerIds.map(async (playerId: number) => {
|
playerIds.map(async (playerId: number) => {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ export async function PUT(request: Request, { params }: RouteParams) {
|
|||||||
description,
|
description,
|
||||||
eventDate,
|
eventDate,
|
||||||
eventType,
|
eventType,
|
||||||
|
tournamentType,
|
||||||
format,
|
format,
|
||||||
status,
|
status,
|
||||||
maxParticipants,
|
maxParticipants,
|
||||||
@@ -166,6 +167,7 @@ export async function PUT(request: Request, { params }: RouteParams) {
|
|||||||
description: description || null,
|
description: description || null,
|
||||||
eventDate: eventDate ? new Date(eventDate) : null,
|
eventDate: eventDate ? new Date(eventDate) : null,
|
||||||
eventType: eventType || "tournament",
|
eventType: eventType || "tournament",
|
||||||
|
tournamentType: tournamentType || "individual",
|
||||||
format: format || "round_robin",
|
format: format || "round_robin",
|
||||||
maxParticipants: maxParticipants ? parseInt(maxParticipants) : null,
|
maxParticipants: maxParticipants ? parseInt(maxParticipants) : null,
|
||||||
targetScore: targetScore ? parseInt(targetScore) : null,
|
targetScore: targetScore ? parseInt(targetScore) : null,
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ export async function POST(request: Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const body = await request.json();
|
const body = await request.json();
|
||||||
const { name, format, eventDate, targetScore, allowTies } = body;
|
const { name, format, eventDate, targetScore, allowTies, maxParticipants, tournamentType } = body;
|
||||||
|
|
||||||
const tournament = await prisma.event.create({
|
const tournament = await prisma.event.create({
|
||||||
data: {
|
data: {
|
||||||
@@ -77,10 +77,13 @@ export async function POST(request: Request) {
|
|||||||
format: format || "round_robin",
|
format: format || "round_robin",
|
||||||
eventDate: eventDate ? new Date(eventDate) : null,
|
eventDate: eventDate ? new Date(eventDate) : null,
|
||||||
eventType: "tournament",
|
eventType: "tournament",
|
||||||
|
tournamentType: tournamentType || "individual",
|
||||||
status: "planned",
|
status: "planned",
|
||||||
ownerId: session.user.id, // Assign ownership to the creator
|
ownerId: session.user.id,
|
||||||
targetScore: targetScore ? parseInt(targetScore) : null,
|
targetScore: targetScore ? parseInt(targetScore) : null,
|
||||||
allowTies: allowTies ?? false,
|
allowTies: allowTies ?? false,
|
||||||
|
maxParticipants: maxParticipants ? parseInt(maxParticipants) : null,
|
||||||
|
description: body.description,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user