feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
import type { Route } from "./+types/admin.sports-seasons.$id.events.$eventId.bracket";
|
|
|
|
|
import { redirect } from "react-router";
|
|
|
|
|
import { findSportsSeasonById } from "~/models/sports-season";
|
|
|
|
|
import { findParticipantsBySportsSeasonId } from "~/models/participant";
|
2025-11-04 22:09:44 -08:00
|
|
|
import { getScoringEventById, updateScoringEvent } from "~/models/scoring-event";
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
import {
|
|
|
|
|
findPlayoffMatchesByEventId,
|
2025-11-04 22:09:44 -08:00
|
|
|
generateBracketFromTemplate,
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
setMatchWinner,
|
2025-11-04 22:09:44 -08:00
|
|
|
advanceWinnerTemplate,
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
findPlayoffMatchById,
|
|
|
|
|
} from "~/models/playoff-match";
|
|
|
|
|
import { processPlayoffEvent } from "~/models/scoring-calculator";
|
2025-11-04 22:09:44 -08:00
|
|
|
import { getBracketTemplate } from "~/lib/bracket-templates";
|
2025-11-03 13:16:37 -08:00
|
|
|
import { database } from "~/database/context";
|
|
|
|
|
import * as schema from "~/database/schema";
|
|
|
|
|
import { eq } from "drizzle-orm";
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
|
|
|
|
|
export async function loader({ params }: Route.LoaderArgs) {
|
|
|
|
|
const sportsSeason = await findSportsSeasonById(params.id);
|
|
|
|
|
|
|
|
|
|
if (!sportsSeason) {
|
|
|
|
|
throw new Response("Sports season not found", { status: 404 });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const event = await getScoringEventById(params.eventId);
|
|
|
|
|
|
|
|
|
|
if (!event) {
|
|
|
|
|
throw new Response("Event not found", { status: 404 });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (event.eventType !== "playoff_game") {
|
|
|
|
|
throw new Response("This event is not a playoff event", { status: 400 });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const participants = await findParticipantsBySportsSeasonId(params.id);
|
|
|
|
|
const matches = await findPlayoffMatchesByEventId(params.eventId);
|
|
|
|
|
|
|
|
|
|
// The matches already include participant relations from the model query
|
|
|
|
|
return {
|
|
|
|
|
sportsSeason: sportsSeason as typeof sportsSeason & {
|
|
|
|
|
sport: { id: string; name: string; type: string; slug: string };
|
|
|
|
|
},
|
|
|
|
|
event,
|
|
|
|
|
participants,
|
|
|
|
|
matches: matches as Array<typeof matches[0] & {
|
|
|
|
|
participant1: { id: string; name: string } | null;
|
|
|
|
|
participant2: { id: string; name: string } | null;
|
|
|
|
|
winner: { id: string; name: string } | null;
|
|
|
|
|
loser: { id: string; name: string } | null;
|
|
|
|
|
}>,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export async function action({ request, params }: Route.ActionArgs) {
|
|
|
|
|
const formData = await request.formData();
|
|
|
|
|
const intent = formData.get("intent");
|
|
|
|
|
|
|
|
|
|
if (intent === "generate-bracket") {
|
2025-11-04 22:09:44 -08:00
|
|
|
const templateId = formData.get("templateId");
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
|
2025-11-04 22:09:44 -08:00
|
|
|
if (typeof templateId !== "string" || !templateId) {
|
|
|
|
|
return { error: "Template ID is required" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const template = getBracketTemplate(templateId);
|
|
|
|
|
if (!template) {
|
|
|
|
|
return { error: "Invalid bracket template" };
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const participantIds: string[] = [];
|
|
|
|
|
|
2025-11-04 22:09:44 -08:00
|
|
|
for (let i = 0; i < template.totalTeams; i++) {
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
const participantId = formData.get(`participant${i}`);
|
|
|
|
|
if (typeof participantId !== "string" || !participantId) {
|
|
|
|
|
return { error: `Participant ${i + 1} is required` };
|
|
|
|
|
}
|
|
|
|
|
participantIds.push(participantId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Check for duplicates
|
|
|
|
|
const uniqueParticipants = new Set(participantIds);
|
|
|
|
|
if (uniqueParticipants.size !== participantIds.length) {
|
|
|
|
|
return { error: "Each participant can only be selected once" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
2025-11-04 22:09:44 -08:00
|
|
|
await generateBracketFromTemplate(params.eventId, templateId, participantIds);
|
|
|
|
|
|
|
|
|
|
// Update the event to store the template ID and scoring start round
|
|
|
|
|
await updateScoringEvent(params.eventId, {
|
|
|
|
|
bracketTemplateId: templateId,
|
|
|
|
|
scoringStartsAtRound: template.scoringStartsAtRound,
|
|
|
|
|
});
|
|
|
|
|
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
return { success: "Bracket generated successfully" };
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error generating bracket:", error);
|
|
|
|
|
return {
|
|
|
|
|
error:
|
|
|
|
|
error instanceof Error
|
|
|
|
|
? error.message
|
|
|
|
|
: "Failed to generate bracket",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (intent === "set-winner") {
|
|
|
|
|
const matchId = formData.get("matchId");
|
|
|
|
|
const winnerId = formData.get("winnerId");
|
|
|
|
|
|
|
|
|
|
if (typeof matchId !== "string" || !matchId) {
|
|
|
|
|
return { error: "Match ID is required" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (typeof winnerId !== "string" || !winnerId) {
|
|
|
|
|
return { error: "Winner ID is required" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const match = await findPlayoffMatchById(matchId);
|
|
|
|
|
if (!match) {
|
|
|
|
|
return { error: "Match not found" };
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-04 22:09:44 -08:00
|
|
|
// Get the event to determine the template
|
|
|
|
|
const event = await getScoringEventById(match.scoringEventId);
|
|
|
|
|
if (!event) {
|
|
|
|
|
return { error: "Event not found" };
|
|
|
|
|
}
|
|
|
|
|
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
// Determine loser
|
|
|
|
|
const loserId =
|
|
|
|
|
match.participant1Id === winnerId
|
|
|
|
|
? match.participant2Id
|
|
|
|
|
: match.participant1Id;
|
|
|
|
|
|
|
|
|
|
if (!loserId) {
|
|
|
|
|
return { error: "Could not determine loser" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set the winner
|
|
|
|
|
await setMatchWinner(matchId, winnerId, loserId);
|
|
|
|
|
|
2025-11-04 22:09:44 -08:00
|
|
|
// Try to advance the winner to the next round using template
|
|
|
|
|
if (event.bracketTemplateId) {
|
|
|
|
|
const template = getBracketTemplate(event.bracketTemplateId);
|
|
|
|
|
if (template) {
|
|
|
|
|
try {
|
|
|
|
|
await advanceWinnerTemplate(matchId, winnerId, template);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
// Only ignore "already filled" errors, re-throw unexpected errors
|
|
|
|
|
if (
|
|
|
|
|
error instanceof Error &&
|
|
|
|
|
error.message.includes("already filled")
|
|
|
|
|
) {
|
|
|
|
|
console.warn("Match already filled, skipping advancement");
|
|
|
|
|
} else {
|
|
|
|
|
throw error; // Re-throw unexpected errors
|
|
|
|
|
}
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { success: "Winner set successfully" };
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error setting winner:", error);
|
|
|
|
|
return {
|
|
|
|
|
error:
|
|
|
|
|
error instanceof Error ? error.message : "Failed to set winner",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-11-04 22:09:44 -08:00
|
|
|
if (intent === "set-round-winners") {
|
|
|
|
|
const round = formData.get("round");
|
|
|
|
|
|
|
|
|
|
if (typeof round !== "string" || !round) {
|
|
|
|
|
return { error: "Round is required" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Get all winner assignments from form data
|
|
|
|
|
const winnerAssignments: Array<{ matchId: string; winnerId: string }> = [];
|
|
|
|
|
|
|
|
|
|
for (const [key, value] of formData.entries()) {
|
|
|
|
|
if (key.startsWith("winner-") && typeof value === "string") {
|
|
|
|
|
const matchId = key.replace("winner-", "");
|
|
|
|
|
winnerAssignments.push({ matchId, winnerId: value });
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (winnerAssignments.length === 0) {
|
|
|
|
|
return { error: "No winners selected" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the event to determine the template
|
|
|
|
|
const event = await getScoringEventById(params.eventId);
|
|
|
|
|
if (!event) {
|
|
|
|
|
return { error: "Event not found" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const template = event.bracketTemplateId ? getBracketTemplate(event.bracketTemplateId) : null;
|
|
|
|
|
|
|
|
|
|
// Process each winner assignment
|
|
|
|
|
let successCount = 0;
|
|
|
|
|
const errors: string[] = [];
|
|
|
|
|
|
|
|
|
|
for (const { matchId, winnerId } of winnerAssignments) {
|
|
|
|
|
try {
|
|
|
|
|
const match = await findPlayoffMatchById(matchId);
|
|
|
|
|
if (!match) {
|
|
|
|
|
errors.push(`Match ${matchId} not found`);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Determine loser
|
|
|
|
|
const loserId =
|
|
|
|
|
match.participant1Id === winnerId
|
|
|
|
|
? match.participant2Id
|
|
|
|
|
: match.participant1Id;
|
|
|
|
|
|
|
|
|
|
if (!loserId) {
|
|
|
|
|
errors.push(`Could not determine loser for match ${match.matchNumber}`);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Set the winner
|
|
|
|
|
await setMatchWinner(matchId, winnerId, loserId);
|
|
|
|
|
|
|
|
|
|
// Try to advance the winner to the next round using template
|
|
|
|
|
if (template) {
|
|
|
|
|
try {
|
|
|
|
|
await advanceWinnerTemplate(matchId, winnerId, template);
|
|
|
|
|
} catch (error) {
|
|
|
|
|
// Only ignore "already filled" errors
|
|
|
|
|
if (
|
|
|
|
|
error instanceof Error &&
|
|
|
|
|
error.message.includes("already filled")
|
|
|
|
|
) {
|
|
|
|
|
console.warn("Match already filled, skipping advancement");
|
|
|
|
|
} else {
|
|
|
|
|
throw error;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
successCount++;
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error(`Error setting winner for match ${matchId}:`, error);
|
|
|
|
|
errors.push(
|
|
|
|
|
`Match ${matchId}: ${error instanceof Error ? error.message : "Unknown error"}`
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (errors.length > 0 && successCount === 0) {
|
|
|
|
|
return { error: `Failed to set winners: ${errors.join(", ")}` };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (errors.length > 0) {
|
|
|
|
|
return {
|
|
|
|
|
success: `Set ${successCount} winner(s) successfully`,
|
|
|
|
|
error: `Some errors occurred: ${errors.join(", ")}`,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { success: `Successfully set ${successCount} winner(s) for ${round}` };
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error setting round winners:", error);
|
|
|
|
|
return {
|
|
|
|
|
error:
|
|
|
|
|
error instanceof Error ? error.message : "Failed to set winners",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
if (intent === "complete-round") {
|
|
|
|
|
const round = formData.get("round");
|
|
|
|
|
|
2025-11-04 22:09:44 -08:00
|
|
|
if (typeof round !== "string" || !round) {
|
|
|
|
|
return { error: "Round is required" };
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Get the event and update playoffRound to the completed round
|
|
|
|
|
const event = await getScoringEventById(params.eventId);
|
|
|
|
|
if (!event) {
|
|
|
|
|
return { error: "Event not found" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Verify all matches in this round are complete
|
|
|
|
|
const matches = await findPlayoffMatchesByEventId(params.eventId);
|
2025-11-04 22:09:44 -08:00
|
|
|
|
|
|
|
|
// Validate that the round exists in this event's matches
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
const roundMatches = matches.filter((m) => m.round === round);
|
2025-11-04 22:09:44 -08:00
|
|
|
if (roundMatches.length === 0) {
|
|
|
|
|
return { error: `Round "${round}" not found in this bracket` };
|
|
|
|
|
}
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
|
|
|
|
|
const allComplete = roundMatches.every((m) => m.isComplete);
|
|
|
|
|
if (!allComplete) {
|
|
|
|
|
return { error: `Not all matches in ${round} are complete` };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Validate round order: ensure previous rounds are complete
|
|
|
|
|
const { findParticipantResultsBySportsSeasonId } = await import(
|
|
|
|
|
"~/models/participant-result"
|
|
|
|
|
);
|
|
|
|
|
const existingResults = await findParticipantResultsBySportsSeasonId(
|
|
|
|
|
params.id
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (round === "Finals") {
|
|
|
|
|
// Finals requires Semifinals to be complete (3rd/4th place results exist)
|
|
|
|
|
const hasSemifinalResults = existingResults.some(
|
|
|
|
|
(r) => r.finalPosition === 3 || r.finalPosition === 4
|
|
|
|
|
);
|
|
|
|
|
if (!hasSemifinalResults) {
|
|
|
|
|
return {
|
|
|
|
|
error:
|
|
|
|
|
"Semifinals must be completed before Finals (no 3rd/4th place results found)",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
} else if (round === "Semifinals") {
|
|
|
|
|
// Semifinals requires Quarterfinals to be complete if QF matches exist
|
|
|
|
|
const hasQuarterfinals = matches.some((m) => m.round === "Quarterfinals");
|
|
|
|
|
if (hasQuarterfinals) {
|
|
|
|
|
const hasQuarterfinalsResults = existingResults.some(
|
|
|
|
|
(r) =>
|
|
|
|
|
r.finalPosition === 5 ||
|
|
|
|
|
r.finalPosition === 6 ||
|
|
|
|
|
r.finalPosition === 7 ||
|
|
|
|
|
r.finalPosition === 8
|
|
|
|
|
);
|
|
|
|
|
if (!hasQuarterfinalsResults) {
|
|
|
|
|
return {
|
|
|
|
|
error:
|
|
|
|
|
"Quarterfinals must be completed before Semifinals (no 5th-8th place results found)",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Get the sports season to find a fantasy season for scoring rules
|
|
|
|
|
const sportsSeason = await findSportsSeasonById(params.id);
|
|
|
|
|
if (!sportsSeason) {
|
|
|
|
|
return { error: "Sports season not found" };
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Process the playoff event to calculate placements
|
2025-11-03 13:16:37 -08:00
|
|
|
// TODO Phase 2.7: Refactor processPlayoffEvent to use template system
|
|
|
|
|
// For now, we still need to set playoffRound for the old scoring logic
|
|
|
|
|
// even though we removed it from the create event UI
|
|
|
|
|
const db = database();
|
|
|
|
|
await db
|
|
|
|
|
.update(schema.scoringEvents)
|
|
|
|
|
.set({ playoffRound: round, updatedAt: new Date() })
|
|
|
|
|
.where(eq(schema.scoringEvents.id, params.eventId));
|
feat: Implement bracket expansion plan to support various tournament structures
- Added a comprehensive plan for bracket expansion, including support for 4, 8, 16, 32, and 68 team formats.
- Introduced a template-based bracket system with predefined templates for NCAA March Madness, NFL Playoffs, NBA Playoffs, and simple brackets.
- Updated UI flow for bracket creation, allowing admins to select templates and assign participants flexibly.
- Enhanced database schema to accommodate new scoring rules and bracket templates.
- Proposed updates to scoring logic to handle non-scoring rounds and participant placements correctly.
- Documented implementation phases for gradual rollout of new features.
- Addressed critical bugs in the playoff event processing and scoring logic, ensuring proper advancement and scoring rules across multiple leagues.
2025-11-03 09:36:16 -08:00
|
|
|
|
|
|
|
|
// Get a fantasy season ID for scoring calculation
|
|
|
|
|
const { findSeasonSportsBySportsSeasonId } = await import(
|
|
|
|
|
"~/models/season-sport"
|
|
|
|
|
);
|
|
|
|
|
const seasonSports = await findSeasonSportsBySportsSeasonId(params.id);
|
|
|
|
|
if (seasonSports.length === 0) {
|
|
|
|
|
return {
|
|
|
|
|
error: "No fantasy seasons found for this sports season",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Process playoff event to update participant results
|
|
|
|
|
await processPlayoffEvent(params.eventId);
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
success: `${round} completed and placements calculated successfully`,
|
|
|
|
|
};
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.error("Error completing round:", error);
|
|
|
|
|
return {
|
|
|
|
|
error:
|
|
|
|
|
error instanceof Error ? error.message : "Failed to complete round",
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return { error: "Invalid action" };
|
|
|
|
|
}
|