Files
gridpilot.gg/apps/api/src/domain/league/LeagueService.ts
2025-12-25 15:24:54 +01:00

435 lines
25 KiB
TypeScript

import { Inject, Injectable } from '@nestjs/common';
import { ApproveJoinRequestInputDTO } from './dtos/ApproveJoinRequestInputDTO';
import { ApproveLeagueJoinRequestDTO } from './dtos/ApproveLeagueJoinRequestDTO';
import { CreateLeagueInputDTO } from './dtos/CreateLeagueInputDTO';
import { GetLeagueAdminConfigQueryDTO } from './dtos/GetLeagueAdminConfigQueryDTO';
import { GetLeagueAdminPermissionsInputDTO } from './dtos/GetLeagueAdminPermissionsInputDTO';
import { GetLeagueOwnerSummaryQueryDTO } from './dtos/GetLeagueOwnerSummaryQueryDTO';
import { GetLeagueProtestsQueryDTO } from './dtos/GetLeagueProtestsQueryDTO';
import { GetLeagueRacesOutputDTO } from './dtos/GetLeagueRacesOutputDTO';
import { GetLeagueSeasonsQueryDTO } from './dtos/GetLeagueSeasonsQueryDTO';
import { GetLeagueWalletOutputDTO } from './dtos/GetLeagueWalletOutputDTO';
import { GetSeasonSponsorshipsOutputDTO } from './dtos/GetSeasonSponsorshipsOutputDTO';
import { LeagueAdminDTO } from './dtos/LeagueAdminDTO';
import { LeagueAdminPermissionsDTO } from './dtos/LeagueAdminPermissionsDTO';
import { LeagueAdminProtestsDTO } from './dtos/LeagueAdminProtestsDTO';
import { LeagueConfigFormModelDTO } from './dtos/LeagueConfigFormModelDTO';
import { LeagueJoinRequestWithDriverDTO } from './dtos/LeagueJoinRequestWithDriverDTO';
import { LeagueMembershipsDTO } from './dtos/LeagueMembershipsDTO';
import { LeagueOwnerSummaryDTO } from './dtos/LeagueOwnerSummaryDTO';
import { LeagueScheduleDTO } from './dtos/LeagueScheduleDTO';
import { LeagueSeasonSummaryDTO } from './dtos/LeagueSeasonSummaryDTO';
import { LeagueStandingsDTO } from './dtos/LeagueStandingsDTO';
import { LeagueStatsDTO } from './dtos/LeagueStatsDTO';
import { RejectJoinRequestInputDTO } from './dtos/RejectJoinRequestInputDTO';
import { RejectJoinRequestOutputDTO } from './dtos/RejectJoinRequestOutputDTO';
import { RemoveLeagueMemberInputDTO } from './dtos/RemoveLeagueMemberInputDTO';
import { RemoveLeagueMemberOutputDTO } from './dtos/RemoveLeagueMemberOutputDTO';
import { TransferLeagueOwnershipOutputDTO } from './dtos/TransferLeagueOwnershipOutputDTO';
import { UpdateLeagueMemberRoleInputDTO } from './dtos/UpdateLeagueMemberRoleInputDTO';
import { UpdateLeagueMemberRoleOutputDTO } from './dtos/UpdateLeagueMemberRoleOutputDTO';
import { WithdrawFromLeagueWalletInputDTO } from './dtos/WithdrawFromLeagueWalletInputDTO';
import { WithdrawFromLeagueWalletOutputDTO } from './dtos/WithdrawFromLeagueWalletOutputDTO';
// Core imports for view models
import type { AllLeaguesWithCapacityDTO as AllLeaguesWithCapacityViewModel } from './dtos/AllLeaguesWithCapacityDTO';
import type { CreateLeagueViewModel } from './dtos/CreateLeagueDTO';
import type { JoinLeagueOutputDTO } from './dtos/JoinLeagueOutputDTO';
import { TotalLeaguesDTO } from './dtos/TotalLeaguesDTO';
import type { LeagueScoringConfigViewModel } from './presenters/LeagueScoringConfigPresenter';
import type { LeagueScoringPresetsViewModel } from './presenters/LeagueScoringPresetsPresenter';
// Core imports
import type { Logger } from '@core/shared/application';
// Use cases
import { ApproveLeagueJoinRequestUseCase } from '@core/racing/application/use-cases/ApproveLeagueJoinRequestUseCase';
import { CreateLeagueWithSeasonAndScoringUseCase } from '@core/racing/application/use-cases/CreateLeagueWithSeasonAndScoringUseCase';
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
import { GetLeagueAdminPermissionsUseCase } from '@core/racing/application/use-cases/GetLeagueAdminPermissionsUseCase';
import { GetLeagueFullConfigUseCase } from '@core/racing/application/use-cases/GetLeagueFullConfigUseCase';
import { GetLeagueJoinRequestsUseCase } from '@core/racing/application/use-cases/GetLeagueJoinRequestsUseCase';
import { GetLeagueMembershipsUseCase } from '@core/racing/application/use-cases/GetLeagueMembershipsUseCase';
import { GetLeagueOwnerSummaryUseCase } from '@core/racing/application/use-cases/GetLeagueOwnerSummaryUseCase';
import { GetLeagueProtestsUseCase } from '@core/racing/application/use-cases/GetLeagueProtestsUseCase';
import { GetLeagueScheduleUseCase } from '@core/racing/application/use-cases/GetLeagueScheduleUseCase';
import { GetLeagueScoringConfigUseCase } from '@core/racing/application/use-cases/GetLeagueScoringConfigUseCase';
import { GetLeagueSeasonsUseCase } from '@core/racing/application/use-cases/GetLeagueSeasonsUseCase';
import { GetLeagueStandingsUseCase } from '@core/racing/application/use-cases/GetLeagueStandingsUseCase';
import { GetLeagueStatsUseCase } from '@core/racing/application/use-cases/GetLeagueStatsUseCase';
import { GetLeagueWalletUseCase } from '@core/racing/application/use-cases/GetLeagueWalletUseCase';
import { GetSeasonSponsorshipsUseCase } from '@core/racing/application/use-cases/GetSeasonSponsorshipsUseCase';
import { GetTotalLeaguesUseCase } from '@core/racing/application/use-cases/GetTotalLeaguesUseCase';
import { JoinLeagueUseCase } from '@core/racing/application/use-cases/JoinLeagueUseCase';
import { ListLeagueScoringPresetsUseCase } from '@core/racing/application/use-cases/ListLeagueScoringPresetsUseCase';
import { RejectLeagueJoinRequestUseCase } from '@core/racing/application/use-cases/RejectLeagueJoinRequestUseCase';
import { RemoveLeagueMemberUseCase } from '@core/racing/application/use-cases/RemoveLeagueMemberUseCase';
import { TransferLeagueOwnershipUseCase } from '@core/racing/application/use-cases/TransferLeagueOwnershipUseCase';
import { UpdateLeagueMemberRoleUseCase } from '@core/racing/application/use-cases/UpdateLeagueMemberRoleUseCase';
import { WithdrawFromLeagueWalletUseCase } from '@core/racing/application/use-cases/WithdrawFromLeagueWalletUseCase';
// API Presenters
import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter';
import { ApproveLeagueJoinRequestPresenter } from './presenters/ApproveLeagueJoinRequestPresenter';
import { CreateLeaguePresenter } from './presenters/CreateLeaguePresenter';
import { GetLeagueAdminPermissionsPresenter } from './presenters/GetLeagueAdminPermissionsPresenter';
import { GetLeagueMembershipsPresenter } from './presenters/GetLeagueMembershipsPresenter';
import { GetLeagueOwnerSummaryPresenter } from './presenters/GetLeagueOwnerSummaryPresenter';
import { GetLeagueProtestsPresenter } from './presenters/GetLeagueProtestsPresenter';
import { GetLeagueSeasonsPresenter } from './presenters/GetLeagueSeasonsPresenter';
import { GetSeasonSponsorshipsPresenter } from './presenters/GetSeasonSponsorshipsPresenter';
import { JoinLeaguePresenter } from './presenters/JoinLeaguePresenter';
import { LeagueConfigPresenter } from './presenters/LeagueConfigPresenter';
import { LeagueJoinRequestsPresenter } from './presenters/LeagueJoinRequestsPresenter';
import { LeagueSchedulePresenter, LeagueRacesPresenter } from './presenters/LeagueSchedulePresenter';
import { LeagueScoringConfigPresenter } from './presenters/LeagueScoringConfigPresenter';
import { LeagueScoringPresetsPresenter } from './presenters/LeagueScoringPresetsPresenter';
import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter';
import { LeagueStatsPresenter } from './presenters/LeagueStatsPresenter';
import { RejectLeagueJoinRequestPresenter } from './presenters/RejectLeagueJoinRequestPresenter';
import { RemoveLeagueMemberPresenter } from './presenters/RemoveLeagueMemberPresenter';
import { TotalLeaguesPresenter } from './presenters/TotalLeaguesPresenter';
import { TransferLeagueOwnershipPresenter } from './presenters/TransferLeagueOwnershipPresenter';
import { UpdateLeagueMemberRolePresenter } from './presenters/UpdateLeagueMemberRolePresenter';
import { GetLeagueWalletPresenter } from './presenters/GetLeagueWalletPresenter';
import { WithdrawFromLeagueWalletPresenter } from './presenters/WithdrawFromLeagueWalletPresenter';
// Tokens
import {
LOGGER_TOKEN,
GET_ALL_LEAGUES_WITH_CAPACITY_USE_CASE,
GET_LEAGUE_STANDINGS_USE_CASE,
GET_LEAGUE_STATS_USE_CASE,
GET_LEAGUE_FULL_CONFIG_USE_CASE,
GET_LEAGUE_SCORING_CONFIG_USE_CASE,
LIST_LEAGUE_SCORING_PRESETS_USE_CASE,
JOIN_LEAGUE_USE_CASE,
TRANSFER_LEAGUE_OWNERSHIP_USE_CASE,
CREATE_LEAGUE_WITH_SEASON_AND_SCORING_USE_CASE,
GET_TOTAL_LEAGUES_USE_CASE,
GET_LEAGUE_JOIN_REQUESTS_USE_CASE,
APPROVE_LEAGUE_JOIN_REQUEST_USE_CASE,
REJECT_LEAGUE_JOIN_REQUEST_USE_CASE,
REMOVE_LEAGUE_MEMBER_USE_CASE,
UPDATE_LEAGUE_MEMBER_ROLE_USE_CASE,
GET_LEAGUE_OWNER_SUMMARY_USE_CASE,
GET_LEAGUE_PROTESTS_USE_CASE,
GET_LEAGUE_SEASONS_USE_CASE,
GET_LEAGUE_MEMBERSHIPS_USE_CASE,
GET_LEAGUE_SCHEDULE_USE_CASE,
GET_LEAGUE_ADMIN_PERMISSIONS_USE_CASE,
GET_LEAGUE_WALLET_USE_CASE,
WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE,
GET_SEASON_SPONSORSHIPS_USE_CASE,
GET_ALL_LEAGUES_WITH_CAPACITY_OUTPUT_PORT_TOKEN,
GET_LEAGUE_STANDINGS_OUTPUT_PORT_TOKEN,
GET_LEAGUE_PROTESTS_OUTPUT_PORT_TOKEN,
GET_SEASON_SPONSORSHIPS_OUTPUT_PORT_TOKEN,
LIST_LEAGUE_SCORING_PRESETS_OUTPUT_PORT_TOKEN,
APPROVE_LEAGUE_JOIN_REQUEST_OUTPUT_PORT_TOKEN,
CREATE_LEAGUE_OUTPUT_PORT_TOKEN,
GET_LEAGUE_ADMIN_PERMISSIONS_OUTPUT_PORT_TOKEN,
GET_LEAGUE_MEMBERSHIPS_OUTPUT_PORT_TOKEN,
GET_LEAGUE_OWNER_SUMMARY_OUTPUT_PORT_TOKEN,
GET_LEAGUE_SEASONS_OUTPUT_PORT_TOKEN,
JOIN_LEAGUE_OUTPUT_PORT_TOKEN,
GET_LEAGUE_SCHEDULE_OUTPUT_PORT_TOKEN,
GET_LEAGUE_STATS_OUTPUT_PORT_TOKEN,
REJECT_LEAGUE_JOIN_REQUEST_OUTPUT_PORT_TOKEN,
REMOVE_LEAGUE_MEMBER_OUTPUT_PORT_TOKEN,
TOTAL_LEAGUES_OUTPUT_PORT_TOKEN,
TRANSFER_LEAGUE_OWNERSHIP_OUTPUT_PORT_TOKEN,
UPDATE_LEAGUE_MEMBER_ROLE_OUTPUT_PORT_TOKEN,
GET_LEAGUE_FULL_CONFIG_OUTPUT_PORT_TOKEN,
GET_LEAGUE_SCORING_CONFIG_OUTPUT_PORT_TOKEN,
GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN,
WITHDRAW_FROM_LEAGUE_WALLET_OUTPUT_PORT_TOKEN,
} from './LeagueTokens';
@Injectable()
export class LeagueService {
constructor(
@Inject(GET_ALL_LEAGUES_WITH_CAPACITY_USE_CASE) private readonly getAllLeaguesWithCapacityUseCase: GetAllLeaguesWithCapacityUseCase,
@Inject(GET_LEAGUE_STANDINGS_USE_CASE) private readonly getLeagueStandingsUseCase: GetLeagueStandingsUseCase,
@Inject(GET_LEAGUE_STATS_USE_CASE) private readonly getLeagueStatsUseCase: GetLeagueStatsUseCase,
@Inject(GET_LEAGUE_FULL_CONFIG_USE_CASE) private readonly getLeagueFullConfigUseCase: GetLeagueFullConfigUseCase,
@Inject(GET_LEAGUE_SCORING_CONFIG_USE_CASE) private readonly getLeagueScoringConfigUseCase: GetLeagueScoringConfigUseCase,
@Inject(LIST_LEAGUE_SCORING_PRESETS_USE_CASE) private readonly listLeagueScoringPresetsUseCase: ListLeagueScoringPresetsUseCase,
@Inject(JOIN_LEAGUE_USE_CASE) private readonly joinLeagueUseCase: JoinLeagueUseCase,
@Inject(TRANSFER_LEAGUE_OWNERSHIP_USE_CASE) private readonly transferLeagueOwnershipUseCase: TransferLeagueOwnershipUseCase,
@Inject(CREATE_LEAGUE_WITH_SEASON_AND_SCORING_USE_CASE) private readonly createLeagueWithSeasonAndScoringUseCase: CreateLeagueWithSeasonAndScoringUseCase,
@Inject(GET_TOTAL_LEAGUES_USE_CASE) private readonly getTotalLeaguesUseCase: GetTotalLeaguesUseCase,
@Inject(GET_LEAGUE_JOIN_REQUESTS_USE_CASE) private readonly getLeagueJoinRequestsUseCase: GetLeagueJoinRequestsUseCase,
@Inject(APPROVE_LEAGUE_JOIN_REQUEST_USE_CASE) private readonly approveLeagueJoinRequestUseCase: ApproveLeagueJoinRequestUseCase,
@Inject(REJECT_LEAGUE_JOIN_REQUEST_USE_CASE) private readonly rejectLeagueJoinRequestUseCase: RejectLeagueJoinRequestUseCase,
@Inject(REMOVE_LEAGUE_MEMBER_USE_CASE) private readonly removeLeagueMemberUseCase: RemoveLeagueMemberUseCase,
@Inject(UPDATE_LEAGUE_MEMBER_ROLE_USE_CASE) private readonly updateLeagueMemberRoleUseCase: UpdateLeagueMemberRoleUseCase,
@Inject(GET_LEAGUE_OWNER_SUMMARY_USE_CASE) private readonly getLeagueOwnerSummaryUseCase: GetLeagueOwnerSummaryUseCase,
@Inject(GET_LEAGUE_PROTESTS_USE_CASE) private readonly getLeagueProtestsUseCase: GetLeagueProtestsUseCase,
@Inject(GET_LEAGUE_SEASONS_USE_CASE) private readonly getLeagueSeasonsUseCase: GetLeagueSeasonsUseCase,
@Inject(GET_LEAGUE_MEMBERSHIPS_USE_CASE) private readonly getLeagueMembershipsUseCase: GetLeagueMembershipsUseCase,
@Inject(GET_LEAGUE_SCHEDULE_USE_CASE) private readonly getLeagueScheduleUseCase: GetLeagueScheduleUseCase,
@Inject(GET_LEAGUE_ADMIN_PERMISSIONS_USE_CASE) private readonly getLeagueAdminPermissionsUseCase: GetLeagueAdminPermissionsUseCase,
@Inject(GET_LEAGUE_WALLET_USE_CASE) private readonly getLeagueWalletUseCase: GetLeagueWalletUseCase,
@Inject(WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE) private readonly withdrawFromLeagueWalletUseCase: WithdrawFromLeagueWalletUseCase,
@Inject(GET_SEASON_SPONSORSHIPS_USE_CASE) private readonly getSeasonSponsorshipsUseCase: GetSeasonSponsorshipsUseCase,
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
// Injected presenters
@Inject(GET_ALL_LEAGUES_WITH_CAPACITY_OUTPUT_PORT_TOKEN) private readonly allLeaguesWithCapacityPresenter: AllLeaguesWithCapacityPresenter,
@Inject(GET_LEAGUE_STANDINGS_OUTPUT_PORT_TOKEN) private readonly leagueStandingsPresenter: LeagueStandingsPresenter,
@Inject(GET_LEAGUE_PROTESTS_OUTPUT_PORT_TOKEN) private readonly leagueProtestsPresenter: GetLeagueProtestsPresenter,
@Inject(GET_SEASON_SPONSORSHIPS_OUTPUT_PORT_TOKEN) private readonly seasonSponsorshipsPresenter: GetSeasonSponsorshipsPresenter,
@Inject(LIST_LEAGUE_SCORING_PRESETS_OUTPUT_PORT_TOKEN) private readonly leagueScoringPresetsPresenter: LeagueScoringPresetsPresenter,
@Inject(APPROVE_LEAGUE_JOIN_REQUEST_OUTPUT_PORT_TOKEN) private readonly approveLeagueJoinRequestPresenter: ApproveLeagueJoinRequestPresenter,
@Inject(CREATE_LEAGUE_OUTPUT_PORT_TOKEN) private readonly createLeaguePresenter: CreateLeaguePresenter,
@Inject(GET_LEAGUE_ADMIN_PERMISSIONS_OUTPUT_PORT_TOKEN) private readonly getLeagueAdminPermissionsPresenter: GetLeagueAdminPermissionsPresenter,
@Inject(GET_LEAGUE_MEMBERSHIPS_OUTPUT_PORT_TOKEN) private readonly getLeagueMembershipsPresenter: GetLeagueMembershipsPresenter,
@Inject(GET_LEAGUE_OWNER_SUMMARY_OUTPUT_PORT_TOKEN) private readonly getLeagueOwnerSummaryPresenter: GetLeagueOwnerSummaryPresenter,
@Inject(GET_LEAGUE_SEASONS_OUTPUT_PORT_TOKEN) private readonly getLeagueSeasonsPresenter: GetLeagueSeasonsPresenter,
@Inject(JOIN_LEAGUE_OUTPUT_PORT_TOKEN) private readonly joinLeaguePresenter: JoinLeaguePresenter,
@Inject(GET_LEAGUE_SCHEDULE_OUTPUT_PORT_TOKEN) private readonly leagueSchedulePresenter: LeagueSchedulePresenter,
@Inject(GET_LEAGUE_STATS_OUTPUT_PORT_TOKEN) private readonly leagueStatsPresenter: LeagueStatsPresenter,
@Inject(REJECT_LEAGUE_JOIN_REQUEST_OUTPUT_PORT_TOKEN) private readonly rejectLeagueJoinRequestPresenter: RejectLeagueJoinRequestPresenter,
@Inject(REMOVE_LEAGUE_MEMBER_OUTPUT_PORT_TOKEN) private readonly removeLeagueMemberPresenter: RemoveLeagueMemberPresenter,
@Inject(TOTAL_LEAGUES_OUTPUT_PORT_TOKEN) private readonly totalLeaguesPresenter: TotalLeaguesPresenter,
@Inject(TRANSFER_LEAGUE_OWNERSHIP_OUTPUT_PORT_TOKEN) private readonly transferLeagueOwnershipPresenter: TransferLeagueOwnershipPresenter,
@Inject(UPDATE_LEAGUE_MEMBER_ROLE_OUTPUT_PORT_TOKEN) private readonly updateLeagueMemberRolePresenter: UpdateLeagueMemberRolePresenter,
@Inject(GET_LEAGUE_FULL_CONFIG_OUTPUT_PORT_TOKEN) private readonly leagueConfigPresenter: LeagueConfigPresenter,
@Inject(GET_LEAGUE_SCORING_CONFIG_OUTPUT_PORT_TOKEN) private readonly leagueScoringConfigPresenter: LeagueScoringConfigPresenter,
@Inject(GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN) private readonly getLeagueWalletPresenter: GetLeagueWalletPresenter,
@Inject(WITHDRAW_FROM_LEAGUE_WALLET_OUTPUT_PORT_TOKEN) private readonly withdrawFromLeagueWalletPresenter: WithdrawFromLeagueWalletPresenter,
private readonly leagueJoinRequestsPresenter: LeagueJoinRequestsPresenter,
private readonly leagueRacesPresenter: LeagueRacesPresenter,
) {}
async getAllLeaguesWithCapacity(): Promise<AllLeaguesWithCapacityViewModel> {
this.logger.debug('[LeagueService] Fetching all leagues with capacity.');
const result = await this.getAllLeaguesWithCapacityUseCase.execute({});
if (result.isErr()) {
const err = result.unwrapErr();
this.logger.error('[LeagueService] Failed to fetch leagues with capacity', new Error(err.code), {
details: err.details,
});
throw new Error(err.code);
}
this.allLeaguesWithCapacityPresenter.present(result.unwrap());
return this.allLeaguesWithCapacityPresenter.getViewModel();
}
async getTotalLeagues(): Promise<TotalLeaguesDTO> {
this.logger.debug('[LeagueService] Fetching total leagues count.');
await this.getTotalLeaguesUseCase.execute({});
return this.totalLeaguesPresenter.getResponseModel()!;
}
async getLeagueJoinRequests(leagueId: string): Promise<LeagueJoinRequestWithDriverDTO[]> {
this.logger.debug(`[LeagueService] Fetching join requests for league: ${leagueId}.`);
await this.getLeagueJoinRequestsUseCase.execute({ leagueId });
return this.leagueJoinRequestsPresenter.getViewModel()!.joinRequests;
}
async approveLeagueJoinRequest(input: ApproveJoinRequestInputDTO): Promise<ApproveLeagueJoinRequestDTO> {
this.logger.debug('Approving join request:', input);
await this.approveLeagueJoinRequestUseCase.execute(input, this.approveLeagueJoinRequestPresenter);
return this.approveLeagueJoinRequestPresenter.getViewModel()!;
}
async rejectLeagueJoinRequest(input: RejectJoinRequestInputDTO): Promise<RejectJoinRequestOutputDTO> {
this.logger.debug('Rejecting join request:', input);
await this.rejectLeagueJoinRequestUseCase.execute({
leagueId: input.leagueId,
adminId: 'admin', // This should come from auth context
requestId: input.requestId
});
return this.rejectLeagueJoinRequestPresenter.getViewModel()!;
}
async getLeagueAdminPermissions(query: GetLeagueAdminPermissionsInputDTO): Promise<LeagueAdminPermissionsDTO> {
this.logger.debug('Getting league admin permissions', { query });
await this.getLeagueAdminPermissionsUseCase.execute(query);
return this.getLeagueAdminPermissionsPresenter.getResponseModel()!;
}
async removeLeagueMember(input: RemoveLeagueMemberInputDTO): Promise<RemoveLeagueMemberOutputDTO> {
this.logger.debug('Removing league member', { leagueId: input.leagueId, targetDriverId: input.targetDriverId });
await this.removeLeagueMemberUseCase.execute(input);
return this.removeLeagueMemberPresenter.getViewModel()!;
}
async updateLeagueMemberRole(input: UpdateLeagueMemberRoleInputDTO): Promise<UpdateLeagueMemberRoleOutputDTO> {
this.logger.debug('Updating league member role', { leagueId: input.leagueId, targetDriverId: input.targetDriverId, newRole: input.newRole });
await this.updateLeagueMemberRoleUseCase.execute(input);
return this.updateLeagueMemberRolePresenter.getViewModel()!;
}
async getLeagueOwnerSummary(query: GetLeagueOwnerSummaryQueryDTO): Promise<LeagueOwnerSummaryDTO> {
this.logger.debug('Getting league owner summary:', query);
await this.getLeagueOwnerSummaryUseCase.execute(query);
return this.getLeagueOwnerSummaryPresenter.getViewModel()!;
}
async getLeagueFullConfig(query: GetLeagueAdminConfigQueryDTO): Promise<LeagueConfigFormModelDTO | null> {
this.logger.debug('Getting league full config', { query });
try {
await this.getLeagueFullConfigUseCase.execute(query);
return this.leagueConfigPresenter.getViewModel();
} catch (error) {
this.logger.error('Error getting league full config', error instanceof Error ? error : new Error(String(error)));
return null;
}
}
async getLeagueProtests(query: GetLeagueProtestsQueryDTO): Promise<LeagueAdminProtestsDTO> {
this.logger.debug('Getting league protests:', query);
await this.getLeagueProtestsUseCase.execute(query);
return this.leagueProtestsPresenter.getResponseModel()!;
}
async getLeagueSeasons(query: GetLeagueSeasonsQueryDTO): Promise<LeagueSeasonSummaryDTO[]> {
this.logger.debug('Getting league seasons:', query);
await this.getLeagueSeasonsUseCase.execute(query);
return this.getLeagueSeasonsPresenter.getResponseModel()!;
}
async getLeagueMemberships(leagueId: string): Promise<LeagueMembershipsDTO> {
this.logger.debug('Getting league memberships', { leagueId });
await this.getLeagueMembershipsUseCase.execute({ leagueId });
return this.getLeagueMembershipsPresenter.getViewModel()!.memberships;
}
async getLeagueStandings(leagueId: string): Promise<LeagueStandingsDTO> {
this.logger.debug('Getting league standings', { leagueId });
await this.getLeagueStandingsUseCase.execute({ leagueId });
return this.leagueStandingsPresenter.getResponseModel()!;
}
async getLeagueSchedule(leagueId: string): Promise<LeagueScheduleDTO> {
this.logger.debug('Getting league schedule', { leagueId });
await this.getLeagueScheduleUseCase.execute({ leagueId });
return this.leagueSchedulePresenter.getViewModel()!;
}
async getLeagueStats(leagueId: string): Promise<LeagueStatsDTO> {
this.logger.debug('Getting league stats', { leagueId });
await this.getLeagueStatsUseCase.execute({ leagueId });
return this.leagueStatsPresenter.getResponseModel()!;
}
async getLeagueAdmin(leagueId: string): Promise<LeagueAdminDTO> {
this.logger.debug('Getting league admin data', { leagueId });
const [fullConfigResult, joinRequests, protests, seasons] = await Promise.all([
this.getLeagueFullConfigUseCase.execute({ leagueId }),
this.getLeagueJoinRequests(leagueId),
this.getLeagueProtests({ leagueId }),
this.getLeagueSeasons({ leagueId }),
]);
if (fullConfigResult.isErr()) {
throw new Error(fullConfigResult.unwrapErr().code);
}
await this.getLeagueOwnerSummaryUseCase.execute({ leagueId });
const ownerSummary = this.getLeagueOwnerSummaryPresenter.getViewModel()!;
const configForm = this.leagueConfigPresenter.getViewModel();
// For now, return a simple structure since we don't have a LeagueAdminPresenter
return {
joinRequests: joinRequests,
ownerSummary,
config: { form: configForm },
protests,
seasons,
};
}
async createLeague(input: CreateLeagueInputDTO): Promise<CreateLeagueViewModel> {
this.logger.debug('Creating league', { input });
const command = {
name: input.name,
description: input.description,
ownerId: input.ownerId,
visibility: 'unranked' as const,
gameId: 'iracing', // Assume default
maxDrivers: 32, // Default value
enableDriverChampionship: true,
enableTeamChampionship: false,
enableNationsChampionship: false,
enableTrophyChampionship: false,
};
await this.createLeagueWithSeasonAndScoringUseCase.execute(command);
return this.createLeaguePresenter.getViewModel()!;
}
async getLeagueScoringConfig(leagueId: string): Promise<LeagueScoringConfigViewModel | null> {
this.logger.debug('Getting league scoring config', { leagueId });
try {
await this.getLeagueScoringConfigUseCase.execute({ leagueId });
return this.leagueScoringConfigPresenter.getViewModel();
} catch (error) {
this.logger.error('Error getting league scoring config', error instanceof Error ? error : new Error(String(error)));
return null;
}
}
async listLeagueScoringPresets(): Promise<LeagueScoringPresetsViewModel> {
this.logger.debug('Listing league scoring presets');
await this.listLeagueScoringPresetsUseCase.execute({});
return this.leagueScoringPresetsPresenter.getViewModel()!;
}
async joinLeague(leagueId: string, driverId: string): Promise<JoinLeagueOutputDTO> {
this.logger.debug('Joining league', { leagueId, driverId });
await this.joinLeagueUseCase.execute({ leagueId, driverId });
return this.joinLeaguePresenter.getViewModel()!;
}
async transferLeagueOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<TransferLeagueOwnershipOutputDTO> {
this.logger.debug('Transferring league ownership', { leagueId, currentOwnerId, newOwnerId });
await this.transferLeagueOwnershipUseCase.execute({ leagueId, currentOwnerId, newOwnerId });
return this.transferLeagueOwnershipPresenter.getViewModel()!;
}
async getSeasonSponsorships(seasonId: string): Promise<GetSeasonSponsorshipsOutputDTO> {
this.logger.debug('Getting season sponsorships', { seasonId });
await this.getSeasonSponsorshipsUseCase.execute({ seasonId });
return this.seasonSponsorshipsPresenter.getViewModel()!;
}
async getRaces(leagueId: string): Promise<GetLeagueRacesOutputDTO> {
this.logger.debug('Getting league races', { leagueId });
await this.getLeagueScheduleUseCase.execute({ leagueId });
return {
races: this.leagueRacesPresenter.getViewModel()!,
};
}
async getLeagueWallet(leagueId: string): Promise<GetLeagueWalletOutputDTO> {
this.logger.debug('Getting league wallet', { leagueId });
await this.getLeagueWalletUseCase.execute({ leagueId });
return this.getLeagueWalletPresenter.getResponseModel();
}
async withdrawFromLeagueWallet(leagueId: string, input: WithdrawFromLeagueWalletInputDTO): Promise<WithdrawFromLeagueWalletOutputDTO> {
this.logger.debug('Withdrawing from league wallet', { leagueId, amount: input.amount });
await this.withdrawFromLeagueWalletUseCase.execute({
leagueId,
requestedById: "admin",
amount: input.amount,
currency: input.currency as 'USD' | 'EUR' | 'GBP',
reason: input.destinationAccount,
});
return this.withdrawFromLeagueWalletPresenter.getResponseModel();
}
}