202 lines
8.8 KiB
TypeScript
202 lines
8.8 KiB
TypeScript
import { LeaguesApiClient } from "@/lib/api/leagues/LeaguesApiClient";
|
|
import { DriversApiClient } from "@/lib/api/drivers/DriversApiClient";
|
|
import { SponsorsApiClient } from "@/lib/api/sponsors/SponsorsApiClient";
|
|
import { RacesApiClient } from "@/lib/api/races/RacesApiClient";
|
|
import { CreateLeagueInputDTO } from "@/lib/types/generated/CreateLeagueInputDTO";
|
|
import { CreateLeagueOutputDTO } from "@/lib/types/generated/CreateLeagueOutputDTO";
|
|
import type { MembershipRole } from "@/lib/types/MembershipRole";
|
|
import type { LeagueRosterJoinRequestDTO } from "@/lib/types/generated/LeagueRosterJoinRequestDTO";
|
|
import type { TotalLeaguesDTO } from '@/lib/types/generated/TotalLeaguesDTO';
|
|
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';
|
|
import type { LeagueRosterMemberDTO } from '@/lib/types/generated/LeagueRosterMemberDTO';
|
|
import type { LeagueMembershipsDTO } from '@/lib/types/generated/LeagueMembershipsDTO';
|
|
import { Result } from '@/lib/contracts/Result';
|
|
import { DomainError, Service } from '@/lib/contracts/services/Service';
|
|
import { ConsoleLogger } from '@/lib/infrastructure/logging/ConsoleLogger';
|
|
import { EnhancedErrorReporter } from '@/lib/infrastructure/EnhancedErrorReporter';
|
|
import { getWebsiteApiBaseUrl } from '@/lib/config/apiBaseUrl';
|
|
import { getWebsiteServerEnv } from '@/lib/config/env';
|
|
import { AllLeaguesWithCapacityAndScoringDTO } from '@/lib/types/AllLeaguesWithCapacityAndScoringDTO';
|
|
|
|
/**
|
|
* League Service - DTO Only
|
|
*
|
|
* Returns Result<ApiDto, DomainError>. No ViewModels or UX logic.
|
|
* All client-side presentation logic must be handled by hooks/components.
|
|
* @server-safe
|
|
*/
|
|
export class LeagueService implements Service {
|
|
private apiClient: LeaguesApiClient;
|
|
private driversApiClient?: DriversApiClient;
|
|
private sponsorsApiClient?: SponsorsApiClient;
|
|
private racesApiClient?: RacesApiClient;
|
|
|
|
constructor() {
|
|
const baseUrl = getWebsiteApiBaseUrl();
|
|
const logger = new ConsoleLogger();
|
|
const { NODE_ENV } = getWebsiteServerEnv();
|
|
const errorReporter = new EnhancedErrorReporter(logger, {
|
|
showUserNotifications: false,
|
|
logToConsole: true,
|
|
reportToExternal: NODE_ENV === 'production',
|
|
});
|
|
this.apiClient = new LeaguesApiClient(baseUrl, errorReporter, logger);
|
|
// Optional clients can be initialized if needed
|
|
}
|
|
|
|
async getAllLeagues(): Promise<Result<AllLeaguesWithCapacityAndScoringDTO, DomainError>> {
|
|
try {
|
|
const dto = await this.apiClient.getAllWithCapacityAndScoring();
|
|
return Result.ok(dto);
|
|
} catch (error) {
|
|
console.error('LeagueService.getAllLeagues failed:', error);
|
|
return Result.err({ type: 'serverError', message: 'Failed to fetch leagues' });
|
|
}
|
|
}
|
|
|
|
async getLeagueStandings(): Promise<Result<never, DomainError>> {
|
|
return Result.err({ type: 'notImplemented', message: 'League standings endpoint not implemented' });
|
|
}
|
|
|
|
async getLeagueStats(): Promise<TotalLeaguesDTO> {
|
|
return this.apiClient.getTotal();
|
|
}
|
|
|
|
async getLeagueSchedule(leagueId: string): Promise<LeagueScheduleDTO> {
|
|
return this.apiClient.getSchedule(leagueId);
|
|
}
|
|
|
|
async getLeagueSeasons(leagueId: string): Promise<LeagueSeasonSummaryDTO[]> {
|
|
return this.apiClient.getSeasons(leagueId);
|
|
}
|
|
|
|
async getLeagueSeasonSummaries(leagueId: string): Promise<LeagueSeasonSummaryDTO[]> {
|
|
return this.apiClient.getSeasons(leagueId);
|
|
}
|
|
|
|
async getAdminSchedule(leagueId: string, seasonId: string): Promise<LeagueScheduleDTO> {
|
|
return this.apiClient.getSchedule(leagueId, seasonId);
|
|
}
|
|
|
|
async publishAdminSchedule(leagueId: string, seasonId: string): Promise<LeagueSeasonSchedulePublishOutputDTO> {
|
|
return this.apiClient.publishSeasonSchedule(leagueId, seasonId);
|
|
}
|
|
|
|
async unpublishAdminSchedule(leagueId: string, seasonId: string): Promise<LeagueSeasonSchedulePublishOutputDTO> {
|
|
return this.apiClient.unpublishSeasonSchedule(leagueId, seasonId);
|
|
}
|
|
|
|
async createAdminScheduleRace(
|
|
leagueId: string,
|
|
seasonId: string,
|
|
input: { track: string; car: string; scheduledAtIso: string },
|
|
): Promise<CreateLeagueScheduleRaceOutputDTO> {
|
|
const payload: CreateLeagueScheduleRaceInputDTO = { ...input, example: '' };
|
|
return this.apiClient.createSeasonScheduleRace(leagueId, seasonId, payload);
|
|
}
|
|
|
|
async updateAdminScheduleRace(
|
|
leagueId: string,
|
|
seasonId: string,
|
|
raceId: string,
|
|
input: Partial<{ track: string; car: string; scheduledAtIso: string }>,
|
|
): Promise<LeagueScheduleRaceMutationSuccessDTO> {
|
|
const payload: UpdateLeagueScheduleRaceInputDTO = { ...input, example: '' };
|
|
return this.apiClient.updateSeasonScheduleRace(leagueId, seasonId, raceId, payload);
|
|
}
|
|
|
|
async deleteAdminScheduleRace(leagueId: string, seasonId: string, raceId: string): Promise<LeagueScheduleRaceMutationSuccessDTO> {
|
|
return this.apiClient.deleteSeasonScheduleRace(leagueId, seasonId, raceId);
|
|
}
|
|
|
|
async getLeagueScheduleDto(leagueId: string, seasonId: string): Promise<LeagueScheduleDTO> {
|
|
return this.apiClient.getSchedule(leagueId, seasonId);
|
|
}
|
|
|
|
async publishLeagueSeasonSchedule(leagueId: string, seasonId: string): Promise<LeagueSeasonSchedulePublishOutputDTO> {
|
|
return this.apiClient.publishSeasonSchedule(leagueId, seasonId);
|
|
}
|
|
|
|
async unpublishLeagueSeasonSchedule(leagueId: string, seasonId: string): Promise<LeagueSeasonSchedulePublishOutputDTO> {
|
|
return this.apiClient.unpublishSeasonSchedule(leagueId, seasonId);
|
|
}
|
|
|
|
async createLeagueSeasonScheduleRace(
|
|
leagueId: string,
|
|
seasonId: string,
|
|
input: CreateLeagueScheduleRaceInputDTO,
|
|
): Promise<CreateLeagueScheduleRaceOutputDTO> {
|
|
return this.apiClient.createSeasonScheduleRace(leagueId, seasonId, input);
|
|
}
|
|
|
|
async updateLeagueSeasonScheduleRace(
|
|
leagueId: string,
|
|
seasonId: string,
|
|
raceId: string,
|
|
input: UpdateLeagueScheduleRaceInputDTO,
|
|
): Promise<LeagueScheduleRaceMutationSuccessDTO> {
|
|
return this.apiClient.updateSeasonScheduleRace(leagueId, seasonId, raceId, input);
|
|
}
|
|
|
|
async deleteLeagueSeasonScheduleRace(
|
|
leagueId: string,
|
|
seasonId: string,
|
|
raceId: string,
|
|
): Promise<LeagueScheduleRaceMutationSuccessDTO> {
|
|
return this.apiClient.deleteSeasonScheduleRace(leagueId, seasonId, raceId);
|
|
}
|
|
|
|
async getLeagueMemberships(leagueId: string): Promise<LeagueMembershipsDTO> {
|
|
return this.apiClient.getMemberships(leagueId);
|
|
}
|
|
|
|
async createLeague(input: CreateLeagueInputDTO): Promise<CreateLeagueOutputDTO> {
|
|
return this.apiClient.create(input);
|
|
}
|
|
|
|
async removeMember(leagueId: string, targetDriverId: string): Promise<{ success: boolean }> {
|
|
const dto = await this.apiClient.removeRosterMember(leagueId, targetDriverId);
|
|
return { success: dto.success };
|
|
}
|
|
|
|
async updateMemberRole(leagueId: string, targetDriverId: string, newRole: MembershipRole): Promise<{ success: boolean }> {
|
|
const dto = await this.apiClient.updateRosterMemberRole(leagueId, targetDriverId, newRole);
|
|
return { success: dto.success };
|
|
}
|
|
|
|
async getAdminRosterMembers(leagueId: string): Promise<LeagueRosterMemberDTO[]> {
|
|
return this.apiClient.getAdminRosterMembers(leagueId);
|
|
}
|
|
|
|
async getAdminRosterJoinRequests(leagueId: string): Promise<LeagueRosterJoinRequestDTO[]> {
|
|
return this.apiClient.getAdminRosterJoinRequests(leagueId);
|
|
}
|
|
|
|
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 };
|
|
}
|
|
|
|
async getLeagueDetail(): Promise<Result<never, DomainError>> {
|
|
return Result.err({ type: 'notImplemented', message: 'League detail endpoint not implemented' });
|
|
}
|
|
|
|
async getLeagueDetailPageData(): Promise<Result<never, DomainError>> {
|
|
return Result.err({ type: 'notImplemented', message: 'League detail page data endpoint not implemented' });
|
|
}
|
|
|
|
async getScoringPresets(): Promise<Result<never, DomainError>> {
|
|
return Result.err({ type: 'notImplemented', message: 'Scoring presets endpoint not implemented' });
|
|
}
|
|
} |