Files
gridpilot.gg/apps/website/app/api/leagues/schedule-preview/route.ts
2025-12-10 18:28:32 +01:00

100 lines
2.5 KiB
TypeScript

import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import {
type LeagueScheduleDTO,
type LeagueSchedulePreviewDTO,
} from '@gridpilot/racing/application';
import { getPreviewLeagueScheduleUseCase } from '@/lib/di-container';
import { LeagueSchedulePreviewPresenter } from '@/lib/presenters/LeagueSchedulePreviewPresenter';
interface RequestBody {
seasonStartDate?: string;
raceStartTime?: string;
timezoneId?: string;
recurrenceStrategy?: LeagueScheduleDTO['recurrenceStrategy'];
intervalWeeks?: number;
weekdays?: LeagueScheduleDTO['weekdays'];
monthlyOrdinal?: LeagueScheduleDTO['monthlyOrdinal'];
monthlyWeekday?: LeagueScheduleDTO['monthlyWeekday'];
plannedRounds?: number;
}
function toLeagueScheduleDTO(body: RequestBody): LeagueScheduleDTO {
const {
seasonStartDate,
raceStartTime,
timezoneId,
recurrenceStrategy,
intervalWeeks,
weekdays,
monthlyOrdinal,
monthlyWeekday,
plannedRounds,
} = body;
if (
!seasonStartDate ||
!raceStartTime ||
!timezoneId ||
!recurrenceStrategy ||
plannedRounds == null
) {
throw new Error(
'seasonStartDate, raceStartTime, timezoneId, recurrenceStrategy, and plannedRounds are required',
);
}
const dto: LeagueScheduleDTO = {
seasonStartDate,
raceStartTime,
timezoneId,
recurrenceStrategy,
plannedRounds,
};
if (intervalWeeks != null) {
dto.intervalWeeks = intervalWeeks;
}
if (weekdays && weekdays.length > 0) {
dto.weekdays = weekdays;
}
if (monthlyOrdinal != null) {
dto.monthlyOrdinal = monthlyOrdinal;
}
if (monthlyWeekday != null) {
dto.monthlyWeekday = monthlyWeekday;
}
return dto;
}
export async function POST(request: NextRequest) {
try {
const json = (await request.json()) as RequestBody;
const schedule = toLeagueScheduleDTO(json);
const presenter = new LeagueSchedulePreviewPresenter();
const useCase = getPreviewLeagueScheduleUseCase();
useCase.execute({
schedule,
maxRounds: 10,
});
const preview = presenter.getData();
if (!preview) {
return NextResponse.json({ error: 'Failed to generate preview' }, { status: 500 });
}
return NextResponse.json(preview, { status: 200 });
} catch (error) {
const message =
error instanceof Error ? error.message : 'Failed to preview schedule';
return NextResponse.json(
{
error: message,
},
{ status: 400 },
);
}
}