wip league admin tools
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Inject, Injectable } from '@nestjs/common';
|
||||
import { BadRequestException, ConflictException, Inject, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { ApproveJoinRequestInputDTO } from './dtos/ApproveJoinRequestInputDTO';
|
||||
import { ApproveLeagueJoinRequestDTO } from './dtos/ApproveLeagueJoinRequestDTO';
|
||||
import { CreateLeagueInputDTO } from './dtos/CreateLeagueInputDTO';
|
||||
@@ -9,6 +9,13 @@ import { GetLeagueProtestsQueryDTO } from './dtos/GetLeagueProtestsQueryDTO';
|
||||
import { GetLeagueRacesOutputDTO } from './dtos/GetLeagueRacesOutputDTO';
|
||||
import { GetLeagueSeasonsQueryDTO } from './dtos/GetLeagueSeasonsQueryDTO';
|
||||
import { GetLeagueWalletOutputDTO } from './dtos/GetLeagueWalletOutputDTO';
|
||||
import { GetLeagueScheduleQueryDTO } from './dtos/GetLeagueScheduleQueryDTO';
|
||||
import {
|
||||
CreateLeagueScheduleRaceInputDTO,
|
||||
CreateLeagueScheduleRaceOutputDTO,
|
||||
LeagueScheduleRaceMutationSuccessDTO,
|
||||
UpdateLeagueScheduleRaceInputDTO,
|
||||
} from './dtos/LeagueScheduleRaceAdminDTO';
|
||||
import { GetSeasonSponsorshipsOutputDTO } from './dtos/GetSeasonSponsorshipsOutputDTO';
|
||||
import { LeagueAdminDTO } from './dtos/LeagueAdminDTO';
|
||||
import { LeagueAdminPermissionsDTO } from './dtos/LeagueAdminPermissionsDTO';
|
||||
@@ -16,8 +23,14 @@ import { LeagueAdminProtestsDTO } from './dtos/LeagueAdminProtestsDTO';
|
||||
import { LeagueConfigFormModelDTO } from './dtos/LeagueConfigFormModelDTO';
|
||||
import { LeagueJoinRequestWithDriverDTO } from './dtos/LeagueJoinRequestWithDriverDTO';
|
||||
import { LeagueMembershipsDTO } from './dtos/LeagueMembershipsDTO';
|
||||
import { LeagueRosterJoinRequestDTO } from './dtos/LeagueRosterJoinRequestDTO';
|
||||
import { LeagueRosterMemberDTO } from './dtos/LeagueRosterMemberDTO';
|
||||
import { LeagueOwnerSummaryDTO } from './dtos/LeagueOwnerSummaryDTO';
|
||||
import { LeagueScheduleDTO } from './dtos/LeagueScheduleDTO';
|
||||
import {
|
||||
LeagueSeasonSchedulePublishInputDTO,
|
||||
LeagueSeasonSchedulePublishOutputDTO,
|
||||
} from './dtos/LeagueSeasonSchedulePublishDTO';
|
||||
import { LeagueSeasonSummaryDTO } from './dtos/LeagueSeasonSummaryDTO';
|
||||
import { LeagueStandingsDTO } from './dtos/LeagueStandingsDTO';
|
||||
import { LeagueStatsDTO } from './dtos/LeagueStatsDTO';
|
||||
@@ -26,11 +39,15 @@ import { RejectJoinRequestOutputDTO } from './dtos/RejectJoinRequestOutputDTO';
|
||||
import { RemoveLeagueMemberInputDTO } from './dtos/RemoveLeagueMemberInputDTO';
|
||||
import { RemoveLeagueMemberOutputDTO } from './dtos/RemoveLeagueMemberOutputDTO';
|
||||
import { TransferLeagueOwnershipOutputDTO } from './dtos/TransferLeagueOwnershipOutputDTO';
|
||||
import { TransferLeagueOwnershipInputDTO } from './dtos/TransferLeagueOwnershipInputDTO';
|
||||
import { UpdateLeagueMemberRoleInputDTO } from './dtos/UpdateLeagueMemberRoleInputDTO';
|
||||
import { UpdateLeagueMemberRoleOutputDTO } from './dtos/UpdateLeagueMemberRoleOutputDTO';
|
||||
import { WithdrawFromLeagueWalletInputDTO } from './dtos/WithdrawFromLeagueWalletInputDTO';
|
||||
import { WithdrawFromLeagueWalletOutputDTO } from './dtos/WithdrawFromLeagueWalletOutputDTO';
|
||||
|
||||
import { getActorFromRequestContext } from '../auth/getActorFromRequestContext';
|
||||
import { requireLeagueAdminOrOwner } from './LeagueAuthorization';
|
||||
|
||||
// Core imports for view models
|
||||
import type { AllLeaguesWithCapacityDTO as AllLeaguesWithCapacityViewModel } from './dtos/AllLeaguesWithCapacityDTO';
|
||||
import type { AllLeaguesWithCapacityAndScoringDTO as AllLeaguesWithCapacityAndScoringViewModel } from './dtos/AllLeaguesWithCapacityAndScoringDTO';
|
||||
@@ -52,9 +69,12 @@ import { GetLeagueAdminPermissionsUseCase } from '@core/racing/application/use-c
|
||||
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 { GetLeagueRosterMembersUseCase } from '@core/racing/application/use-cases/GetLeagueRosterMembersUseCase';
|
||||
import { GetLeagueRosterJoinRequestsUseCase } from '@core/racing/application/use-cases/GetLeagueRosterJoinRequestsUseCase';
|
||||
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 type { GetLeagueScheduleInput } 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';
|
||||
@@ -70,6 +90,12 @@ import { TransferLeagueOwnershipUseCase } from '@core/racing/application/use-cas
|
||||
import { UpdateLeagueMemberRoleUseCase } from '@core/racing/application/use-cases/UpdateLeagueMemberRoleUseCase';
|
||||
import { WithdrawFromLeagueWalletUseCase } from '@core/racing/application/use-cases/WithdrawFromLeagueWalletUseCase';
|
||||
|
||||
import { CreateLeagueSeasonScheduleRaceUseCase } from '@core/racing/application/use-cases/CreateLeagueSeasonScheduleRaceUseCase';
|
||||
import { DeleteLeagueSeasonScheduleRaceUseCase } from '@core/racing/application/use-cases/DeleteLeagueSeasonScheduleRaceUseCase';
|
||||
import { PublishLeagueSeasonScheduleUseCase } from '@core/racing/application/use-cases/PublishLeagueSeasonScheduleUseCase';
|
||||
import { UnpublishLeagueSeasonScheduleUseCase } from '@core/racing/application/use-cases/UnpublishLeagueSeasonScheduleUseCase';
|
||||
import { UpdateLeagueSeasonScheduleRaceUseCase } from '@core/racing/application/use-cases/UpdateLeagueSeasonScheduleRaceUseCase';
|
||||
|
||||
// API Presenters
|
||||
import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter';
|
||||
import { AllLeaguesWithCapacityAndScoringPresenter } from './presenters/AllLeaguesWithCapacityAndScoringPresenter';
|
||||
@@ -77,6 +103,10 @@ import { ApproveLeagueJoinRequestPresenter } from './presenters/ApproveLeagueJoi
|
||||
import { CreateLeaguePresenter } from './presenters/CreateLeaguePresenter';
|
||||
import { GetLeagueAdminPermissionsPresenter } from './presenters/GetLeagueAdminPermissionsPresenter';
|
||||
import { GetLeagueMembershipsPresenter } from './presenters/GetLeagueMembershipsPresenter';
|
||||
import {
|
||||
GetLeagueRosterJoinRequestsPresenter,
|
||||
GetLeagueRosterMembersPresenter,
|
||||
} from './presenters/LeagueRosterAdminReadPresenters';
|
||||
import { GetLeagueOwnerSummaryPresenter } from './presenters/GetLeagueOwnerSummaryPresenter';
|
||||
import { GetLeagueProtestsPresenter } from './presenters/GetLeagueProtestsPresenter';
|
||||
import { GetLeagueSeasonsPresenter } from './presenters/GetLeagueSeasonsPresenter';
|
||||
@@ -96,58 +126,74 @@ import { TransferLeagueOwnershipPresenter } from './presenters/TransferLeagueOwn
|
||||
import { UpdateLeagueMemberRolePresenter } from './presenters/UpdateLeagueMemberRolePresenter';
|
||||
import { GetLeagueWalletPresenter } from './presenters/GetLeagueWalletPresenter';
|
||||
import { WithdrawFromLeagueWalletPresenter } from './presenters/WithdrawFromLeagueWalletPresenter';
|
||||
import {
|
||||
CreateLeagueSeasonScheduleRacePresenter,
|
||||
DeleteLeagueSeasonScheduleRacePresenter,
|
||||
PublishLeagueSeasonSchedulePresenter,
|
||||
UnpublishLeagueSeasonSchedulePresenter,
|
||||
UpdateLeagueSeasonScheduleRacePresenter,
|
||||
} from './presenters/LeagueSeasonScheduleMutationPresenters';
|
||||
// Tokens
|
||||
import {
|
||||
LOGGER_TOKEN,
|
||||
GET_ALL_LEAGUES_WITH_CAPACITY_USE_CASE,
|
||||
GET_LEAGUE_STANDINGS_USE_CASE,
|
||||
GET_ALL_LEAGUES_WITH_CAPACITY_AND_SCORING_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_ALL_LEAGUES_WITH_CAPACITY_AND_SCORING_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,
|
||||
APPROVE_LEAGUE_JOIN_REQUEST_USE_CASE,
|
||||
CREATE_LEAGUE_OUTPUT_PORT_TOKEN,
|
||||
CREATE_LEAGUE_SEASON_SCHEDULE_RACE_USE_CASE,
|
||||
CREATE_LEAGUE_WITH_SEASON_AND_SCORING_USE_CASE,
|
||||
GET_ALL_LEAGUES_WITH_CAPACITY_AND_SCORING_OUTPUT_PORT_TOKEN,
|
||||
GET_ALL_LEAGUES_WITH_CAPACITY_AND_SCORING_USE_CASE,
|
||||
GET_ALL_LEAGUES_WITH_CAPACITY_OUTPUT_PORT_TOKEN,
|
||||
GET_ALL_LEAGUES_WITH_CAPACITY_USE_CASE,
|
||||
GET_LEAGUE_ADMIN_PERMISSIONS_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_ADMIN_PERMISSIONS_USE_CASE,
|
||||
GET_LEAGUE_FULL_CONFIG_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_FULL_CONFIG_USE_CASE,
|
||||
GET_LEAGUE_JOIN_REQUESTS_USE_CASE,
|
||||
GET_LEAGUE_MEMBERSHIPS_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_MEMBERSHIPS_USE_CASE,
|
||||
GET_LEAGUE_ROSTER_JOIN_REQUESTS_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_ROSTER_JOIN_REQUESTS_USE_CASE,
|
||||
GET_LEAGUE_ROSTER_MEMBERS_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_ROSTER_MEMBERS_USE_CASE,
|
||||
GET_LEAGUE_OWNER_SUMMARY_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_SEASONS_OUTPUT_PORT_TOKEN,
|
||||
JOIN_LEAGUE_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_OWNER_SUMMARY_USE_CASE,
|
||||
GET_LEAGUE_PROTESTS_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_PROTESTS_USE_CASE,
|
||||
GET_LEAGUE_SCHEDULE_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_SCHEDULE_USE_CASE,
|
||||
GET_LEAGUE_SCORING_CONFIG_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_SCORING_CONFIG_USE_CASE,
|
||||
GET_LEAGUE_SEASONS_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_SEASONS_USE_CASE,
|
||||
GET_LEAGUE_STATS_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_STATS_USE_CASE,
|
||||
GET_LEAGUE_STANDINGS_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_STANDINGS_USE_CASE,
|
||||
GET_LEAGUE_WALLET_OUTPUT_PORT_TOKEN,
|
||||
GET_LEAGUE_WALLET_USE_CASE,
|
||||
GET_SEASON_SPONSORSHIPS_OUTPUT_PORT_TOKEN,
|
||||
GET_SEASON_SPONSORSHIPS_USE_CASE,
|
||||
GET_TOTAL_LEAGUES_USE_CASE,
|
||||
JOIN_LEAGUE_OUTPUT_PORT_TOKEN,
|
||||
JOIN_LEAGUE_USE_CASE,
|
||||
LIST_LEAGUE_SCORING_PRESETS_OUTPUT_PORT_TOKEN,
|
||||
LIST_LEAGUE_SCORING_PRESETS_USE_CASE,
|
||||
LOGGER_TOKEN,
|
||||
PUBLISH_LEAGUE_SEASON_SCHEDULE_USE_CASE,
|
||||
REJECT_LEAGUE_JOIN_REQUEST_OUTPUT_PORT_TOKEN,
|
||||
REJECT_LEAGUE_JOIN_REQUEST_USE_CASE,
|
||||
REMOVE_LEAGUE_MEMBER_OUTPUT_PORT_TOKEN,
|
||||
REMOVE_LEAGUE_MEMBER_USE_CASE,
|
||||
TOTAL_LEAGUES_OUTPUT_PORT_TOKEN,
|
||||
TRANSFER_LEAGUE_OWNERSHIP_OUTPUT_PORT_TOKEN,
|
||||
TRANSFER_LEAGUE_OWNERSHIP_USE_CASE,
|
||||
UNPUBLISH_LEAGUE_SEASON_SCHEDULE_USE_CASE,
|
||||
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,
|
||||
UPDATE_LEAGUE_MEMBER_ROLE_USE_CASE,
|
||||
UPDATE_LEAGUE_SEASON_SCHEDULE_RACE_USE_CASE,
|
||||
DELETE_LEAGUE_SEASON_SCHEDULE_RACE_USE_CASE,
|
||||
WITHDRAW_FROM_LEAGUE_WALLET_OUTPUT_PORT_TOKEN,
|
||||
WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE,
|
||||
} from './LeagueTokens';
|
||||
|
||||
@Injectable()
|
||||
@@ -178,7 +224,21 @@ export class LeagueService {
|
||||
@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,
|
||||
|
||||
// Schedule mutations
|
||||
@Inject(CREATE_LEAGUE_SEASON_SCHEDULE_RACE_USE_CASE)
|
||||
private readonly createLeagueSeasonScheduleRaceUseCase: CreateLeagueSeasonScheduleRaceUseCase,
|
||||
@Inject(UPDATE_LEAGUE_SEASON_SCHEDULE_RACE_USE_CASE)
|
||||
private readonly updateLeagueSeasonScheduleRaceUseCase: UpdateLeagueSeasonScheduleRaceUseCase,
|
||||
@Inject(DELETE_LEAGUE_SEASON_SCHEDULE_RACE_USE_CASE)
|
||||
private readonly deleteLeagueSeasonScheduleRaceUseCase: DeleteLeagueSeasonScheduleRaceUseCase,
|
||||
@Inject(PUBLISH_LEAGUE_SEASON_SCHEDULE_USE_CASE)
|
||||
private readonly publishLeagueSeasonScheduleUseCase: PublishLeagueSeasonScheduleUseCase,
|
||||
@Inject(UNPUBLISH_LEAGUE_SEASON_SCHEDULE_USE_CASE)
|
||||
private readonly unpublishLeagueSeasonScheduleUseCase: UnpublishLeagueSeasonScheduleUseCase,
|
||||
|
||||
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
|
||||
|
||||
// Injected presenters
|
||||
@Inject(GET_ALL_LEAGUES_WITH_CAPACITY_OUTPUT_PORT_TOKEN) private readonly allLeaguesWithCapacityPresenter: AllLeaguesWithCapacityPresenter,
|
||||
@Inject(GET_ALL_LEAGUES_WITH_CAPACITY_AND_SCORING_OUTPUT_PORT_TOKEN) private readonly allLeaguesWithCapacityAndScoringPresenter: AllLeaguesWithCapacityAndScoringPresenter,
|
||||
@@ -204,8 +264,30 @@ export class LeagueService {
|
||||
@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,
|
||||
@Inject(LeagueJoinRequestsPresenter) private readonly leagueJoinRequestsPresenter: LeagueJoinRequestsPresenter,
|
||||
@Inject(LeagueRacesPresenter) private readonly leagueRacesPresenter: LeagueRacesPresenter,
|
||||
|
||||
// Schedule mutation presenters
|
||||
@Inject(CreateLeagueSeasonScheduleRacePresenter)
|
||||
private readonly createLeagueSeasonScheduleRacePresenter: CreateLeagueSeasonScheduleRacePresenter,
|
||||
@Inject(UpdateLeagueSeasonScheduleRacePresenter)
|
||||
private readonly updateLeagueSeasonScheduleRacePresenter: UpdateLeagueSeasonScheduleRacePresenter,
|
||||
@Inject(DeleteLeagueSeasonScheduleRacePresenter)
|
||||
private readonly deleteLeagueSeasonScheduleRacePresenter: DeleteLeagueSeasonScheduleRacePresenter,
|
||||
@Inject(PublishLeagueSeasonSchedulePresenter)
|
||||
private readonly publishLeagueSeasonSchedulePresenter: PublishLeagueSeasonSchedulePresenter,
|
||||
@Inject(UnpublishLeagueSeasonSchedulePresenter)
|
||||
private readonly unpublishLeagueSeasonSchedulePresenter: UnpublishLeagueSeasonSchedulePresenter,
|
||||
|
||||
// Roster admin read delegation
|
||||
@Inject(GET_LEAGUE_ROSTER_MEMBERS_USE_CASE)
|
||||
private readonly getLeagueRosterMembersUseCase: GetLeagueRosterMembersUseCase,
|
||||
@Inject(GET_LEAGUE_ROSTER_JOIN_REQUESTS_USE_CASE)
|
||||
private readonly getLeagueRosterJoinRequestsUseCase: GetLeagueRosterJoinRequestsUseCase,
|
||||
@Inject(GET_LEAGUE_ROSTER_MEMBERS_OUTPUT_PORT_TOKEN)
|
||||
private readonly getLeagueRosterMembersPresenter: GetLeagueRosterMembersPresenter,
|
||||
@Inject(GET_LEAGUE_ROSTER_JOIN_REQUESTS_OUTPUT_PORT_TOKEN)
|
||||
private readonly getLeagueRosterJoinRequestsPresenter: GetLeagueRosterJoinRequestsPresenter,
|
||||
) {}
|
||||
|
||||
async getAllLeaguesWithCapacity(): Promise<AllLeaguesWithCapacityViewModel> {
|
||||
@@ -247,43 +329,214 @@ export class LeagueService {
|
||||
return this.totalLeaguesPresenter.getResponseModel()!;
|
||||
}
|
||||
|
||||
private getActor(): ReturnType<typeof getActorFromRequestContext> {
|
||||
return getActorFromRequestContext();
|
||||
}
|
||||
|
||||
private async requireLeagueAdminPermissions(leagueId: string): Promise<void> {
|
||||
await requireLeagueAdminOrOwner(leagueId, this.getLeagueAdminPermissionsUseCase);
|
||||
}
|
||||
|
||||
async getLeagueJoinRequests(leagueId: string): Promise<LeagueJoinRequestWithDriverDTO[]> {
|
||||
this.logger.debug(`[LeagueService] Fetching join requests for league: ${leagueId}.`);
|
||||
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
this.leagueJoinRequestsPresenter.reset?.();
|
||||
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);
|
||||
|
||||
await this.requireLeagueAdminPermissions(input.leagueId);
|
||||
|
||||
this.approveLeagueJoinRequestPresenter.reset?.();
|
||||
const result = await this.approveLeagueJoinRequestUseCase.execute(
|
||||
{ leagueId: input.leagueId, joinRequestId: input.requestId },
|
||||
this.approveLeagueJoinRequestPresenter,
|
||||
);
|
||||
|
||||
if (result.isErr()) {
|
||||
const err = result.unwrapErr();
|
||||
|
||||
if (err.code === 'JOIN_REQUEST_NOT_FOUND') {
|
||||
throw new NotFoundException('Join request not found');
|
||||
}
|
||||
|
||||
if (err.code === 'LEAGUE_NOT_FOUND') {
|
||||
throw new NotFoundException('League not found');
|
||||
}
|
||||
|
||||
if (err.code === 'LEAGUE_AT_CAPACITY') {
|
||||
throw new ConflictException('League is at capacity');
|
||||
}
|
||||
|
||||
throw new Error(err.code);
|
||||
}
|
||||
|
||||
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
|
||||
});
|
||||
|
||||
await this.requireLeagueAdminPermissions(input.leagueId);
|
||||
|
||||
this.rejectLeagueJoinRequestPresenter.reset?.();
|
||||
const result = await this.rejectLeagueJoinRequestUseCase.execute(
|
||||
{ leagueId: input.leagueId, joinRequestId: input.requestId },
|
||||
this.rejectLeagueJoinRequestPresenter,
|
||||
);
|
||||
|
||||
if (result.isErr()) {
|
||||
const err = result.unwrapErr();
|
||||
|
||||
if (err.code === 'JOIN_REQUEST_NOT_FOUND') {
|
||||
throw new NotFoundException('Join request not found');
|
||||
}
|
||||
|
||||
if (err.code === 'LEAGUE_NOT_FOUND') {
|
||||
throw new NotFoundException('League not found');
|
||||
}
|
||||
|
||||
if (err.code === 'LEAGUE_AT_CAPACITY') {
|
||||
throw new ConflictException('League is at capacity');
|
||||
}
|
||||
|
||||
throw new Error(err.code);
|
||||
}
|
||||
|
||||
return this.rejectLeagueJoinRequestPresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async approveLeagueRosterJoinRequest(leagueId: string, joinRequestId: string): Promise<ApproveLeagueJoinRequestDTO> {
|
||||
this.logger.debug('Approving roster join request:', { leagueId, joinRequestId });
|
||||
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
this.approveLeagueJoinRequestPresenter.reset?.();
|
||||
const result = await this.approveLeagueJoinRequestUseCase.execute(
|
||||
{ leagueId, joinRequestId },
|
||||
this.approveLeagueJoinRequestPresenter,
|
||||
);
|
||||
|
||||
if (result.isErr()) {
|
||||
const err = result.unwrapErr();
|
||||
|
||||
if (err.code === 'JOIN_REQUEST_NOT_FOUND') {
|
||||
throw new NotFoundException('Join request not found');
|
||||
}
|
||||
|
||||
if (err.code === 'LEAGUE_NOT_FOUND') {
|
||||
throw new NotFoundException('League not found');
|
||||
}
|
||||
|
||||
if (err.code === 'LEAGUE_AT_CAPACITY') {
|
||||
throw new ConflictException('League is at capacity');
|
||||
}
|
||||
|
||||
throw new Error(err.code);
|
||||
}
|
||||
|
||||
return this.approveLeagueJoinRequestPresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async rejectLeagueRosterJoinRequest(leagueId: string, joinRequestId: string): Promise<RejectJoinRequestOutputDTO> {
|
||||
this.logger.debug('Rejecting roster join request:', { leagueId, joinRequestId });
|
||||
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
this.rejectLeagueJoinRequestPresenter.reset?.();
|
||||
const result = await this.rejectLeagueJoinRequestUseCase.execute(
|
||||
{ leagueId, joinRequestId },
|
||||
this.rejectLeagueJoinRequestPresenter,
|
||||
);
|
||||
|
||||
if (result.isErr()) {
|
||||
throw new NotFoundException('Join request not found');
|
||||
}
|
||||
|
||||
return this.rejectLeagueJoinRequestPresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getLeagueAdminPermissions(query: GetLeagueAdminPermissionsInputDTO): Promise<LeagueAdminPermissionsDTO> {
|
||||
this.logger.debug('Getting league admin permissions', { query });
|
||||
await this.getLeagueAdminPermissionsUseCase.execute(query);
|
||||
const actor = this.getActor();
|
||||
|
||||
this.logger.debug('Getting league admin permissions', { leagueId: query.leagueId, performerDriverId: actor.driverId });
|
||||
|
||||
await this.getLeagueAdminPermissionsUseCase.execute({
|
||||
leagueId: query.leagueId,
|
||||
performerDriverId: actor.driverId,
|
||||
});
|
||||
|
||||
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);
|
||||
|
||||
await this.requireLeagueAdminPermissions(input.leagueId);
|
||||
|
||||
this.removeLeagueMemberPresenter.reset?.();
|
||||
const result = await this.removeLeagueMemberUseCase.execute({
|
||||
leagueId: input.leagueId,
|
||||
targetDriverId: input.targetDriverId,
|
||||
});
|
||||
|
||||
if (result.isErr()) {
|
||||
const err = result.unwrapErr();
|
||||
|
||||
if (err.code === 'MEMBERSHIP_NOT_FOUND') {
|
||||
throw new NotFoundException('Member not found');
|
||||
}
|
||||
|
||||
if (err.code === 'CANNOT_REMOVE_LAST_OWNER') {
|
||||
throw new BadRequestException(err.details.message);
|
||||
}
|
||||
|
||||
throw new Error(err.code);
|
||||
}
|
||||
|
||||
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);
|
||||
async updateLeagueMemberRole(
|
||||
leagueId: string,
|
||||
targetDriverId: string,
|
||||
input: UpdateLeagueMemberRoleInputDTO,
|
||||
): Promise<UpdateLeagueMemberRoleOutputDTO> {
|
||||
this.logger.debug('Updating league member role', {
|
||||
leagueId,
|
||||
targetDriverId,
|
||||
newRole: input.newRole,
|
||||
});
|
||||
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
this.updateLeagueMemberRolePresenter.reset?.();
|
||||
const result = await this.updateLeagueMemberRoleUseCase.execute({
|
||||
leagueId,
|
||||
targetDriverId,
|
||||
newRole: input.newRole,
|
||||
});
|
||||
|
||||
if (result.isErr()) {
|
||||
const err = result.unwrapErr();
|
||||
|
||||
if (err.code === 'MEMBERSHIP_NOT_FOUND') {
|
||||
throw new NotFoundException('Member not found');
|
||||
}
|
||||
|
||||
if (err.code === 'INVALID_ROLE' || err.code === 'CANNOT_DOWNGRADE_LAST_OWNER') {
|
||||
throw new BadRequestException(err.details.message);
|
||||
}
|
||||
|
||||
throw new Error(err.code);
|
||||
}
|
||||
|
||||
return this.updateLeagueMemberRolePresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
@@ -323,19 +576,166 @@ export class LeagueService {
|
||||
return this.getLeagueMembershipsPresenter.getViewModel()!.memberships;
|
||||
}
|
||||
|
||||
async getLeagueRosterMembers(leagueId: string): Promise<LeagueRosterMemberDTO[]> {
|
||||
this.logger.debug('Getting league roster members (admin)', { leagueId });
|
||||
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
this.getLeagueRosterMembersPresenter.reset?.();
|
||||
const result = await this.getLeagueRosterMembersUseCase.execute({ leagueId });
|
||||
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().code);
|
||||
}
|
||||
|
||||
return this.getLeagueRosterMembersPresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getLeagueRosterJoinRequests(leagueId: string): Promise<LeagueRosterJoinRequestDTO[]> {
|
||||
this.logger.debug('Getting league roster join requests (admin)', { leagueId });
|
||||
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
this.getLeagueRosterJoinRequestsPresenter.reset?.();
|
||||
const result = await this.getLeagueRosterJoinRequestsUseCase.execute({ leagueId });
|
||||
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().code);
|
||||
}
|
||||
|
||||
return this.getLeagueRosterJoinRequestsPresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
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 });
|
||||
async getLeagueSchedule(leagueId: string, query?: GetLeagueScheduleQueryDTO): Promise<LeagueScheduleDTO> {
|
||||
this.logger.debug('Getting league schedule', { leagueId, query });
|
||||
|
||||
const input: GetLeagueScheduleInput = query?.seasonId ? { leagueId, seasonId: query.seasonId } : { leagueId };
|
||||
await this.getLeagueScheduleUseCase.execute(input);
|
||||
|
||||
await this.getLeagueScheduleUseCase.execute({ leagueId });
|
||||
return this.leagueSchedulePresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async publishLeagueSeasonSchedule(
|
||||
leagueId: string,
|
||||
seasonId: string,
|
||||
_input: LeagueSeasonSchedulePublishInputDTO,
|
||||
): Promise<LeagueSeasonSchedulePublishOutputDTO> {
|
||||
void _input;
|
||||
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
this.publishLeagueSeasonSchedulePresenter.reset?.();
|
||||
const result = await this.publishLeagueSeasonScheduleUseCase.execute({ leagueId, seasonId });
|
||||
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().code);
|
||||
}
|
||||
|
||||
return this.publishLeagueSeasonSchedulePresenter.getResponseModel()!;
|
||||
}
|
||||
|
||||
async unpublishLeagueSeasonSchedule(
|
||||
leagueId: string,
|
||||
seasonId: string,
|
||||
_input: LeagueSeasonSchedulePublishInputDTO,
|
||||
): Promise<LeagueSeasonSchedulePublishOutputDTO> {
|
||||
void _input;
|
||||
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
this.unpublishLeagueSeasonSchedulePresenter.reset?.();
|
||||
const result = await this.unpublishLeagueSeasonScheduleUseCase.execute({ leagueId, seasonId });
|
||||
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().code);
|
||||
}
|
||||
|
||||
return this.unpublishLeagueSeasonSchedulePresenter.getResponseModel()!;
|
||||
}
|
||||
|
||||
async createLeagueSeasonScheduleRace(
|
||||
leagueId: string,
|
||||
seasonId: string,
|
||||
input: CreateLeagueScheduleRaceInputDTO,
|
||||
): Promise<CreateLeagueScheduleRaceOutputDTO> {
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
const scheduledAt = new Date(input.scheduledAtIso);
|
||||
if (Number.isNaN(scheduledAt.getTime())) {
|
||||
throw new Error('INVALID_SCHEDULED_AT');
|
||||
}
|
||||
|
||||
this.createLeagueSeasonScheduleRacePresenter.reset?.();
|
||||
const result = await this.createLeagueSeasonScheduleRaceUseCase.execute({
|
||||
leagueId,
|
||||
seasonId,
|
||||
track: input.track,
|
||||
car: input.car,
|
||||
scheduledAt,
|
||||
});
|
||||
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().code);
|
||||
}
|
||||
|
||||
return this.createLeagueSeasonScheduleRacePresenter.getResponseModel()!;
|
||||
}
|
||||
|
||||
async updateLeagueSeasonScheduleRace(
|
||||
leagueId: string,
|
||||
seasonId: string,
|
||||
raceId: string,
|
||||
input: UpdateLeagueScheduleRaceInputDTO,
|
||||
): Promise<LeagueScheduleRaceMutationSuccessDTO> {
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
const scheduledAt =
|
||||
input.scheduledAtIso !== undefined ? new Date(input.scheduledAtIso) : undefined;
|
||||
|
||||
if (scheduledAt && Number.isNaN(scheduledAt.getTime())) {
|
||||
throw new Error('INVALID_SCHEDULED_AT');
|
||||
}
|
||||
|
||||
this.updateLeagueSeasonScheduleRacePresenter.reset?.();
|
||||
const result = await this.updateLeagueSeasonScheduleRaceUseCase.execute({
|
||||
leagueId,
|
||||
seasonId,
|
||||
raceId,
|
||||
...(input.track !== undefined ? { track: input.track } : {}),
|
||||
...(input.car !== undefined ? { car: input.car } : {}),
|
||||
...(scheduledAt !== undefined ? { scheduledAt } : {}),
|
||||
});
|
||||
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().code);
|
||||
}
|
||||
|
||||
return this.updateLeagueSeasonScheduleRacePresenter.getResponseModel()!;
|
||||
}
|
||||
|
||||
async deleteLeagueSeasonScheduleRace(
|
||||
leagueId: string,
|
||||
seasonId: string,
|
||||
raceId: string,
|
||||
): Promise<LeagueScheduleRaceMutationSuccessDTO> {
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
this.deleteLeagueSeasonScheduleRacePresenter.reset?.();
|
||||
const result = await this.deleteLeagueSeasonScheduleRaceUseCase.execute({ leagueId, seasonId, raceId });
|
||||
|
||||
if (result.isErr()) {
|
||||
throw new Error(result.unwrapErr().code);
|
||||
}
|
||||
|
||||
return this.deleteLeagueSeasonScheduleRacePresenter.getResponseModel()!;
|
||||
}
|
||||
|
||||
async getLeagueStats(leagueId: string): Promise<LeagueStatsDTO> {
|
||||
this.logger.debug('Getting league stats', { leagueId });
|
||||
await this.getLeagueStatsUseCase.execute({ leagueId });
|
||||
@@ -408,17 +808,27 @@ export class LeagueService {
|
||||
return this.leagueScoringPresetsPresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async joinLeague(leagueId: string, driverId: string): Promise<JoinLeagueOutputDTO> {
|
||||
this.logger.debug('Joining league', { leagueId, driverId });
|
||||
async joinLeague(leagueId: string): Promise<JoinLeagueOutputDTO> {
|
||||
const actor = this.getActor();
|
||||
this.logger.debug('Joining league', { leagueId, actorDriverId: actor.driverId });
|
||||
|
||||
await this.joinLeagueUseCase.execute({ leagueId, driverId });
|
||||
await this.joinLeagueUseCase.execute({ leagueId, driverId: actor.driverId });
|
||||
return this.joinLeaguePresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async transferLeagueOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<TransferLeagueOwnershipOutputDTO> {
|
||||
this.logger.debug('Transferring league ownership', { leagueId, currentOwnerId, newOwnerId });
|
||||
async transferLeagueOwnership(leagueId: string, input: TransferLeagueOwnershipInputDTO): Promise<TransferLeagueOwnershipOutputDTO> {
|
||||
this.logger.debug('Transferring league ownership', { leagueId, newOwnerId: input.newOwnerId });
|
||||
|
||||
await this.requireLeagueAdminPermissions(leagueId);
|
||||
|
||||
const actor = this.getActor();
|
||||
|
||||
await this.transferLeagueOwnershipUseCase.execute({
|
||||
leagueId,
|
||||
currentOwnerId: actor.driverId,
|
||||
newOwnerId: input.newOwnerId,
|
||||
});
|
||||
|
||||
await this.transferLeagueOwnershipUseCase.execute({ leagueId, currentOwnerId, newOwnerId });
|
||||
return this.transferLeagueOwnershipPresenter.getViewModel()!;
|
||||
}
|
||||
|
||||
@@ -444,15 +854,22 @@ export class LeagueService {
|
||||
return this.getLeagueWalletPresenter.getResponseModel();
|
||||
}
|
||||
|
||||
async withdrawFromLeagueWallet(leagueId: string, input: WithdrawFromLeagueWalletInputDTO): Promise<WithdrawFromLeagueWalletOutputDTO> {
|
||||
async withdrawFromLeagueWallet(
|
||||
leagueId: string,
|
||||
input: WithdrawFromLeagueWalletInputDTO,
|
||||
): Promise<WithdrawFromLeagueWalletOutputDTO> {
|
||||
this.logger.debug('Withdrawing from league wallet', { leagueId, amount: input.amount });
|
||||
|
||||
const actor = this.getActor();
|
||||
|
||||
await this.withdrawFromLeagueWalletUseCase.execute({
|
||||
leagueId,
|
||||
requestedById: "admin",
|
||||
requestedById: actor.driverId,
|
||||
amount: input.amount,
|
||||
currency: input.currency as 'USD' | 'EUR' | 'GBP',
|
||||
reason: input.destinationAccount,
|
||||
});
|
||||
|
||||
return this.withdrawFromLeagueWalletPresenter.getResponseModel();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user