refactor
This commit is contained in:
237
apps/api/src/domain/league/LeagueService.ts
Normal file
237
apps/api/src/domain/league/LeagueService.ts
Normal file
@@ -0,0 +1,237 @@
|
||||
import { Injectable, Inject } from '@nestjs/common';
|
||||
import { AllLeaguesWithCapacityViewModel, LeagueStatsDto, LeagueJoinRequestViewModel, ApproveJoinRequestInput, ApproveJoinRequestOutput, RejectJoinRequestInput, RejectJoinRequestOutput, LeagueAdminPermissionsViewModel, RemoveLeagueMemberInput, RemoveLeagueMemberOutput, UpdateLeagueMemberRoleInput, UpdateLeagueMemberRoleOutput, LeagueOwnerSummaryViewModel, LeagueConfigFormModelDto, LeagueAdminProtestsViewModel, LeagueSeasonSummaryViewModel, GetLeagueAdminPermissionsInput, GetLeagueProtestsQuery, GetLeagueSeasonsQuery, GetLeagueAdminConfigQuery, GetLeagueOwnerSummaryQuery, LeagueMembershipsViewModel, LeagueStandingsViewModel, LeagueScheduleViewModel, LeagueStatsViewModel, LeagueAdminViewModel, CreateLeagueInput, CreateLeagueOutput } from './dto/LeagueDto';
|
||||
|
||||
// Core imports
|
||||
import type { Logger } from '@core/shared/application/Logger';
|
||||
|
||||
// Use cases
|
||||
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
|
||||
import { GetLeagueStandingsUseCase } from '@core/racing/application/use-cases/GetLeagueStandingsUseCase';
|
||||
import { GetLeagueStatsUseCase } from '@core/racing/application/use-cases/GetLeagueStatsUseCase';
|
||||
import { GetLeagueFullConfigUseCase } from '@core/racing/application/use-cases/GetLeagueFullConfigUseCase';
|
||||
import { CreateLeagueWithSeasonAndScoringUseCase } from '@core/racing/application/use-cases/CreateLeagueWithSeasonAndScoringUseCase';
|
||||
import { GetRaceProtestsUseCase } from '@core/racing/application/use-cases/GetRaceProtestsUseCase';
|
||||
import { GetTotalLeaguesUseCase } from '@core/racing/application/use-cases/GetTotalLeaguesUseCase';
|
||||
import { GetLeagueJoinRequestsUseCase } from '@core/racing/application/use-cases/GetLeagueJoinRequestsUseCase';
|
||||
import { ApproveLeagueJoinRequestUseCase } from '@core/racing/application/use-cases/ApproveLeagueJoinRequestUseCase';
|
||||
import { RejectLeagueJoinRequestUseCase } from '@core/racing/application/use-cases/RejectLeagueJoinRequestUseCase';
|
||||
import { RemoveLeagueMemberUseCase } from '@core/racing/application/use-cases/RemoveLeagueMemberUseCase';
|
||||
import { UpdateLeagueMemberRoleUseCase } from '@core/racing/application/use-cases/UpdateLeagueMemberRoleUseCase';
|
||||
import { GetLeagueOwnerSummaryUseCase } from '@core/racing/application/use-cases/GetLeagueOwnerSummaryUseCase';
|
||||
import { GetLeagueProtestsUseCase } from '@core/racing/application/use-cases/GetLeagueProtestsUseCase';
|
||||
import { GetLeagueSeasonsUseCase } from '@core/racing/application/use-cases/GetLeagueSeasonsUseCase';
|
||||
import { GetLeagueMembershipsUseCase } from '@core/racing/application/use-cases/GetLeagueMembershipsUseCase';
|
||||
import { GetLeagueScheduleUseCase } from '@core/racing/application/use-cases/GetLeagueScheduleUseCase';
|
||||
import { GetLeagueAdminPermissionsUseCase } from '@core/racing/application/use-cases/GetLeagueAdminPermissionsUseCase';
|
||||
|
||||
// API Presenters
|
||||
import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter';
|
||||
import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter';
|
||||
import { LeagueJoinRequestsPresenter } from './presenters/LeagueJoinRequestsPresenter';
|
||||
import { ApproveLeagueJoinRequestPresenter } from './presenters/ApproveLeagueJoinRequestPresenter';
|
||||
import { RejectLeagueJoinRequestPresenter } from './presenters/RejectLeagueJoinRequestPresenter';
|
||||
import { RemoveLeagueMemberPresenter } from './presenters/RemoveLeagueMemberPresenter';
|
||||
import { UpdateLeagueMemberRolePresenter } from './presenters/UpdateLeagueMemberRolePresenter';
|
||||
import { GetLeagueOwnerSummaryPresenter } from './presenters/GetLeagueOwnerSummaryPresenter';
|
||||
import { GetLeagueProtestsPresenter } from './presenters/GetLeagueProtestsPresenter';
|
||||
import { GetLeagueSeasonsPresenter } from './presenters/GetLeagueSeasonsPresenter';
|
||||
import { GetLeagueMembershipsPresenter } from './presenters/GetLeagueMembershipsPresenter';
|
||||
import { LeagueSchedulePresenter } from './presenters/LeagueSchedulePresenter';
|
||||
import { TotalLeaguesPresenter } from './presenters/TotalLeaguesPresenter';
|
||||
import { LeagueConfigPresenter } from './presenters/LeagueConfigPresenter';
|
||||
import { LeagueStatsPresenter } from './presenters/LeagueStatsPresenter';
|
||||
import { GetLeagueAdminPermissionsPresenter } from './presenters/GetLeagueAdminPermissionsPresenter';
|
||||
|
||||
// Tokens
|
||||
import { LOGGER_TOKEN } from './LeagueProviders';
|
||||
|
||||
@Injectable()
|
||||
export class LeagueService {
|
||||
constructor(
|
||||
private readonly getAllLeaguesWithCapacityUseCase: GetAllLeaguesWithCapacityUseCase,
|
||||
private readonly getLeagueStandingsUseCase: GetLeagueStandingsUseCase,
|
||||
private readonly getLeagueStatsUseCase: GetLeagueStatsUseCase,
|
||||
private readonly getLeagueFullConfigUseCase: GetLeagueFullConfigUseCase,
|
||||
private readonly createLeagueWithSeasonAndScoringUseCase: CreateLeagueWithSeasonAndScoringUseCase,
|
||||
private readonly getRaceProtestsUseCase: GetRaceProtestsUseCase,
|
||||
private readonly getTotalLeaguesUseCase: GetTotalLeaguesUseCase,
|
||||
private readonly getLeagueJoinRequestsUseCase: GetLeagueJoinRequestsUseCase,
|
||||
private readonly approveLeagueJoinRequestUseCase: ApproveLeagueJoinRequestUseCase,
|
||||
private readonly rejectLeagueJoinRequestUseCase: RejectLeagueJoinRequestUseCase,
|
||||
private readonly removeLeagueMemberUseCase: RemoveLeagueMemberUseCase,
|
||||
private readonly updateLeagueMemberRoleUseCase: UpdateLeagueMemberRoleUseCase,
|
||||
private readonly getLeagueOwnerSummaryUseCase: GetLeagueOwnerSummaryUseCase,
|
||||
private readonly getLeagueProtestsUseCase: GetLeagueProtestsUseCase,
|
||||
private readonly getLeagueSeasonsUseCase: GetLeagueSeasonsUseCase,
|
||||
private readonly getLeagueMembershipsUseCase: GetLeagueMembershipsUseCase,
|
||||
private readonly getLeagueScheduleUseCase: GetLeagueScheduleUseCase,
|
||||
private readonly getLeagueAdminPermissionsUseCase: GetLeagueAdminPermissionsUseCase,
|
||||
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
|
||||
) {}
|
||||
|
||||
async getAllLeaguesWithCapacity(): Promise<AllLeaguesWithCapacityViewModel> {
|
||||
this.logger.debug('[LeagueService] Fetching all leagues with capacity.');
|
||||
|
||||
const presenter = new AllLeaguesWithCapacityPresenter();
|
||||
await this.getAllLeaguesWithCapacityUseCase.execute(undefined, presenter);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getTotalLeagues(): Promise<LeagueStatsDto> {
|
||||
this.logger.debug('[LeagueService] Fetching total leagues count.');
|
||||
const presenter = new TotalLeaguesPresenter();
|
||||
await this.getTotalLeaguesUseCase.execute({}, presenter);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getLeagueJoinRequests(leagueId: string): Promise<LeagueJoinRequestViewModel[]> {
|
||||
this.logger.debug(`[LeagueService] Fetching join requests for league: ${leagueId}.`);
|
||||
const presenter = new LeagueJoinRequestsPresenter();
|
||||
await this.getLeagueJoinRequestsUseCase.execute({ leagueId }, presenter);
|
||||
return presenter.getViewModel()!.joinRequests;
|
||||
}
|
||||
|
||||
async approveLeagueJoinRequest(input: ApproveJoinRequestInput): Promise<ApproveJoinRequestOutput> {
|
||||
this.logger.debug('Approving join request:', input);
|
||||
const presenter = new ApproveLeagueJoinRequestPresenter();
|
||||
await this.approveLeagueJoinRequestUseCase.execute({ leagueId: input.leagueId, requestId: input.requestId }, presenter);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async rejectLeagueJoinRequest(input: RejectJoinRequestInput): Promise<RejectJoinRequestOutput> {
|
||||
this.logger.debug('Rejecting join request:', input);
|
||||
const presenter = new RejectLeagueJoinRequestPresenter();
|
||||
await this.rejectLeagueJoinRequestUseCase.execute({ requestId: input.requestId }, presenter);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getLeagueAdminPermissions(query: GetLeagueAdminPermissionsInput): Promise<LeagueAdminPermissionsViewModel> {
|
||||
this.logger.debug('Getting league admin permissions', { query });
|
||||
const presenter = new GetLeagueAdminPermissionsPresenter();
|
||||
await this.getLeagueAdminPermissionsUseCase.execute(
|
||||
{ leagueId: query.leagueId, performerDriverId: query.performerDriverId },
|
||||
presenter
|
||||
);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async removeLeagueMember(input: RemoveLeagueMemberInput): Promise<RemoveLeagueMemberOutput> {
|
||||
this.logger.debug('Removing league member', { leagueId: input.leagueId, targetDriverId: input.targetDriverId });
|
||||
const presenter = new RemoveLeagueMemberPresenter();
|
||||
await this.removeLeagueMemberUseCase.execute({ leagueId: input.leagueId, targetDriverId: input.targetDriverId }, presenter);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async updateLeagueMemberRole(input: UpdateLeagueMemberRoleInput): Promise<UpdateLeagueMemberRoleOutput> {
|
||||
this.logger.debug('Updating league member role', { leagueId: input.leagueId, targetDriverId: input.targetDriverId, newRole: input.newRole });
|
||||
const presenter = new UpdateLeagueMemberRolePresenter();
|
||||
await this.updateLeagueMemberRoleUseCase.execute({ leagueId: input.leagueId, targetDriverId: input.targetDriverId, newRole: input.newRole }, presenter);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getLeagueOwnerSummary(query: GetLeagueOwnerSummaryQuery): Promise<LeagueOwnerSummaryViewModel | null> {
|
||||
this.logger.debug('Getting league owner summary:', query);
|
||||
const presenter = new GetLeagueOwnerSummaryPresenter();
|
||||
await this.getLeagueOwnerSummaryUseCase.execute({ ownerId: query.ownerId }, presenter);
|
||||
return presenter.getViewModel()!.summary;
|
||||
}
|
||||
|
||||
async getLeagueFullConfig(query: GetLeagueAdminConfigQuery): Promise<LeagueConfigFormModelDto | null> {
|
||||
this.logger.debug('Getting league full config', { query });
|
||||
|
||||
const presenter = new LeagueConfigPresenter();
|
||||
try {
|
||||
await this.getLeagueFullConfigUseCase.execute({ leagueId: query.leagueId }, presenter);
|
||||
return presenter.viewModel;
|
||||
} catch (error) {
|
||||
this.logger.error('Error getting league full config', error instanceof Error ? error : new Error(String(error)));
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async getLeagueProtests(query: GetLeagueProtestsQuery): Promise<LeagueAdminProtestsViewModel> {
|
||||
this.logger.debug('Getting league protests:', query);
|
||||
const presenter = new GetLeagueProtestsPresenter();
|
||||
await this.getLeagueProtestsUseCase.execute({ leagueId: query.leagueId }, presenter);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getLeagueSeasons(query: GetLeagueSeasonsQuery): Promise<LeagueSeasonSummaryViewModel[]> {
|
||||
this.logger.debug('Getting league seasons:', query);
|
||||
const presenter = new GetLeagueSeasonsPresenter();
|
||||
await this.getLeagueSeasonsUseCase.execute({ leagueId: query.leagueId }, presenter);
|
||||
return presenter.getViewModel()!.seasons;
|
||||
}
|
||||
|
||||
async getLeagueMemberships(leagueId: string): Promise<LeagueMembershipsViewModel> {
|
||||
this.logger.debug('Getting league memberships', { leagueId });
|
||||
const presenter = new GetLeagueMembershipsPresenter();
|
||||
await this.getLeagueMembershipsUseCase.execute({ leagueId }, presenter);
|
||||
return presenter.apiViewModel!;
|
||||
}
|
||||
|
||||
async getLeagueStandings(leagueId: string): Promise<LeagueStandingsViewModel> {
|
||||
this.logger.debug('Getting league standings', { leagueId });
|
||||
|
||||
const presenter = new LeagueStandingsPresenter();
|
||||
await this.getLeagueStandingsUseCase.execute({ leagueId }, presenter);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getLeagueSchedule(leagueId: string): Promise<LeagueScheduleViewModel> {
|
||||
this.logger.debug('Getting league schedule', { leagueId });
|
||||
const presenter = new LeagueSchedulePresenter();
|
||||
await this.getLeagueScheduleUseCase.execute({ leagueId }, presenter);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getLeagueStats(leagueId: string): Promise<LeagueStatsViewModel> {
|
||||
this.logger.debug('Getting league stats', { leagueId });
|
||||
const presenter = new LeagueStatsPresenter();
|
||||
await this.getLeagueStatsUseCase.execute({ leagueId }, presenter);
|
||||
return presenter.getViewModel()!;
|
||||
}
|
||||
|
||||
async getLeagueAdmin(leagueId: string): Promise<LeagueAdminViewModel> {
|
||||
this.logger.debug('Getting league admin data', { leagueId });
|
||||
// For now, we'll keep the orchestration in the service since it combines multiple use cases
|
||||
// TODO: Create a composite use case that handles all the admin data fetching
|
||||
const joinRequests = await this.getLeagueJoinRequests(leagueId);
|
||||
const config = await this.getLeagueFullConfig({ leagueId });
|
||||
const protests = await this.getLeagueProtests({ leagueId });
|
||||
const seasons = await this.getLeagueSeasons({ leagueId });
|
||||
|
||||
// Get owner summary - we need the ownerId, so we use a simple approach for now
|
||||
// In a full implementation, we'd have a use case that gets league basic info
|
||||
const ownerSummary = config ? await this.getLeagueOwnerSummary({ ownerId: 'placeholder', leagueId }) : null;
|
||||
|
||||
return {
|
||||
joinRequests,
|
||||
ownerSummary,
|
||||
config: { form: config },
|
||||
protests,
|
||||
seasons,
|
||||
};
|
||||
}
|
||||
|
||||
async createLeague(input: CreateLeagueInput): Promise<CreateLeagueOutput> {
|
||||
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,
|
||||
};
|
||||
const result = await this.createLeagueWithSeasonAndScoringUseCase.execute(command);
|
||||
return {
|
||||
leagueId: result.leagueId,
|
||||
success: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user