wip league admin tools

This commit is contained in:
2025-12-28 12:04:12 +01:00
parent 5dc8c2399c
commit 6edf12fda8
401 changed files with 15365 additions and 6047 deletions

View File

@@ -11,6 +11,17 @@ import type { RaceDTO } from '../../types/generated/RaceDTO';
import type { GetLeagueAdminConfigOutputDTO } from '../../types/generated/GetLeagueAdminConfigOutputDTO';
import type { LeagueScoringPresetDTO } from '../../types/generated/LeagueScoringPresetDTO';
import type { LeagueSeasonSummaryDTO } from '../../types/generated/LeagueSeasonSummaryDTO';
import type { CreateLeagueScheduleRaceInputDTO } from '../../types/generated/CreateLeagueScheduleRaceInputDTO';
import type { CreateLeagueScheduleRaceOutputDTO } from '../../types/generated/CreateLeagueScheduleRaceOutputDTO';
import type { UpdateLeagueScheduleRaceInputDTO } from '../../types/generated/UpdateLeagueScheduleRaceInputDTO';
import type { LeagueScheduleRaceMutationSuccessDTO } from '../../types/generated/LeagueScheduleRaceMutationSuccessDTO';
import type { LeagueSeasonSchedulePublishOutputDTO } from '../../types/generated/LeagueSeasonSchedulePublishOutputDTO';
import type { LeagueRosterMemberDTO } from '../../types/generated/LeagueRosterMemberDTO';
import type { LeagueRosterJoinRequestDTO } from '../../types/generated/LeagueRosterJoinRequestDTO';
import type { ApproveJoinRequestOutputDTO } from '../../types/generated/ApproveJoinRequestOutputDTO';
import type { RejectJoinRequestOutputDTO } from '../../types/generated/RejectJoinRequestOutputDTO';
import type { UpdateLeagueMemberRoleOutputDTO } from '../../types/generated/UpdateLeagueMemberRoleOutputDTO';
import type { RemoveLeagueMemberOutputDTO } from '../../types/generated/RemoveLeagueMemberOutputDTO';
import type { AllLeaguesWithCapacityAndScoringDTO } from '../../types/AllLeaguesWithCapacityAndScoringDTO';
/**
@@ -40,8 +51,9 @@ export class LeaguesApiClient extends BaseApiClient {
}
/** Get league schedule */
getSchedule(leagueId: string): Promise<LeagueScheduleDTO> {
return this.get<LeagueScheduleDTO>(`/leagues/${leagueId}/schedule`);
getSchedule(leagueId: string, seasonId?: string): Promise<LeagueScheduleDTO> {
const qs = seasonId ? `?seasonId=${encodeURIComponent(seasonId)}` : '';
return this.get<LeagueScheduleDTO>(`/leagues/${leagueId}/schedule${qs}`);
}
/** Get league memberships */
@@ -92,8 +104,78 @@ export class LeaguesApiClient extends BaseApiClient {
});
}
/** Publish a league season schedule (admin/owner only; actor derived from session) */
publishSeasonSchedule(leagueId: string, seasonId: string): Promise<LeagueSeasonSchedulePublishOutputDTO> {
return this.post<LeagueSeasonSchedulePublishOutputDTO>(`/leagues/${leagueId}/seasons/${seasonId}/schedule/publish`, {});
}
/** Unpublish a league season schedule (admin/owner only; actor derived from session) */
unpublishSeasonSchedule(leagueId: string, seasonId: string): Promise<LeagueSeasonSchedulePublishOutputDTO> {
return this.post<LeagueSeasonSchedulePublishOutputDTO>(`/leagues/${leagueId}/seasons/${seasonId}/schedule/unpublish`, {});
}
/** Create a schedule race for a league season (admin/owner only; actor derived from session) */
createSeasonScheduleRace(
leagueId: string,
seasonId: string,
input: CreateLeagueScheduleRaceInputDTO,
): Promise<CreateLeagueScheduleRaceOutputDTO> {
const { example: _example, ...payload } = input;
return this.post<CreateLeagueScheduleRaceOutputDTO>(`/leagues/${leagueId}/seasons/${seasonId}/schedule/races`, payload);
}
/** Update a schedule race for a league season (admin/owner only; actor derived from session) */
updateSeasonScheduleRace(
leagueId: string,
seasonId: string,
raceId: string,
input: UpdateLeagueScheduleRaceInputDTO,
): Promise<LeagueScheduleRaceMutationSuccessDTO> {
const { example: _example, ...payload } = input;
return this.patch<LeagueScheduleRaceMutationSuccessDTO>(`/leagues/${leagueId}/seasons/${seasonId}/schedule/races/${raceId}`, payload);
}
/** Delete a schedule race for a league season (admin/owner only; actor derived from session) */
deleteSeasonScheduleRace(
leagueId: string,
seasonId: string,
raceId: string,
): Promise<LeagueScheduleRaceMutationSuccessDTO> {
return this.delete<LeagueScheduleRaceMutationSuccessDTO>(`/leagues/${leagueId}/seasons/${seasonId}/schedule/races/${raceId}`);
}
/** Get races for a league */
getRaces(leagueId: string): Promise<{ races: RaceDTO[] }> {
return this.get<{ races: RaceDTO[] }>(`/leagues/${leagueId}/races`);
}
/** Admin roster: list current members (admin/owner only; actor derived from session) */
getAdminRosterMembers(leagueId: string): Promise<LeagueRosterMemberDTO[]> {
return this.get<LeagueRosterMemberDTO[]>(`/leagues/${leagueId}/admin/roster/members`);
}
/** Admin roster: list pending join requests (admin/owner only; actor derived from session) */
getAdminRosterJoinRequests(leagueId: string): Promise<LeagueRosterJoinRequestDTO[]> {
return this.get<LeagueRosterJoinRequestDTO[]>(`/leagues/${leagueId}/admin/roster/join-requests`);
}
/** Admin roster: approve a join request (admin/owner only; actor derived from session) */
approveRosterJoinRequest(leagueId: string, joinRequestId: string): Promise<ApproveJoinRequestOutputDTO> {
return this.post<ApproveJoinRequestOutputDTO>(`/leagues/${leagueId}/admin/roster/join-requests/${joinRequestId}/approve`, {});
}
/** Admin roster: reject a join request (admin/owner only; actor derived from session) */
rejectRosterJoinRequest(leagueId: string, joinRequestId: string): Promise<RejectJoinRequestOutputDTO> {
return this.post<RejectJoinRequestOutputDTO>(`/leagues/${leagueId}/admin/roster/join-requests/${joinRequestId}/reject`, {});
}
/** Admin roster: update member role (admin/owner only; actor derived from session) */
updateRosterMemberRole(leagueId: string, targetDriverId: string, newRole: string): Promise<UpdateLeagueMemberRoleOutputDTO> {
return this.patch<UpdateLeagueMemberRoleOutputDTO>(`/leagues/${leagueId}/admin/roster/members/${targetDriverId}/role`, { newRole });
}
/** Admin roster: remove member (admin/owner only; actor derived from session) */
removeRosterMember(leagueId: string, targetDriverId: string): Promise<RemoveLeagueMemberOutputDTO> {
return this.patch<RemoveLeagueMemberOutputDTO>(`/leagues/${leagueId}/admin/roster/members/${targetDriverId}/remove`, {});
}
}

