module cleanup

This commit is contained in:
2025-12-19 01:22:45 +01:00
parent d617654928
commit d0fac9e6c1
135 changed files with 5104 additions and 1315 deletions

View File

@@ -1,37 +1,34 @@
import { Controller, Get, Post, Patch, Body, Param } from '@nestjs/common';
import { ApiTags, ApiResponse, ApiOperation, ApiBody } from '@nestjs/swagger';
import { Body, Controller, Get, Param, Patch, Post } from '@nestjs/common';
import { ApiBody, ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
import { LeagueService } from './LeagueService';
import { AllLeaguesWithCapacityDTO } from './dtos/AllLeaguesWithCapacityDTO';
import { LeagueStatsDTO } from './dtos/LeagueStatsDTO';
import { LeagueJoinRequestDTO } from './dtos/LeagueJoinRequestDTO';
import { ApproveJoinRequestInputDTO } from './dtos/ApproveJoinRequestInputDTO';
import { ApproveJoinRequestOutputDTO } from './dtos/ApproveJoinRequestOutputDTO';
import { CreateLeagueInputDTO } from './dtos/CreateLeagueInputDTO';
import { CreateLeagueOutputDTO } from './dtos/CreateLeagueOutputDTO';
import { GetLeagueRacesOutputDTO } from './dtos/GetLeagueRacesOutputDTO';
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 { LeagueJoinRequestDTO } from './dtos/LeagueJoinRequestDTO';
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 { LeagueAdminPermissionsDTO } from './dtos/LeagueAdminPermissionsDTO';
import { RemoveLeagueMemberInputDTO } from './dtos/RemoveLeagueMemberInputDTO';
import { RemoveLeagueMemberOutputDTO } from './dtos/RemoveLeagueMemberOutputDTO';
import { UpdateLeagueMemberRoleInputDTO } from './dtos/UpdateLeagueMemberRoleInputDTO';
import { UpdateLeagueMemberRoleOutputDTO } from './dtos/UpdateLeagueMemberRoleOutputDTO';
import { LeagueOwnerSummaryDTO } from './dtos/LeagueOwnerSummaryDTO';
import { LeagueConfigFormModelDTO } from './dtos/LeagueConfigFormModelDTO';
import { LeagueAdminProtestsDTO } from './dtos/LeagueAdminProtestsDTO';
import { LeagueSeasonSummaryDTO } from './dtos/LeagueSeasonSummaryDTO';
import { LeagueMembershipsDTO } from './dtos/LeagueMembershipsDTO';
import { LeagueStandingsDTO } from './dtos/LeagueStandingsDTO';
import { LeagueScheduleDTO } from './dtos/LeagueScheduleDTO';
import { LeagueStatsDTO } from './dtos/LeagueStatsDTO';
import { LeagueAdminDTO } from './dtos/LeagueAdminDTO';
import { CreateLeagueInputDTO } from './dtos/CreateLeagueInputDTO';
import { CreateLeagueOutputDTO } from './dtos/CreateLeagueOutputDTO';
import { GetLeagueAdminPermissionsInputDTO } from './dtos/GetLeagueAdminPermissionsInputDTO';
import { GetLeagueJoinRequestsQueryDTO } from './dtos/GetLeagueJoinRequestsQueryDTO';
import { GetLeagueOwnerSummaryQueryDTO } from './dtos/GetLeagueOwnerSummaryQueryDTO';
import { GetLeagueAdminConfigQueryDTO } from './dtos/GetLeagueAdminConfigQueryDTO';
import { GetLeagueProtestsQueryDTO } from './dtos/GetLeagueProtestsQueryDTO';
import { GetLeagueSeasonsQueryDTO } from './dtos/GetLeagueSeasonsQueryDTO';
import { GetLeagueAdminConfigQueryDTO } from './dtos/GetLeagueAdminConfigQueryDTO';
import { GetLeagueOwnerSummaryQueryDTO } from './dtos/GetLeagueOwnerSummaryQueryDTO';
import { GetSeasonSponsorshipsOutputDTO } from './dtos/GetSeasonSponsorshipsOutputDTO';
import { GetLeagueRacesOutputDTO } from './dtos/GetLeagueRacesOutputDTO';
@ApiTags('leagues')
@Controller('leagues')
@@ -104,8 +101,7 @@ export class LeagueController {
async removeLeagueMember(
@Param('leagueId') leagueId: string,
@Param('performerDriverId') performerDriverId: string,
@Param('targetDriverId') targetDriverId: string,
@Body() input: RemoveLeagueMemberInputDTO, // Body content for a patch often includes IDs
@Param('targetDriverId') targetDriverId: string, // Body content for a patch often includes IDs
): Promise<RemoveLeagueMemberOutputDTO> {
return this.leagueService.removeLeagueMember({ leagueId, performerDriverId, targetDriverId });
}
@@ -133,27 +129,27 @@ export class LeagueController {
@Param('leagueId') leagueId: string,
@Param('ownerId') ownerId: string,
): Promise<LeagueOwnerSummaryDTO | null> {
const query: GetLeagueOwnerSummaryQuery = { ownerId, leagueId };
const query: GetLeagueOwnerSummaryQueryDTO = { ownerId, leagueId };
return this.leagueService.getLeagueOwnerSummary(query);
}
@Get(':leagueId/config')
@ApiOperation({ summary: 'Get league full configuration' })
@ApiResponse({ status: 200, description: 'League configuration form model', type: LeagueConfigFormModelDTO })
async getLeagueFullConfig(
@Param('leagueId') leagueId: string,
): Promise<LeagueConfigFormModelDTO | null> {
const query: GetLeagueAdminConfigQuery = { leagueId };
return this.leagueService.getLeagueFullConfig(query);
}
@ApiOperation({ summary: 'Get league full configuration' })
@ApiResponse({ status: 200, description: 'League configuration form model', type: LeagueConfigFormModelDTO })
async getLeagueFullConfig(
@Param('leagueId') leagueId: string,
): Promise<LeagueConfigFormModelDTO | null> {
const query: GetLeagueAdminConfigQueryDTO = { leagueId };
return this.leagueService.getLeagueFullConfig(query);
}
@Get(':leagueId/protests')
@ApiOperation({ summary: 'Get protests for a league' })
@ApiResponse({ status: 200, description: 'List of protests for the league', type: LeagueAdminProtestsDTO })
async getLeagueProtests(@Param('leagueId') leagueId: string): Promise<LeagueAdminProtestsDTO> {
const query: GetLeagueProtestsQuery = { leagueId };
return this.leagueService.getLeagueProtests(query);
}
@ApiOperation({ summary: 'Get protests for a league' })
@ApiResponse({ status: 200, description: 'List of protests for the league', type: LeagueAdminProtestsDTO })
async getLeagueProtests(@Param('leagueId') leagueId: string): Promise<LeagueAdminProtestsDTO> {
const query: GetLeagueProtestsQueryDTO = { leagueId };
return this.leagueService.getLeagueProtests(query);
}
@Get(':leagueId/protests/:protestId')
@ApiOperation({ summary: 'Get a specific protest for a league' })
@@ -162,7 +158,7 @@ export class LeagueController {
@Param('leagueId') leagueId: string,
@Param('protestId') protestId: string,
): Promise<LeagueAdminProtestsDTO> {
const query: GetLeagueProtestsQuery = { leagueId };
const query: GetLeagueProtestsQueryDTO = { leagueId };
const allProtests = await this.leagueService.getLeagueProtests(query);
// Filter to only include the specific protest
@@ -187,12 +183,12 @@ export class LeagueController {
}
@Get(':leagueId/seasons')
@ApiOperation({ summary: 'Get seasons for a league' })
@ApiResponse({ status: 200, description: 'List of seasons for the league', type: [LeagueSeasonSummaryDTO] })
async getLeagueSeasons(@Param('leagueId') leagueId: string): Promise<LeagueSeasonSummaryDTO[]> {
const query: GetLeagueSeasonsQuery = { leagueId };
return this.leagueService.getLeagueSeasons(query);
}
@ApiOperation({ summary: 'Get seasons for a league' })
@ApiResponse({ status: 200, description: 'List of seasons for the league', type: [LeagueSeasonSummaryDTO] })
async getLeagueSeasons(@Param('leagueId') leagueId: string): Promise<LeagueSeasonSummaryDTO[]> {
const query: GetLeagueSeasonsQueryDTO = { leagueId };
return this.leagueService.getLeagueSeasons(query);
}
@Get(':leagueId/memberships')
@ApiOperation({ summary: 'Get league memberships' })

View File

@@ -19,7 +19,8 @@ import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
// Import use cases
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
import { GetLeagueStandingsUseCase } from '@core/racing/application/use-cases/GetLeagueStandingsUseCase';
import { GetLeagueStandingsUseCase } from '@core/league/application/use-cases/GetLeagueStandingsUseCase';
import { GetLeagueStandingsUseCaseImpl } from '@core/league/application/use-cases/GetLeagueStandingsUseCaseImpl';
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';
@@ -49,6 +50,7 @@ export const PROTEST_REPOSITORY_TOKEN = 'IProtestRepository';
export const RACE_REPOSITORY_TOKEN = 'IRaceRepository';
export const DRIVER_REPOSITORY_TOKEN = 'IDriverRepository';
export const LOGGER_TOKEN = 'Logger'; // Already defined in AuthProviders, but good to have here too
export const GET_LEAGUE_STANDINGS_USE_CASE = 'GetLeagueStandingsUseCase';
export const LeagueProviders: Provider[] = [
LeagueService, // Provide the service itself
@@ -108,7 +110,10 @@ export const LeagueProviders: Provider[] = [
},
// Use cases
GetAllLeaguesWithCapacityUseCase,
GetLeagueStandingsUseCase,
{
provide: GET_LEAGUE_STANDINGS_USE_CASE,
useClass: GetLeagueStandingsUseCaseImpl,
},
GetLeagueStatsUseCase,
GetLeagueFullConfigUseCase,
CreateLeagueWithSeasonAndScoringUseCase,

View File

@@ -1,81 +1,111 @@
import { Injectable, Inject } from '@nestjs/common';
import { Inject, Injectable } from '@nestjs/common';
import { AllLeaguesWithCapacityDTO } from './dtos/AllLeaguesWithCapacityDTO';
import { LeagueStatsDTO } from './dtos/LeagueStatsDTO';
import { LeagueJoinRequestDTO } from './dtos/LeagueJoinRequestDTO';
import { ApproveJoinRequestInputDTO } from './dtos/ApproveJoinRequestInputDTO';
import { ApproveJoinRequestOutputDTO } from './dtos/ApproveJoinRequestOutputDTO';
import { CreateLeagueInputDTO } from './dtos/CreateLeagueInputDTO';
import { CreateLeagueOutputDTO } from './dtos/CreateLeagueOutputDTO';
import { JoinLeagueOutputDTO } from './dtos/JoinLeagueOutputDTO';
import { TransferLeagueOwnershipOutputDTO } from './dtos/TransferLeagueOwnershipOutputDTO';
import { LeagueJoinRequestWithDriverDTO } from './dtos/LeagueJoinRequestWithDriverDTO';
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 { GetSeasonSponsorshipsOutputDTO } from './dtos/GetSeasonSponsorshipsOutputDTO';
import { LeagueAdminDTO } from './dtos/LeagueAdminDTO';
import { LeagueAdminProtestsDTO } from './dtos/LeagueAdminProtestsDTO';
import { LeagueConfigFormModelDTO } from './dtos/LeagueConfigFormModelDTO';
import { LeagueJoinRequestDTO } from './dtos/LeagueJoinRequestDTO';
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 { LeagueAdminPermissionsDTO } from './dtos/LeagueAdminPermissionsDTO';
import { RemoveLeagueMemberInputDTO } from './dtos/RemoveLeagueMemberInputDTO';
import { RemoveLeagueMemberOutputDTO } from './dtos/RemoveLeagueMemberOutputDTO';
import { UpdateLeagueMemberRoleInputDTO } from './dtos/UpdateLeagueMemberRoleInputDTO';
import { UpdateLeagueMemberRoleOutputDTO } from './dtos/UpdateLeagueMemberRoleOutputDTO';
import { LeagueOwnerSummaryDTO } from './dtos/LeagueOwnerSummaryDTO';
import { LeagueConfigFormModelDTO } from './dtos/LeagueConfigFormModelDTO';
import { LeagueAdminProtestsDTO } from './dtos/LeagueAdminProtestsDTO';
import { LeagueSeasonSummaryDTO } from './dtos/LeagueSeasonSummaryDTO';
import { GetLeagueAdminPermissionsInputDTO } from './dtos/GetLeagueAdminPermissionsInputDTO';
import { GetLeagueProtestsQueryDTO } from './dtos/GetLeagueProtestsQueryDTO';
import { GetLeagueSeasonsQueryDTO } from './dtos/GetLeagueSeasonsQueryDTO';
import { GetLeagueAdminConfigQueryDTO } from './dtos/GetLeagueAdminConfigQueryDTO';
import { GetLeagueOwnerSummaryQueryDTO } from './dtos/GetLeagueOwnerSummaryQueryDTO';
import { LeagueMembershipsDTO } from './dtos/LeagueMembershipsDTO';
import { LeagueStandingsDTO } from './dtos/LeagueStandingsDTO';
import { LeagueScheduleDTO } from './dtos/LeagueScheduleDTO';
import { LeagueStatsDTO } from './dtos/LeagueStatsDTO';
import { LeagueAdminDTO } from './dtos/LeagueAdminDTO';
import { CreateLeagueInputDTO } from './dtos/CreateLeagueInputDTO';
import { CreateLeagueOutputDTO } from './dtos/CreateLeagueOutputDTO';
import { GetSeasonSponsorshipsOutputDTO } from './dtos/GetSeasonSponsorshipsOutputDTO';
import { GetLeagueRacesOutputDTO } from './dtos/GetLeagueRacesOutputDTO';
// Core imports for entities
import type { League } from '@core/racing/domain/entities/League';
// Core imports for view models
import type { LeagueScoringConfigViewModel } from '@core/racing/application/presenters/ILeagueScoringConfigPresenter';
import type { LeagueScoringPresetsViewModel } from '@core/racing/application/presenters/ILeagueScoringPresetsPresenter';
import type { AllLeaguesWithCapacityViewModel } from '@core/racing/application/presenters/IAllLeaguesWithCapacityPresenter';
import type { GetTotalLeaguesViewModel } from '@core/racing/application/presenters/IGetTotalLeaguesPresenter';
import type { GetLeagueJoinRequestsViewModel } from '@core/racing/application/presenters/IGetLeagueJoinRequestsPresenter';
import type { ApproveLeagueJoinRequestViewModel } from '@core/racing/application/presenters/IApproveLeagueJoinRequestPresenter';
import type { RejectLeagueJoinRequestViewModel } from '@core/racing/application/presenters/IRejectLeagueJoinRequestPresenter';
import type { GetLeagueAdminPermissionsViewModel } from '@core/racing/application/presenters/IGetLeagueAdminPermissionsPresenter';
import type { RemoveLeagueMemberViewModel } from '@core/racing/application/presenters/IRemoveLeagueMemberPresenter';
import type { UpdateLeagueMemberRoleViewModel } from '@core/racing/application/presenters/IUpdateLeagueMemberRolePresenter';
import type { GetLeagueOwnerSummaryViewModel } from '@core/racing/application/presenters/IGetLeagueOwnerSummaryPresenter';
import type { GetLeagueProtestsViewModel } from '@core/racing/application/presenters/IGetLeagueProtestsPresenter';
import type { GetLeagueSeasonsViewModel } from '@core/racing/application/presenters/IGetLeagueSeasonsPresenter';
import type { GetLeagueMembershipsViewModel } from '@core/racing/application/presenters/IGetLeagueMembershipsPresenter';
import type { LeagueStandingsViewModel } from '@core/racing/application/presenters/ILeagueStandingsPresenter';
import type { LeagueScheduleViewModel } from '@core/racing/application/presenters/ILeagueSchedulePresenter';
import type { LeagueStatsViewModel } from '@core/racing/application/presenters/ILeagueStatsPresenter';
import type { LeagueConfigFormViewModel } from '@core/racing/application/presenters/ILeagueFullConfigPresenter';
import type { CreateLeagueViewModel } from '@core/racing/application/presenters/ICreateLeaguePresenter';
import type { JoinLeagueViewModel } from '@core/racing/application/presenters/IJoinLeaguePresenter';
import type { TransferLeagueOwnershipViewModel } from '@core/racing/application/presenters/ITransferLeagueOwnershipPresenter';
// 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 { GetLeagueScoringConfigUseCase } from '@core/racing/application/use-cases/GetLeagueScoringConfigUseCase';
import { ListLeagueScoringPresetsUseCase } from '@core/racing/application/use-cases/ListLeagueScoringPresetsUseCase';
import { JoinLeagueUseCase } from '@core/racing/application/use-cases/JoinLeagueUseCase';
import { TransferLeagueOwnershipUseCase } from '@core/racing/application/use-cases/TransferLeagueOwnershipUseCase';
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 { GetLeagueStandingsUseCase } from '@core/league/application/use-cases/GetLeagueStandingsUseCase';
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 { 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 { 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';
import { GetLeagueScoringConfigUseCase } from '@core/racing/application/use-cases/GetLeagueScoringConfigUseCase';
import { GetLeagueSeasonsUseCase } from '@core/racing/application/use-cases/GetLeagueSeasonsUseCase';
import { GetLeagueStatsUseCase } from '@core/racing/application/use-cases/GetLeagueStatsUseCase';
import { GetRaceProtestsUseCase } from '@core/racing/application/use-cases/GetRaceProtestsUseCase';
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';
// API Presenters
import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter';
import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter';
import { TotalLeaguesPresenter } from './presenters/TotalLeaguesPresenter';
import { LeagueScoringConfigPresenter } from './presenters/LeagueScoringConfigPresenter';
import { LeagueScoringPresetsPresenter } from './presenters/LeagueScoringPresetsPresenter';
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 { 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 { GetLeagueMembershipsPresenter } from './presenters/GetLeagueMembershipsPresenter';
import { LeagueJoinRequestsPresenter } from './presenters/LeagueJoinRequestsPresenter';
import { LeagueSchedulePresenter } from './presenters/LeagueSchedulePresenter';
import { TotalLeaguesPresenter } from './presenters/TotalLeaguesPresenter';
import { LeagueConfigPresenter } from './presenters/LeagueConfigPresenter';
import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter';
import { LeagueStatsPresenter } from './presenters/LeagueStatsPresenter';
import { GetLeagueAdminPermissionsPresenter } from './presenters/GetLeagueAdminPermissionsPresenter';
import { RejectLeagueJoinRequestPresenter } from './presenters/RejectLeagueJoinRequestPresenter';
import { RemoveLeagueMemberPresenter } from './presenters/RemoveLeagueMemberPresenter';
import { UpdateLeagueMemberRolePresenter } from './presenters/UpdateLeagueMemberRolePresenter';
import { CreateLeaguePresenter } from './presenters/CreateLeaguePresenter';
import { JoinLeaguePresenter } from './presenters/JoinLeaguePresenter';
import { TransferLeagueOwnershipPresenter } from './presenters/TransferLeagueOwnershipPresenter';
// Tokens
import { LOGGER_TOKEN } from './LeagueProviders';
@@ -111,127 +141,173 @@ export class LeagueService {
async getAllLeaguesWithCapacity(): Promise<AllLeaguesWithCapacityViewModel> {
this.logger.debug('[LeagueService] Fetching all leagues with capacity.');
const result = await this.getAllLeaguesWithCapacityUseCase.execute();
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new AllLeaguesWithCapacityPresenter();
await this.getAllLeaguesWithCapacityUseCase.execute(undefined, presenter);
presenter.present(result.unwrap());
return presenter.getViewModel()!;
}
async getTotalLeagues(): Promise<LeagueStatsDto> {
async getTotalLeagues(): Promise<GetTotalLeaguesViewModel> {
this.logger.debug('[LeagueService] Fetching total leagues count.');
const result = await this.getTotalLeaguesUseCase.execute();
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new TotalLeaguesPresenter();
await this.getTotalLeaguesUseCase.execute({}, presenter);
presenter.present(result.unwrap());
return presenter.getViewModel()!;
}
async getLeagueJoinRequests(leagueId: string): Promise<LeagueJoinRequestViewModel[]> {
async getLeagueJoinRequests(leagueId: string): Promise<GetLeagueJoinRequestsViewModel> {
this.logger.debug(`[LeagueService] Fetching join requests for league: ${leagueId}.`);
const result = await this.getLeagueJoinRequestsUseCase.execute({ leagueId });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new LeagueJoinRequestsPresenter();
await this.getLeagueJoinRequestsUseCase.execute({ leagueId }, presenter);
return presenter.getViewModel()!.joinRequests;
presenter.present(result.unwrap());
return presenter.getViewModel();
}
async approveLeagueJoinRequest(input: ApproveJoinRequestInput): Promise<ApproveJoinRequestOutput> {
async approveLeagueJoinRequest(input: ApproveJoinRequestInputDTO): Promise<ApproveLeagueJoinRequestViewModel> {
this.logger.debug('Approving join request:', input);
const result = await this.approveLeagueJoinRequestUseCase.execute({ leagueId: input.leagueId, requestId: input.requestId });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new ApproveLeagueJoinRequestPresenter();
await this.approveLeagueJoinRequestUseCase.execute({ leagueId: input.leagueId, requestId: input.requestId }, presenter);
return presenter.getViewModel()!;
presenter.present(result.unwrap());
return presenter.getViewModel();
}
async rejectLeagueJoinRequest(input: RejectJoinRequestInput): Promise<RejectJoinRequestOutput> {
async rejectLeagueJoinRequest(input: RejectJoinRequestInputDTO): Promise<RejectLeagueJoinRequestViewModel> {
this.logger.debug('Rejecting join request:', input);
const result = await this.rejectLeagueJoinRequestUseCase.execute({ requestId: input.requestId });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new RejectLeagueJoinRequestPresenter();
await this.rejectLeagueJoinRequestUseCase.execute({ requestId: input.requestId }, presenter);
return presenter.getViewModel()!;
presenter.present(result.unwrap());
return presenter.getViewModel();
}
async getLeagueAdminPermissions(query: GetLeagueAdminPermissionsInput): Promise<LeagueAdminPermissionsViewModel> {
async getLeagueAdminPermissions(query: GetLeagueAdminPermissionsInputDTO): Promise<GetLeagueAdminPermissionsViewModel> {
this.logger.debug('Getting league admin permissions', { query });
const result = await this.getLeagueAdminPermissionsUseCase.execute({ leagueId: query.leagueId, performerDriverId: query.performerDriverId });
// This use case never errors
const presenter = new GetLeagueAdminPermissionsPresenter();
await this.getLeagueAdminPermissionsUseCase.execute(
{ leagueId: query.leagueId, performerDriverId: query.performerDriverId },
presenter
);
presenter.present(result.unwrap());
return presenter.getViewModel()!;
}
async removeLeagueMember(input: RemoveLeagueMemberInput): Promise<RemoveLeagueMemberOutput> {
async removeLeagueMember(input: RemoveLeagueMemberInputDTO): Promise<RemoveLeagueMemberViewModel> {
this.logger.debug('Removing league member', { leagueId: input.leagueId, targetDriverId: input.targetDriverId });
const result = await this.removeLeagueMemberUseCase.execute({ leagueId: input.leagueId, targetDriverId: input.targetDriverId });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new RemoveLeagueMemberPresenter();
await this.removeLeagueMemberUseCase.execute({ leagueId: input.leagueId, targetDriverId: input.targetDriverId }, presenter);
return presenter.getViewModel()!;
presenter.present(result.unwrap());
return presenter.getViewModel();
}
async updateLeagueMemberRole(input: UpdateLeagueMemberRoleInput): Promise<UpdateLeagueMemberRoleOutput> {
async updateLeagueMemberRole(input: UpdateLeagueMemberRoleInputDTO): Promise<UpdateLeagueMemberRoleViewModel> {
this.logger.debug('Updating league member role', { leagueId: input.leagueId, targetDriverId: input.targetDriverId, newRole: input.newRole });
const result = await this.updateLeagueMemberRoleUseCase.execute({ leagueId: input.leagueId, targetDriverId: input.targetDriverId, newRole: input.newRole });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new UpdateLeagueMemberRolePresenter();
await this.updateLeagueMemberRoleUseCase.execute({ leagueId: input.leagueId, targetDriverId: input.targetDriverId, newRole: input.newRole }, presenter);
return presenter.getViewModel()!;
presenter.present(result.unwrap());
return presenter.getViewModel();
}
async getLeagueOwnerSummary(query: GetLeagueOwnerSummaryQuery): Promise<LeagueOwnerSummaryViewModel | null> {
async getLeagueOwnerSummary(query: GetLeagueOwnerSummaryQueryDTO): Promise<GetLeagueOwnerSummaryViewModel> {
this.logger.debug('Getting league owner summary:', query);
const result = await this.getLeagueOwnerSummaryUseCase.execute({ ownerId: query.ownerId });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new GetLeagueOwnerSummaryPresenter();
await this.getLeagueOwnerSummaryUseCase.execute({ ownerId: query.ownerId }, presenter);
return presenter.getViewModel()!.summary;
presenter.present(result.unwrap());
return presenter.getViewModel();
}
async getLeagueFullConfig(query: GetLeagueAdminConfigQuery): Promise<LeagueConfigFormModelDto | null> {
async getLeagueFullConfig(query: GetLeagueAdminConfigQueryDTO): Promise<LeagueConfigFormViewModel | 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;
const result = await this.getLeagueFullConfigUseCase.execute({ leagueId: query.leagueId });
if (result.isErr()) {
this.logger.error('Error getting league full config', new Error(result.unwrapErr().code));
return null;
}
return result.unwrap();
} 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> {
async getLeagueProtests(query: GetLeagueProtestsQueryDTO): Promise<LeagueAdminProtestsDTO> {
this.logger.debug('Getting league protests:', query);
const presenter = new GetLeagueProtestsPresenter();
await this.getLeagueProtestsUseCase.execute({ leagueId: query.leagueId }, presenter);
return presenter.getViewModel()!;
const result = await this.getLeagueProtestsUseCase.execute({ leagueId: query.leagueId });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
return result.unwrap();
}
async getLeagueSeasons(query: GetLeagueSeasonsQuery): Promise<LeagueSeasonSummaryViewModel[]> {
async getLeagueSeasons(query: GetLeagueSeasonsQueryDTO): Promise<LeagueSeasonSummaryDTO[]> {
this.logger.debug('Getting league seasons:', query);
const presenter = new GetLeagueSeasonsPresenter();
await this.getLeagueSeasonsUseCase.execute({ leagueId: query.leagueId }, presenter);
return presenter.getViewModel()!.seasons;
const result = await this.getLeagueSeasonsUseCase.execute({ leagueId: query.leagueId });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
return result.unwrap().seasons;
}
async getLeagueMemberships(leagueId: string): Promise<LeagueMembershipsViewModel> {
async getLeagueMemberships(leagueId: string): Promise<LeagueMembershipsDTO> {
this.logger.debug('Getting league memberships', { leagueId });
const presenter = new GetLeagueMembershipsPresenter();
await this.getLeagueMembershipsUseCase.execute({ leagueId }, presenter);
return presenter.apiViewModel!;
const result = await this.getLeagueMembershipsUseCase.execute({ leagueId });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
return result.unwrap();
}
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()!;
return await this.getLeagueStandingsUseCase.execute(leagueId);
}
async getLeagueSchedule(leagueId: string): Promise<LeagueScheduleViewModel> {
this.logger.debug('Getting league schedule', { leagueId });
const result = await this.getLeagueScheduleUseCase.execute({ leagueId });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new LeagueSchedulePresenter();
await this.getLeagueScheduleUseCase.execute({ leagueId }, presenter);
presenter.present(result.unwrap());
return presenter.getViewModel()!;
}
async getLeagueStats(leagueId: string): Promise<LeagueStatsViewModel> {
this.logger.debug('Getting league stats', { leagueId });
const result = await this.getLeagueStatsUseCase.execute({ leagueId });
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new LeagueStatsPresenter();
await this.getLeagueStatsUseCase.execute({ leagueId }, presenter);
presenter.present(result.unwrap());
return presenter.getViewModel()!;
}
async getLeagueAdmin(leagueId: string): Promise<LeagueAdminViewModel> {
async getLeagueAdmin(leagueId: string): Promise<LeagueAdminDTO> {
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
@@ -253,7 +329,7 @@ export class LeagueService {
};
}
async createLeague(input: CreateLeagueInput): Promise<CreateLeagueOutput> {
async createLeague(input: CreateLeagueInputDTO): Promise<CreateLeagueViewModel> {
this.logger.debug('Creating league', { input });
const command = {
name: input.name,
@@ -268,10 +344,12 @@ export class LeagueService {
enableTrophyChampionship: false,
};
const result = await this.createLeagueWithSeasonAndScoringUseCase.execute(command);
return {
leagueId: result.leagueId,
success: true,
};
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new CreateLeaguePresenter();
presenter.present(result.unwrap());
return presenter.getViewModel();
}
async getLeagueScoringConfig(leagueId: string): Promise<LeagueScoringConfigViewModel | null> {
@@ -281,10 +359,10 @@ export class LeagueService {
try {
const result = await this.getLeagueScoringConfigUseCase.execute({ leagueId });
if (result.isErr()) {
this.logger.error('Error getting league scoring config', result.error);
this.logger.error('Error getting league scoring config', new Error(result.unwrapErr().code));
return null;
}
await presenter.present(result.value);
await presenter.present(result.unwrap());
return presenter.getViewModel();
} catch (error) {
this.logger.error('Error getting league scoring config', error instanceof Error ? error : new Error(String(error)));
@@ -295,40 +373,46 @@ export class LeagueService {
async listLeagueScoringPresets(): Promise<LeagueScoringPresetsViewModel> {
this.logger.debug('Listing league scoring presets');
const result = await this.listLeagueScoringPresetsUseCase.execute();
if (result.isErr()) {
throw new Error(result.unwrapErr().code);
}
const presenter = new LeagueScoringPresetsPresenter();
await this.listLeagueScoringPresetsUseCase.execute(undefined, presenter);
await presenter.present(result.unwrap());
return presenter.getViewModel()!;
}
async joinLeague(leagueId: string, driverId: string): Promise<JoinLeagueOutput> {
async joinLeague(leagueId: string, driverId: string): Promise<JoinLeagueViewModel> {
this.logger.debug('Joining league', { leagueId, driverId });
const result = await this.joinLeagueUseCase.execute({ leagueId, driverId });
if (result.isErr()) {
const error = result.unwrapErr();
return {
success: false,
error: result.error.code,
error: error.code,
};
}
return {
success: true,
membershipId: result.value.id,
};
const presenter = new JoinLeaguePresenter();
presenter.present(result.unwrap());
return presenter.getViewModel();
}
async transferLeagueOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<TransferLeagueOwnershipOutput> {
async transferLeagueOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<TransferLeagueOwnershipViewModel> {
this.logger.debug('Transferring league ownership', { leagueId, currentOwnerId, newOwnerId });
const result = await this.transferLeagueOwnershipUseCase.execute({ leagueId, currentOwnerId, newOwnerId });
if (result.isErr()) {
const error = result.unwrapErr();
return {
success: false,
error: result.error.code,
error: error.code,
};
}
return {
success: true,
};
const presenter = new TransferLeagueOwnershipPresenter();
presenter.present(result.unwrap());
return presenter.getViewModel();
}
async getSeasonSponsorships(seasonId: string): Promise<GetSeasonSponsorshipsOutputDTO> {

View File

@@ -0,0 +1,5 @@
export interface JoinLeagueOutputDTO {
success: boolean;
error?: string;
membershipId?: string;
}

View File

@@ -23,9 +23,9 @@ export class LeagueConfigFormModelDTO {
@Type(() => LeagueConfigFormModelStructureDTO)
structure: LeagueConfigFormModelStructureDTO;
@ApiProperty({ type: [Object] })
@ApiProperty({ type: [Object] })
@IsArray()
championships: any[];
championships: Object[];
@ApiProperty({ type: LeagueConfigFormModelScoringDTO })
@ValidateNested()

View File

@@ -0,0 +1,11 @@
export interface LeagueJoinRequestWithDriverDTO {
id: string;
leagueId: string;
driverId: string;
requestedAt: Date;
message?: string;
driver: {
id: string;
name: string;
};
}

View File

@@ -0,0 +1,4 @@
export interface TransferLeagueOwnershipOutputDTO {
success: boolean;
error?: string;
}

View File

@@ -0,0 +1,21 @@
import { ICreateLeaguePresenter, CreateLeagueResultDTO, CreateLeagueViewModel } from '@core/racing/application/presenters/ICreateLeaguePresenter';
export class CreateLeaguePresenter implements ICreateLeaguePresenter {
private result: CreateLeagueViewModel | null = null;
reset() {
this.result = null;
}
present(dto: CreateLeagueResultDTO): void {
this.result = {
leagueId: dto.leagueId,
success: true,
};
}
getViewModel(): CreateLeagueViewModel {
if (!this.result) throw new Error('Presenter not presented');
return this.result;
}
}

View File

@@ -0,0 +1,21 @@
import { IJoinLeaguePresenter, JoinLeagueResultDTO, JoinLeagueViewModel } from '@core/racing/application/presenters/IJoinLeaguePresenter';
export class JoinLeaguePresenter implements IJoinLeaguePresenter {
private result: JoinLeagueViewModel | null = null;
reset() {
this.result = null;
}
present(dto: JoinLeagueResultDTO): void {
this.result = {
success: true,
membershipId: dto.id,
};
}
getViewModel(): JoinLeagueViewModel {
if (!this.result) throw new Error('Presenter not presented');
return this.result;
}
}

View File

@@ -8,11 +8,11 @@ export class LeagueAdminPresenter {
}
present(data: {
joinRequests: any[];
ownerSummary: any;
config: any;
protests: any;
seasons: any[];
joinRequests: unknown[];
ownerSummary: unknown;
config: unknown;
protests: unknown;
seasons: unknown[];
}) {
this.result = {
joinRequests: data.joinRequests,

View File

@@ -0,0 +1,20 @@
import { ITransferLeagueOwnershipPresenter, TransferLeagueOwnershipResultDTO, TransferLeagueOwnershipViewModel } from '@core/racing/application/presenters/ITransferLeagueOwnershipPresenter';
export class TransferLeagueOwnershipPresenter implements ITransferLeagueOwnershipPresenter {
private result: TransferLeagueOwnershipViewModel | null = null;
reset() {
this.result = null;
}
present(dto: TransferLeagueOwnershipResultDTO): void {
this.result = {
success: dto.success,
};
}
getViewModel(): TransferLeagueOwnershipViewModel {
if (!this.result) throw new Error('Presenter not presented');
return this.result;
}
}