View File

@@ -55,7 +55,6 @@ export class ProtestDecisionCommandModel {
raceId,
driverId,
stewardId,
enum: this.penaltyType,
type: this.penaltyType,
reason,
protestId,

View File

@@ -1,4 +1,4 @@
import { describe, it, expect, vi, Mocked } from 'vitest';
import { describe, it, expect, vi, Mocked, beforeEach, afterEach } from 'vitest';
import { LeagueService } from './LeagueService';
import { LeaguesApiClient } from '../../api/leagues/LeaguesApiClient';
import { LeagueStandingsViewModel } from '../../view-models/LeagueStandingsViewModel';
@@ -114,12 +114,19 @@ describe('LeagueService', () => {
});
describe('getLeagueSchedule', () => {
it('should call apiClient.getSchedule and return LeagueScheduleViewModel', async () => {
afterEach(() => {
vi.useRealTimers();
});
it('should call apiClient.getSchedule and return LeagueScheduleViewModel with Date parsing', async () => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2025-01-01T00:00:00Z'));
const leagueId = 'league-123';
const mockDto = {
races: [
{ id: 'race-1', name: 'Race One', date: new Date().toISOString() },
{ id: 'race-2', name: 'Race Two', date: new Date().toISOString() },
{ id: 'race-1', name: 'Race One', date: '2024-12-31T20:00:00Z' },
{ id: 'race-2', name: 'Race Two', date: '2025-01-02T20:00:00Z' },
],
} as any;
@@ -129,14 +136,51 @@ describe('LeagueService', () => {
expect(mockApiClient.getSchedule).toHaveBeenCalledWith(leagueId);
expect(result).toBeInstanceOf(LeagueScheduleViewModel);
expect(result.races).toEqual(mockDto.races);
expect(result.raceCount).toBe(2);
expect(result.races[0]!.scheduledAt).toBeInstanceOf(Date);
expect(result.races[0]!.isPast).toBe(true);
expect(result.races[1]!.isUpcoming).toBe(true);
});
it('should prefer scheduledAt over date and map optional fields/status', async () => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2025-01-01T00:00:00Z'));
const leagueId = 'league-123';
const mockDto = {
races: [
{
id: 'race-1',
name: 'Round 1',
date: '2025-01-02T20:00:00Z',
scheduledAt: '2025-01-03T20:00:00Z',
track: 'Monza',
car: 'GT3',
sessionType: 'race',
isRegistered: true,
status: 'scheduled',
},
],
} as any;
mockApiClient.getSchedule.mockResolvedValue(mockDto);
const result = await service.getLeagueSchedule(leagueId);
expect(result.races[0]!.scheduledAt.toISOString()).toBe('2025-01-03T20:00:00.000Z');
expect(result.races[0]!.track).toBe('Monza');
expect(result.races[0]!.car).toBe('GT3');
expect(result.races[0]!.sessionType).toBe('race');
expect(result.races[0]!.isRegistered).toBe(true);
expect(result.races[0]!.status).toBe('scheduled');
});
it('should handle empty races array', async () => {
const leagueId = 'league-123';
const mockDto = { races: [] };
mockApiClient.getSchedule.mockResolvedValue(mockDto);
mockApiClient.getSchedule.mockResolvedValue(mockDto as any);
const result = await service.getLeagueSchedule(leagueId);

View File

@@ -6,8 +6,10 @@ import { CreateLeagueInputDTO } from "@/lib/types/generated/CreateLeagueInputDTO
import { CreateLeagueOutputDTO } from "@/lib/types/generated/CreateLeagueOutputDTO";
import { LeagueWithCapacityDTO } from "@/lib/types/generated/LeagueWithCapacityDTO";
import { CreateLeagueViewModel } from "@/lib/view-models/CreateLeagueViewModel";
import { LeagueAdminScheduleViewModel } from "@/lib/view-models/LeagueAdminScheduleViewModel";
import { LeagueMembershipsViewModel } from "@/lib/view-models/LeagueMembershipsViewModel";
import { LeagueScheduleViewModel } from "@/lib/view-models/LeagueScheduleViewModel";
import { LeagueScheduleViewModel, type LeagueScheduleRaceViewModel } from "@/lib/view-models/LeagueScheduleViewModel";
import { LeagueSeasonSummaryViewModel } from "@/lib/view-models/LeagueSeasonSummaryViewModel";
import { LeagueStandingsViewModel } from "@/lib/view-models/LeagueStandingsViewModel";
import { LeagueStatsViewModel } from "@/lib/view-models/LeagueStatsViewModel";
import { LeagueSummaryViewModel } from "@/lib/view-models/LeagueSummaryViewModel";
@@ -15,12 +17,22 @@ import { RemoveMemberViewModel } from "@/lib/view-models/RemoveMemberViewModel";
import { LeaguePageDetailViewModel } from "@/lib/view-models/LeaguePageDetailViewModel";
import { LeagueDetailPageViewModel, SponsorInfo } from "@/lib/view-models/LeagueDetailPageViewModel";
import { RaceViewModel } from "@/lib/view-models/RaceViewModel";
import type { LeagueAdminRosterJoinRequestViewModel } from "@/lib/view-models/LeagueAdminRosterJoinRequestViewModel";
import type { LeagueAdminRosterMemberViewModel } from "@/lib/view-models/LeagueAdminRosterMemberViewModel";
import type { MembershipRole } from "@/lib/types/MembershipRole";
import type { LeagueRosterJoinRequestDTO } from "@/lib/types/generated/LeagueRosterJoinRequestDTO";
import { SubmitBlocker, ThrottleBlocker } from "@/lib/blockers";
import { RaceDTO } from "@/lib/types/generated/RaceDTO";
import type { RaceDTO } from "@/lib/types/generated/RaceDTO";
import { LeagueStatsDTO } from "@/lib/types/generated/LeagueStatsDTO";
import { LeagueScoringConfigDTO } from "@/lib/types/generated/LeagueScoringConfigDTO";
import type { LeagueMembership } from "@/lib/types/LeagueMembership";
import type { LeagueSeasonSummaryDTO } from '@/lib/types/generated/LeagueSeasonSummaryDTO';
import type { LeagueScheduleDTO } from '@/lib/types/generated/LeagueScheduleDTO';
import type { CreateLeagueScheduleRaceInputDTO } from '@/lib/types/generated/CreateLeagueScheduleRaceInputDTO';
import type { CreateLeagueScheduleRaceOutputDTO } from '@/lib/types/generated/CreateLeagueScheduleRaceOutputDTO';
import type { UpdateLeagueScheduleRaceInputDTO } from '@/lib/types/generated/UpdateLeagueScheduleRaceInputDTO';
import type { LeagueScheduleRaceMutationSuccessDTO } from '@/lib/types/generated/LeagueScheduleRaceMutationSuccessDTO';
import type { LeagueSeasonSchedulePublishOutputDTO } from '@/lib/types/generated/LeagueSeasonSchedulePublishOutputDTO';
/**
@@ -29,6 +41,58 @@ import type { LeagueSeasonSummaryDTO } from '@/lib/types/generated/LeagueSeasonS
* Orchestrates league operations by coordinating API calls and view model creation.
* All dependencies are injected via constructor.
*/
function parseIsoDate(value: string, fallback: Date): Date {
const parsed = new Date(value);
if (Number.isNaN(parsed.getTime())) return fallback;
return parsed;
}
function getBestEffortIsoDate(race: RaceDTO): string | undefined {
const anyRace = race as unknown as { scheduledAt?: unknown; date?: unknown };
if (typeof anyRace.scheduledAt === 'string') return anyRace.scheduledAt;
if (typeof anyRace.date === 'string') return anyRace.date;
return undefined;
}
function getOptionalStringField(race: RaceDTO, key: string): string | undefined {
const anyRace = race as unknown as Record<string, unknown>;
const value = anyRace[key];
return typeof value === 'string' ? value : undefined;
}
function getOptionalBooleanField(race: RaceDTO, key: string): boolean | undefined {
const anyRace = race as unknown as Record<string, unknown>;
const value = anyRace[key];
return typeof value === 'boolean' ? value : undefined;
}
function mapLeagueScheduleDtoToRaceViewModels(dto: LeagueScheduleDTO, now: Date = new Date()): LeagueScheduleRaceViewModel[] {
return dto.races.map((race) => {
const iso = getBestEffortIsoDate(race);
const scheduledAt = iso ? parseIsoDate(iso, new Date(0)) : new Date(0);
const isPast = scheduledAt.getTime() < now.getTime();
const isUpcoming = !isPast;
const status = getOptionalStringField(race, 'status') ?? (isPast ? 'completed' : 'scheduled');
return {
id: race.id,
name: race.name,
scheduledAt,
isPast,
isUpcoming,
status,
track: getOptionalStringField(race, 'track'),
car: getOptionalStringField(race, 'car'),
sessionType: getOptionalStringField(race, 'sessionType'),
isRegistered: getOptionalBooleanField(race, 'isRegistered'),
};
});
}
export class LeagueService {
private readonly submitBlocker = new SubmitBlocker();
private readonly throttle = new ThrottleBlocker(500);
@@ -103,10 +167,128 @@ export class LeagueService {
/**
* Get league schedule
*
* Service boundary: returns ViewModels only (no DTOs / mappers in UI).
*/
async getLeagueSchedule(leagueId: string): Promise<LeagueScheduleViewModel> {
const dto = await this.apiClient.getSchedule(leagueId);
return new LeagueScheduleViewModel(dto);
const races = mapLeagueScheduleDtoToRaceViewModels(dto);
return new LeagueScheduleViewModel(races);
}
/**
* Admin schedule editor API (ViewModel boundary)
*/
async getLeagueSeasonSummaries(leagueId: string): Promise<LeagueSeasonSummaryViewModel[]> {
const dtos = await this.apiClient.getSeasons(leagueId);
return dtos.map((dto) => new LeagueSeasonSummaryViewModel(dto));
}
async getAdminSchedule(leagueId: string, seasonId: string): Promise<LeagueAdminScheduleViewModel> {
const dto = await this.apiClient.getSchedule(leagueId, seasonId);
const races = mapLeagueScheduleDtoToRaceViewModels(dto);
return new LeagueAdminScheduleViewModel({
seasonId: dto.seasonId,
published: dto.published,
races,
});
}
async publishAdminSchedule(leagueId: string, seasonId: string): Promise<LeagueAdminScheduleViewModel> {
await this.apiClient.publishSeasonSchedule(leagueId, seasonId);
return this.getAdminSchedule(leagueId, seasonId);
}
async unpublishAdminSchedule(leagueId: string, seasonId: string): Promise<LeagueAdminScheduleViewModel> {
await this.apiClient.unpublishSeasonSchedule(leagueId, seasonId);
return this.getAdminSchedule(leagueId, seasonId);
}
async createAdminScheduleRace(
leagueId: string,
seasonId: string,
input: { track: string; car: string; scheduledAtIso: string },
): Promise<LeagueAdminScheduleViewModel> {
const payload: CreateLeagueScheduleRaceInputDTO = { ...input, example: '' };
await this.apiClient.createSeasonScheduleRace(leagueId, seasonId, payload);
return this.getAdminSchedule(leagueId, seasonId);
}
async updateAdminScheduleRace(
leagueId: string,
seasonId: string,
raceId: string,
input: Partial<{ track: string; car: string; scheduledAtIso: string }>,
): Promise<LeagueAdminScheduleViewModel> {
const payload: UpdateLeagueScheduleRaceInputDTO = { ...input, example: '' };
await this.apiClient.updateSeasonScheduleRace(leagueId, seasonId, raceId, payload);
return this.getAdminSchedule(leagueId, seasonId);
}
async deleteAdminScheduleRace(leagueId: string, seasonId: string, raceId: string): Promise<LeagueAdminScheduleViewModel> {
await this.apiClient.deleteSeasonScheduleRace(leagueId, seasonId, raceId);
return this.getAdminSchedule(leagueId, seasonId);
}
/**
* Legacy DTO methods (kept for existing callers)
*/
/**
* Get league schedule DTO (season-scoped)
*
* Admin UI uses the raw DTO so it can render `published` and do CRUD refreshes.
*/
async getLeagueScheduleDto(leagueId: string, seasonId: string): Promise<LeagueScheduleDTO> {
return this.apiClient.getSchedule(leagueId, seasonId);
}
/**
* Publish a league season schedule
*/
async publishLeagueSeasonSchedule(leagueId: string, seasonId: string): Promise<LeagueSeasonSchedulePublishOutputDTO> {
return this.apiClient.publishSeasonSchedule(leagueId, seasonId);
}
/**
* Unpublish a league season schedule
*/
async unpublishLeagueSeasonSchedule(leagueId: string, seasonId: string): Promise<LeagueSeasonSchedulePublishOutputDTO> {
return this.apiClient.unpublishSeasonSchedule(leagueId, seasonId);
}
/**
* Create a schedule race for a league season
*/
async createLeagueSeasonScheduleRace(
leagueId: string,
seasonId: string,
input: CreateLeagueScheduleRaceInputDTO,
): Promise<CreateLeagueScheduleRaceOutputDTO> {
return this.apiClient.createSeasonScheduleRace(leagueId, seasonId, input);
}
/**
* Update a schedule race for a league season
*/
async updateLeagueSeasonScheduleRace(
leagueId: string,
seasonId: string,
raceId: string,
input: UpdateLeagueScheduleRaceInputDTO,
): Promise<LeagueScheduleRaceMutationSuccessDTO> {
return this.apiClient.updateSeasonScheduleRace(leagueId, seasonId, raceId, input);
}
/**
* Delete a schedule race for a league season
*/
async deleteLeagueSeasonScheduleRace(
leagueId: string,
seasonId: string,
raceId: string,
): Promise<LeagueScheduleRaceMutationSuccessDTO> {
return this.apiClient.deleteSeasonScheduleRace(leagueId, seasonId, raceId);
}
/**
@@ -143,17 +325,83 @@ export class LeagueService {
/**
* Remove a member from league
*
* Overload:
* - Legacy: removeMember(leagueId, performerDriverId, targetDriverId)
* - Admin roster: removeMember(leagueId, targetDriverId) (actor derived from session)
*/
async removeMember(leagueId: string, performerDriverId: string, targetDriverId: string): Promise<RemoveMemberViewModel> {
const dto = await this.apiClient.removeMember(leagueId, performerDriverId, targetDriverId);
return new RemoveMemberViewModel(dto);
async removeMember(leagueId: string, targetDriverId: string): Promise<{ success: boolean }>;
async removeMember(leagueId: string, performerDriverId: string, targetDriverId: string): Promise<RemoveMemberViewModel>;
async removeMember(leagueId: string, arg1: string, arg2?: string): Promise<{ success: boolean } | RemoveMemberViewModel> {
if (arg2 === undefined) {
const dto = await this.apiClient.removeRosterMember(leagueId, arg1);
return { success: dto.success };
}
const dto = await this.apiClient.removeMember(leagueId, arg1, arg2);
return new RemoveMemberViewModel(dto as any);
}
/**
* Update a member's role in league
*
* Overload:
* - Legacy: updateMemberRole(leagueId, performerDriverId, targetDriverId, newRole)
* - Admin roster: updateMemberRole(leagueId, targetDriverId, newRole) (actor derived from session)
*/
async updateMemberRole(leagueId: string, performerDriverId: string, targetDriverId: string, newRole: string): Promise<{ success: boolean }> {
return this.apiClient.updateMemberRole(leagueId, performerDriverId, targetDriverId, newRole);
async updateMemberRole(leagueId: string, targetDriverId: string, newRole: MembershipRole): Promise<{ success: boolean }>;
async updateMemberRole(leagueId: string, performerDriverId: string, targetDriverId: string, newRole: string): Promise<{ success: boolean }>;
async updateMemberRole(leagueId: string, arg1: string, arg2: string, arg3?: string): Promise<{ success: boolean }> {
if (arg3 === undefined) {
const dto = await this.apiClient.updateRosterMemberRole(leagueId, arg1, arg2);
return { success: dto.success };
}
return this.apiClient.updateMemberRole(leagueId, arg1, arg2, arg3);
}
/**
* Admin roster: members list as ViewModels
*/
async getAdminRosterMembers(leagueId: string): Promise<LeagueAdminRosterMemberViewModel[]> {
const dtos = await this.apiClient.getAdminRosterMembers(leagueId);
return dtos.map((dto) => ({
driverId: dto.driverId,
driverName: dto.driver?.name ?? dto.driverId,
role: (dto.role as MembershipRole) ?? 'member',
joinedAtIso: dto.joinedAt,
}));
}
/**
* Admin roster: join requests list as ViewModels
*/
async getAdminRosterJoinRequests(leagueId: string): Promise<LeagueAdminRosterJoinRequestViewModel[]> {
const dtos = await this.apiClient.getAdminRosterJoinRequests(leagueId);
return dtos.map((dto) => ({
id: dto.id,
leagueId: dto.leagueId,
driverId: dto.driverId,
driverName: this.resolveJoinRequestDriverName(dto),
requestedAtIso: dto.requestedAt,
message: dto.message,
}));
}
async approveJoinRequest(leagueId: string, joinRequestId: string): Promise<{ success: boolean }> {
const dto = await this.apiClient.approveRosterJoinRequest(leagueId, joinRequestId);
return { success: dto.success };
}
async rejectJoinRequest(leagueId: string, joinRequestId: string): Promise<{ success: boolean }> {
const dto = await this.apiClient.rejectRosterJoinRequest(leagueId, joinRequestId);
return { success: dto.success };
}
private resolveJoinRequestDriverName(dto: LeagueRosterJoinRequestDTO): string {
const driver = dto.driver as any;
const name = driver && typeof driver === 'object' ? (driver.name as string | undefined) : undefined;
return name ?? dto.driverId;
}
/**

View File

@@ -22,10 +22,12 @@ describe('LeagueStewardingService', () => {
mockProtestService = {
findByRaceId: vi.fn(),
getProtestById: vi.fn(),
} as Mocked<ProtestService>;
mockPenaltyService = {
findByRaceId: vi.fn(),
getPenaltyTypesReference: vi.fn(),
} as Mocked<PenaltyService>;
mockDriverService = {
@@ -144,4 +146,35 @@ describe('LeagueStewardingService', () => {
expect(mockPenaltyService.applyPenalty).toHaveBeenCalledWith(input);
});
});
describe('getProtestDetailViewModel', () => {
it('should combine protest details + penalty types into a page-ready view model', async () => {
const leagueId = 'league-123';
const protestId = 'protest-1';
mockProtestService.getProtestById.mockResolvedValue({
protest: { id: protestId, raceId: 'race-1', protestingDriverId: 'd1', accusedDriverId: 'd2', status: 'pending', submittedAt: '2023-10-01T10:00:00Z', description: 'desc' } as any,
race: { id: 'race-1' } as any,
protestingDriver: { id: 'd1', name: 'Driver 1' } as any,
accusedDriver: { id: 'd2', name: 'Driver 2' } as any,
});
mockPenaltyService.getPenaltyTypesReference.mockResolvedValue({
penaltyTypes: [
{ type: 'time_penalty', requiresValue: true, valueKind: 'seconds' },
{ type: 'warning', requiresValue: false, valueKind: 'none' },
],
defaultReasons: { upheld: 'Upheld reason', dismissed: 'Dismissed reason' },
} as any);
const result = await service.getProtestDetailViewModel(leagueId, protestId);
expect(mockProtestService.getProtestById).toHaveBeenCalledWith(leagueId, protestId);
expect(mockPenaltyService.getPenaltyTypesReference).toHaveBeenCalled();
expect(result.protest.id).toBe(protestId);
expect(result.penaltyTypes.length).toBe(2);
expect(result.defaultReasons.upheld).toBe('Upheld reason');
expect(result.initialPenaltyType).toBe('time_penalty');
});
});
});

View File

@@ -4,6 +4,7 @@ import { PenaltyService } from '../penalties/PenaltyService';
import { DriverService } from '../drivers/DriverService';
import { LeagueMembershipService } from './LeagueMembershipService';
import { LeagueStewardingViewModel, RaceWithProtests } from '../../view-models/LeagueStewardingViewModel';
import type { ProtestDetailViewModel } from '../../view-models/ProtestDetailViewModel';
/**
* League Stewarding Service
@@ -12,6 +13,39 @@ import { LeagueStewardingViewModel, RaceWithProtests } from '../../view-models/L
* All dependencies are injected via constructor.
*/
export class LeagueStewardingService {
private getPenaltyValueLabel(valueKind: string): string {
switch (valueKind) {
case 'seconds':
return 'seconds';
case 'grid_positions':
return 'positions';
case 'points':
return 'points';
case 'races':
return 'races';
case 'none':
return '';
default:
return '';
}
}
private getFallbackDefaultPenaltyValue(valueKind: string): number {
switch (valueKind) {
case 'seconds':
return 5;
case 'grid_positions':
return 3;
case 'points':
return 5;
case 'races':
return 1;
case 'none':
return 0;
default:
return 0;
}
}
constructor(
private readonly raceService: RaceService,
private readonly protestService: ProtestService,
@@ -77,6 +111,58 @@ export class LeagueStewardingService {
return new LeagueStewardingViewModel(racesWithData, driverMap);
}
/**
* Get protest review details as a page-ready view model
*/
async getProtestDetailViewModel(leagueId: string, protestId: string): Promise<ProtestDetailViewModel> {
const [protestData, penaltyTypesReference] = await Promise.all([
this.protestService.getProtestById(leagueId, protestId),
this.penaltyService.getPenaltyTypesReference(),
]);
if (!protestData) {
throw new Error('Protest not found');
}
const penaltyUiDefaults: Record<string, { label: string; description: string; defaultValue: number }> = {
time_penalty: { label: 'Time Penalty', description: 'Add seconds to race result', defaultValue: 5 },
grid_penalty: { label: 'Grid Penalty', description: 'Grid positions for next race', defaultValue: 3 },
points_deduction: { label: 'Points Deduction', description: 'Deduct championship points', defaultValue: 5 },
disqualification: { label: 'Disqualification', description: 'Disqualify from race', defaultValue: 0 },
warning: { label: 'Warning', description: 'Official warning only', defaultValue: 0 },
license_points: { label: 'License Points', description: 'Safety rating penalty', defaultValue: 2 },
};
const penaltyTypes = (penaltyTypesReference?.penaltyTypes ?? []).map((ref: any) => {
const ui = penaltyUiDefaults[ref.type];
const valueLabel = this.getPenaltyValueLabel(String(ref.valueKind ?? 'none'));
const defaultValue = ui?.defaultValue ?? this.getFallbackDefaultPenaltyValue(String(ref.valueKind ?? 'none'));
return {
type: String(ref.type),
label: ui?.label ?? String(ref.type).replaceAll('_', ' '),
description: ui?.description ?? '',
requiresValue: Boolean(ref.requiresValue),
valueLabel,
defaultValue,
};
});
const timePenalty = penaltyTypes.find((p) => p.type === 'time_penalty');
const initial = timePenalty ?? penaltyTypes[0];
return {
protest: protestData.protest,
race: protestData.race,
protestingDriver: protestData.protestingDriver,
accusedDriver: protestData.accusedDriver,
penaltyTypes,
defaultReasons: penaltyTypesReference?.defaultReasons ?? { upheld: '', dismissed: '' },
initialPenaltyType: initial?.type ?? null,
initialPenaltyValue: initial?.defaultValue ?? 0,
};
}
/**
* Review a protest
*/

View File

@@ -0,0 +1,42 @@
import { describe, it, expect } from 'vitest';
import * as fs from 'fs/promises';
import * as path from 'path';
import { glob } from 'glob';
describe('Website boundary: pages/components must not import mappers or generated DTOs', () => {
it('rejects imports from mappers and types/generated', async () => {
const websiteRoot = path.resolve(__dirname, '../../..');
const candidates = await glob([
'app/leagues/[id]/schedule/**/*.{ts,tsx}',
'components/leagues/LeagueSchedule.tsx',
], {
cwd: websiteRoot,
absolute: true,
nodir: true,
ignore: ['**/*.test.*', '**/*.spec.*'],
});
const forbiddenImportRegex =
/^\s*import[\s\S]*from\s+['"][^'"]*(\/mappers\/|\/types\/generated\/)[^'"]*['"]/gm;
const offenders: Array<{ file: string; matches: string[] }> = [];
for (const file of candidates) {
const content = await fs.readFile(file, 'utf-8');
const matches = Array.from(content.matchAll(forbiddenImportRegex)).map((m) => m[0]).filter(Boolean);
if (matches.length > 0) {
offenders.push({
file: path.relative(websiteRoot, file),
matches,
});
}
}
expect(offenders, `Forbidden imports found:\n${offenders
.map((o) => `- ${o.file}\n${o.matches.map((m) => ` ${m}`).join('\n')}`)
.join('\n')}`).toEqual([]);
});
});

View File

@@ -0,0 +1,34 @@
import { describe, it, expect } from 'vitest';
import * as fs from 'fs/promises';
import * as path from 'path';
describe('Schedule boundary: view-model constructors must not depend on DTOs or mappers', () => {
it('rejects schedule ViewModels importing from mappers or types/generated', async () => {
const websiteRoot = path.resolve(__dirname, '../../..');
const viewModelFiles = [
'lib/view-models/LeagueScheduleViewModel.ts',
'lib/view-models/LeagueAdminScheduleViewModel.ts',
];
const forbiddenImportRegex =
/^\s*import[\s\S]*from\s+['"][^'"]*(\/mappers\/|\/types\/generated\/)[^'"]*['"]/gm;
const offenders: Array<{ file: string; matches: string[] }> = [];
for (const rel of viewModelFiles) {
const abs = path.join(websiteRoot, rel);
const content = await fs.readFile(abs, 'utf-8');
const matches = Array.from(content.matchAll(forbiddenImportRegex)).map((m) => m[0]).filter(Boolean);
if (matches.length > 0) {
offenders.push({ file: rel, matches });
}
}
expect(offenders, `Forbidden imports found:\n${offenders
.map((o) => `- ${o.file}\n${o.matches.map((m) => ` ${m}`).join('\n')}`)
.join('\n')}`).toEqual([]);
});
});

View File

@@ -0,0 +1,73 @@
import { describe, it, expect } from 'vitest';
import * as fs from 'fs/promises';
import * as path from 'path';
describe('Website boundary: pages must consume ViewModels only (no DTO imports)', () => {
it('rejects forbidden imports for specific pages', async () => {
const websiteRoot = path.resolve(__dirname, '../..');
const candidates = [
'app/races/[id]/page.tsx',
'app/leagues/[id]/stewarding/protests/[protestId]/page.tsx',
].map((p) => path.resolve(websiteRoot, p));
const forbiddenImportRegex =
/^\s*import[\s\S]*from\s+['"][^'"]*(\/mappers\/|\/lib\/types\/|\/types\/generated\/)[^'"]*['"]/gm;
const offenders: Array<{ file: string; matches: string[] }> = [];
for (const file of candidates) {
const content = await fs.readFile(file, 'utf-8');
const matches = Array.from(content.matchAll(forbiddenImportRegex))
.map((m) => m[0])
.filter(Boolean);
if (matches.length > 0) {
offenders.push({
file: path.relative(websiteRoot, file),
matches,
});
}
}
expect(
offenders,
`Forbidden imports found:\n${offenders
.map((o) => `- ${o.file}\n${o.matches.map((m) => ` ${m}`).join('\n')}`)
.join('\n')}`,
).toEqual([]);
});
it('rejects DTO identifier usage in these page modules', async () => {
const websiteRoot = path.resolve(__dirname, '../..');
const candidates = [
'app/races/[id]/page.tsx',
'app/leagues/[id]/stewarding/protests/[protestId]/page.tsx',
].map((p) => path.resolve(websiteRoot, p));
const dtoIdentifierRegex = /\b[A-Za-z0-9_]+DTO\b/g;
const offenders: Array<{ file: string; matches: string[] }> = [];
for (const file of candidates) {
const content = await fs.readFile(file, 'utf-8');
const matches = Array.from(content.matchAll(dtoIdentifierRegex)).map((m) => m[0]).filter(Boolean);
if (matches.length > 0) {
offenders.push({
file: path.relative(websiteRoot, file),
matches: Array.from(new Set(matches)).sort(),
});
}
}
expect(
offenders,
`DTO identifiers found:\n${offenders
.map((o) => `- ${o.file}\n${o.matches.map((m) => ` ${m}`).join('\n')}`)
.join('\n')}`,
).toEqual([]);
});
});

View File

@@ -162,7 +162,7 @@ describe('ProtestService', () => {
const input = {
protestId: 'protest-123',
stewardId: 'steward-456',
decision: 'upheld',
decision: 'uphold',
decisionNotes: 'Test notes',
};
@@ -170,10 +170,7 @@ describe('ProtestService', () => {
await service.reviewProtest(input);
expect(mockApiClient.reviewProtest).toHaveBeenCalledWith({
...input,
enum: 'uphold',
});
expect(mockApiClient.reviewProtest).toHaveBeenCalledWith(input);
});
});

View File

@@ -84,15 +84,13 @@ export class ProtestService {
* Review protest
*/
async reviewProtest(input: { protestId: string; stewardId: string; decision: string; decisionNotes: string }): Promise<void> {
const normalizedDecision = input.decision.toLowerCase();
const enumValue: ReviewProtestCommandDTO['enum'] =
normalizedDecision === 'uphold' || normalizedDecision === 'upheld' ? 'uphold' : 'dismiss';
const normalizedDecision =
input.decision.toLowerCase() === 'upheld' ? 'uphold' : input.decision.toLowerCase();
const command: ReviewProtestCommandDTO = {
protestId: input.protestId,
stewardId: input.stewardId,
enum: enumValue,
decision: input.decision,
decision: normalizedDecision,
decisionNotes: input.decisionNotes,
};

View File

@@ -4,6 +4,7 @@ import { RacesApiClient } from '../../api/races/RacesApiClient';
import { RaceDetailViewModel } from '../../view-models/RaceDetailViewModel';
import { RacesPageViewModel } from '../../view-models/RacesPageViewModel';
import { RaceStatsViewModel } from '../../view-models/RaceStatsViewModel';
import type { RaceDetailsViewModel } from '../../view-models/RaceDetailsViewModel';
describe('RaceService', () => {
let mockApiClient: Mocked<RacesApiClient>;
@@ -57,6 +58,38 @@ describe('RaceService', () => {
});
});
describe('getRaceDetails', () => {
it('should call apiClient.getDetail and return a ViewModel-shaped object (no DTOs)', async () => {
const raceId = 'race-123';
const driverId = 'driver-456';
const mockDto = {
race: {
id: raceId,
track: 'Test Track',
car: 'Test Car',
scheduledAt: '2023-12-31T20:00:00Z',
status: 'completed',
sessionType: 'race',
},
league: { id: 'league-1', name: 'Test League', description: 'Desc', settings: { maxDrivers: 32 } },
entryList: [],
registration: { isUserRegistered: true, canRegister: false },
userResult: null,
};
mockApiClient.getDetail.mockResolvedValue(mockDto as any);
const result: RaceDetailsViewModel = await service.getRaceDetails(raceId, driverId);
expect(mockApiClient.getDetail).toHaveBeenCalledWith(raceId, driverId);
expect(result.race?.id).toBe(raceId);
expect(result.league?.id).toBe('league-1');
expect(result.registration.isUserRegistered).toBe(true);
expect(result.canReopenRace).toBe(true);
});
});
describe('getRacesPageData', () => {
it('should call apiClient.getPageData and return RacesPageViewModel with transformed data', async () => {
const mockDto = {

View File

@@ -1,7 +1,10 @@
import { RacesApiClient } from '../../api/races/RacesApiClient';
import { RaceDetailEntryViewModel } from '../../view-models/RaceDetailEntryViewModel';
import { RaceDetailUserResultViewModel } from '../../view-models/RaceDetailUserResultViewModel';
import { RaceDetailViewModel } from '../../view-models/RaceDetailViewModel';
import { RacesPageViewModel } from '../../view-models/RacesPageViewModel';
import { RaceStatsViewModel } from '../../view-models/RaceStatsViewModel';
import type { RaceDetailsViewModel } from '../../view-models/RaceDetailsViewModel';
import type { FileProtestCommandDTO } from '../../types/generated/FileProtestCommandDTO';
import type { RaceStatsDTO } from '../../types/generated/RaceStatsDTO';
/**
@@ -26,6 +29,55 @@ export class RaceService {
return new RaceDetailViewModel(dto, driverId);
}
/**
* Get race details for pages/components (DTO-free shape)
*/
async getRaceDetails(
raceId: string,
driverId: string
): Promise<RaceDetailsViewModel> {
const dto: any = await this.apiClient.getDetail(raceId, driverId);
const raceDto: any = dto?.race ?? null;
const leagueDto: any = dto?.league ?? null;
const registrationDto: any = dto?.registration ?? {};
const isUserRegistered = Boolean(registrationDto.isUserRegistered ?? registrationDto.isRegistered ?? false);
const canRegister = Boolean(registrationDto.canRegister);
const status = String(raceDto?.status ?? '');
const canReopenRace = status === 'completed' || status === 'cancelled';
return {
race: raceDto
? {
id: String(raceDto.id ?? ''),
track: String(raceDto.track ?? ''),
car: String(raceDto.car ?? ''),
scheduledAt: String(raceDto.scheduledAt ?? ''),
status,
sessionType: String(raceDto.sessionType ?? ''),
}
: null,
league: leagueDto
? {
id: String(leagueDto.id ?? ''),
name: String(leagueDto.name ?? ''),
description: leagueDto.description ?? null,
settings: leagueDto.settings,
}
: null,
entryList: (dto?.entryList ?? []).map((entry: any) => new RaceDetailEntryViewModel(entry, driverId)),
registration: {
canRegister,
isUserRegistered,
},
userResult: dto?.userResult ? new RaceDetailUserResultViewModel(dto.userResult) : null,
canReopenRace,
error: dto?.error,
};
}
/**
* Get races page data with view model transformation
*/

View File

@@ -61,12 +61,19 @@ describe('Website Contract Consumption', () => {
for (const file of dtos) {
const content = await fs.readFile(path.join(generatedTypesDir, file), 'utf-8');
// Basic syntax validation
// `index.ts` is a generated barrel file (no interfaces).
if (file === 'index.ts') {
expect(content).toContain('export type {');
expect(content).toContain("from './");
continue;
}
// Basic syntax validation (DTO interfaces)
expect(content).toContain('export interface');
expect(content).toContain('{');
expect(content).toContain('}');
// Should not have common syntax errors
expect(content).not.toMatch(/interface\s+\w+\s*\{\s*\}/); // Empty interfaces
}

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface AcceptSponsorshipRequestInputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface ActivityItemDTO {

View File

@@ -1,12 +1,13 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { LeagueSummaryDTO } from './LeagueSummaryDTO';
import type { LeagueWithCapacityAndScoringDTO } from './LeagueWithCapacityAndScoringDTO';
export interface AllLeaguesWithCapacityAndScoringDTO {
leagues: LeagueSummaryDTO[];
leagues: LeagueWithCapacityAndScoringDTO[];
totalCount: number;
}

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { LeagueWithCapacityDTO } from './LeagueWithCapacityDTO';

View File

@@ -1,11 +1,12 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { AllRacesStatusFilterDTO } from './AllRacesStatusFilterDTO';
import type { AllRacesLeagueFilterDTO } from './AllRacesLeagueFilterDTO';
import type { AllRacesStatusFilterDTO } from './AllRacesStatusFilterDTO';
export interface AllRacesFilterOptionsDTO {
statuses: AllRacesStatusFilterDTO[];

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface AllRacesLeagueFilterDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface AllRacesListItemDTO {

View File

@@ -1,11 +1,12 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { AllRacesListItemDTO } from './AllRacesListItemDTO';
import type { AllRacesFilterOptionsDTO } from './AllRacesFilterOptionsDTO';
import type { AllRacesListItemDTO } from './AllRacesListItemDTO';
export interface AllRacesPageDTO {
races: AllRacesListItemDTO[];

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface AllRacesStatusFilterDTO {

View File

@@ -1,14 +1,14 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface ApplyPenaltyCommandDTO {
raceId: string;
driverId: string;
stewardId: string;
enum: string;
type: string;
value?: number;
reason: string;

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface ApproveJoinRequestInputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface ApproveJoinRequestOutputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { AuthenticatedUserDTO } from './AuthenticatedUserDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface AuthenticatedUserDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface AvailableLeagueDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface AvatarDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { PrizeDTO } from './PrizeDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface BillingStatsDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface CompleteOnboardingInputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface CompleteOnboardingOutputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface CreateLeagueInputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface CreateLeagueOutputDTO {

View File

@@ -0,0 +1,13 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface CreateLeagueScheduleRaceInputDTO {
track: string;
car: string;
example: string;
scheduledAtIso: string;
}

View File

@@ -0,0 +1,10 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface CreateLeagueScheduleRaceOutputDTO {
raceId: string;
}

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface CreatePaymentInputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { PaymentDTO } from './PaymentDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { PrizeDTO } from './PrizeDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface CreateSponsorInputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { SponsorDTO } from './SponsorDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface CreateTeamInputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface CreateTeamOutputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DashboardDriverSummaryDTO {

View File

@@ -1,12 +1,12 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DashboardFeedItemSummaryDTO {
id: string;
enum: string;
type: string;
headline: string;
body?: string;

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { DashboardFeedItemSummaryDTO } from './DashboardFeedItemSummaryDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DashboardFriendSummaryDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DashboardLeagueStandingSummaryDTO {

View File

@@ -1,15 +1,16 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { DashboardDriverSummaryDTO } from './DashboardDriverSummaryDTO';
import type { DashboardRaceSummaryDTO } from './DashboardRaceSummaryDTO';
import type { DashboardRecentResultDTO } from './DashboardRecentResultDTO';
import type { DashboardLeagueStandingSummaryDTO } from './DashboardLeagueStandingSummaryDTO';
import type { DashboardFeedSummaryDTO } from './DashboardFeedSummaryDTO';
import type { DashboardFriendSummaryDTO } from './DashboardFriendSummaryDTO';
import type { DashboardLeagueStandingSummaryDTO } from './DashboardLeagueStandingSummaryDTO';
import type { DashboardRaceSummaryDTO } from './DashboardRaceSummaryDTO';
import type { DashboardRecentResultDTO } from './DashboardRecentResultDTO';
export interface DashboardOverviewDTO {
currentDriver?: DashboardDriverSummaryDTO;

View File

@@ -1,13 +1,14 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DashboardRaceSummaryDTO {
id: string;
leagueId: string;
leagueName: string;
leagueId?: string;
leagueName?: string;
track: string;
car: string;
scheduledAt: string;

View File

@@ -1,14 +1,15 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DashboardRecentResultDTO {
raceId: string;
raceName: string;
leagueId: string;
leagueName: string;
leagueId?: string;
leagueName?: string;
finishedAt: string;
position: number;
incidents: number;

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DeleteMediaOutputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DeletePrizeResultDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverLeaderboardItemDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverProfileAchievementDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverProfileDriverSummaryDTO {

View File

@@ -1,11 +1,12 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { DriverProfileSocialHandleDTO } from './DriverProfileSocialHandleDTO';
import type { DriverProfileAchievementDTO } from './DriverProfileAchievementDTO';
import type { DriverProfileSocialHandleDTO } from './DriverProfileSocialHandleDTO';
export interface DriverProfileExtendedProfileDTO {
socialHandles: DriverProfileSocialHandleDTO[];

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverProfileFinishDistributionDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverProfileSocialFriendSummaryDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverProfileSocialHandleDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { DriverProfileSocialFriendSummaryDTO } from './DriverProfileSocialFriendSummaryDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverProfileStatsDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverProfileTeamMembershipDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverRegistrationStatusDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverStatsDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface DriverSummaryDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { DriverLeaderboardItemDTO } from './DriverLeaderboardItemDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { ProtestIncidentDTO } from './ProtestIncidentDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface FullTransactionDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { TeamListItemDTO } from './TeamListItemDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetAnalyticsMetricsOutputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetAvatarOutputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetDashboardDataOutputDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetDriverOutputDTO {

View File

@@ -1,15 +1,16 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { DriverProfileDriverSummaryDTO } from './DriverProfileDriverSummaryDTO';
import type { DriverProfileStatsDTO } from './DriverProfileStatsDTO';
import type { DriverProfileFinishDistributionDTO } from './DriverProfileFinishDistributionDTO';
import type { DriverProfileTeamMembershipDTO } from './DriverProfileTeamMembershipDTO';
import type { DriverProfileSocialSummaryDTO } from './DriverProfileSocialSummaryDTO';
import type { DriverProfileExtendedProfileDTO } from './DriverProfileExtendedProfileDTO';
import type { DriverProfileFinishDistributionDTO } from './DriverProfileFinishDistributionDTO';
import type { DriverProfileSocialSummaryDTO } from './DriverProfileSocialSummaryDTO';
import type { DriverProfileStatsDTO } from './DriverProfileStatsDTO';
import type { DriverProfileTeamMembershipDTO } from './DriverProfileTeamMembershipDTO';
export interface GetDriverProfileOutputDTO {
currentDriver?: DriverProfileDriverSummaryDTO;

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetDriverRegistrationStatusQueryDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { TeamDTO } from './TeamDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { SponsorshipPricingItemDTO } from './SponsorshipPricingItemDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { LeagueConfigFormModelDTO } from './LeagueConfigFormModelDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetLeagueAdminConfigQueryDTO {

View File

@@ -1,10 +1,10 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetLeagueAdminPermissionsInputDTO {
leagueId: string;
performerDriverId: string;
}

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetLeagueJoinRequestsQueryDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetLeagueOwnerSummaryQueryDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetLeagueProtestsQueryDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { RaceDTO } from './RaceDTO';

View File

@@ -0,0 +1,10 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetLeagueScheduleQueryDTO {
seasonId?: string;
}

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetLeagueSeasonsQueryDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { WalletTransactionDTO } from './WalletTransactionDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetMediaOutputDTO {

View File

@@ -1,11 +1,12 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { MembershipFeeDTO } from './MembershipFeeDTO';
import type { MemberPaymentDTO } from './MemberPaymentDTO';
import type { MembershipFeeDTO } from './MembershipFeeDTO';
export interface GetMembershipFeesResultDTO {
fee?: MembershipFeeDTO;

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { SponsorshipRequestDTO } from './SponsorshipRequestDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { PrizeDTO } from './PrizeDTO';

View File

@@ -1,10 +1,11 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetRaceDetailParamsDTO {
raceId: string;
driverId: string;
driverId?: string;
}

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { SponsorshipDetailDTO } from './SponsorshipDetailDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetSponsorDashboardQueryParamsDTO {

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
import type { SponsorDTO } from './SponsorDTO';

View File

@@ -1,7 +1,8 @@
/**
* Auto-generated DTO from OpenAPI spec
* Spec SHA256: 16aae91ec085d450f377d8c914d93df23e86783b2b124fedd1075307d2c5b17f
* This file is generated by scripts/generate-api-types.ts
* Do not edit manually - regenerate using: npm run api:sync-types
* Do not edit manually - regenerate using: npm run api:generate-types
*/
export interface GetSponsorSponsorshipsQueryParamsDTO {

Some files were not shown because too many files have changed in this diff Show More