refactor league module (wip)
This commit is contained in:
@@ -4,8 +4,7 @@
|
|||||||
* In-memory implementation of IAnalyticsSnapshotRepository for development/testing.
|
* In-memory implementation of IAnalyticsSnapshotRepository for development/testing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { IAnalyticsSnapshotRepository } from '../../domain/repositories/IAnalyticsSnapshotRepository';
|
import { AnalyticsSnapshot, IAnalyticsSnapshotRepository, SnapshotEntityType, SnapshotPeriod } from '@core/analytics';
|
||||||
import { AnalyticsSnapshot, type SnapshotPeriod, type SnapshotEntityType } from '../../domain/entities/AnalyticsSnapshot';
|
|
||||||
import { Logger } from '@core/shared/application';
|
import { Logger } from '@core/shared/application';
|
||||||
|
|
||||||
export class InMemoryAnalyticsSnapshotRepository implements IAnalyticsSnapshotRepository {
|
export class InMemoryAnalyticsSnapshotRepository implements IAnalyticsSnapshotRepository {
|
||||||
|
|||||||
@@ -1,9 +1,15 @@
|
|||||||
import type { LogLevel } from '@core/automation/application/ports/LoggerLogLevel';
|
enum LogLevel {
|
||||||
|
DEBUG = 'debug',
|
||||||
|
INFO = 'info',
|
||||||
|
WARN = 'warn',
|
||||||
|
ERROR = 'error',
|
||||||
|
FATAL = 'fatal'
|
||||||
|
} // TODO move to core
|
||||||
|
|
||||||
export type LogEnvironment = 'development' | 'production' | 'test';
|
export type LogEnvironment = 'development' | 'production' | 'test';
|
||||||
|
|
||||||
export interface LoggingEnvironmentConfig {
|
export interface LoggingEnvironmentConfig {
|
||||||
level: LogLevel;
|
level: LogLevel; // TODO
|
||||||
prettyPrint: boolean;
|
prettyPrint: boolean;
|
||||||
fileOutput: boolean;
|
fileOutput: boolean;
|
||||||
filePath?: string;
|
filePath?: string;
|
||||||
@@ -46,19 +52,19 @@ function getDefaultsForEnvironment(env: LogEnvironment): LoggingEnvironmentConfi
|
|||||||
switch (env) {
|
switch (env) {
|
||||||
case 'development':
|
case 'development':
|
||||||
return {
|
return {
|
||||||
level: 'debug',
|
level: LogLevel.DEBUG,
|
||||||
prettyPrint: true,
|
prettyPrint: true,
|
||||||
fileOutput: false,
|
fileOutput: false,
|
||||||
};
|
};
|
||||||
case 'production':
|
case 'production':
|
||||||
return {
|
return {
|
||||||
level: 'info',
|
level: LogLevel.ERROR,
|
||||||
prettyPrint: false,
|
prettyPrint: false,
|
||||||
fileOutput: true,
|
fileOutput: true,
|
||||||
};
|
};
|
||||||
case 'test':
|
case 'test':
|
||||||
return {
|
return {
|
||||||
level: 'warn',
|
level: LogLevel.WARN,
|
||||||
prettyPrint: false,
|
prettyPrint: false,
|
||||||
fileOutput: false,
|
fileOutput: false,
|
||||||
};
|
};
|
||||||
|
|||||||
35
adapters/bootstrap/PointsSystems.ts
Normal file
35
adapters/bootstrap/PointsSystems.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
export const pointsSystems: Record<string, Record<number, number>> = {
|
||||||
|
'f1-2024': {
|
||||||
|
1: 25,
|
||||||
|
2: 18,
|
||||||
|
3: 15,
|
||||||
|
4: 12,
|
||||||
|
5: 10,
|
||||||
|
6: 8,
|
||||||
|
7: 6,
|
||||||
|
8: 4,
|
||||||
|
9: 2,
|
||||||
|
10: 1,
|
||||||
|
},
|
||||||
|
indycar: {
|
||||||
|
1: 50,
|
||||||
|
2: 40,
|
||||||
|
3: 35,
|
||||||
|
4: 32,
|
||||||
|
5: 30,
|
||||||
|
6: 28,
|
||||||
|
7: 26,
|
||||||
|
8: 24,
|
||||||
|
9: 22,
|
||||||
|
10: 20,
|
||||||
|
11: 19,
|
||||||
|
12: 18,
|
||||||
|
13: 17,
|
||||||
|
14: 16,
|
||||||
|
15: 15,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function getPointsSystems(): Record<string, Record<number, number>> {
|
||||||
|
return { ...pointsSystems };
|
||||||
|
}
|
||||||
@@ -4,17 +4,11 @@
|
|||||||
* In-memory implementation of IAchievementRepository
|
* In-memory implementation of IAchievementRepository
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Logger } from '@core/shared/application';
|
import { Achievement, AchievementCategory, IAchievementRepository, UserAchievement } from "@core/identity";
|
||||||
import {
|
import { ADMIN_ACHIEVEMENTS, COMMUNITY_ACHIEVEMENTS, DRIVER_ACHIEVEMENTS, STEWARD_ACHIEVEMENTS } from "@core/identity/domain/AchievementConstants";
|
||||||
Achievement,
|
import { Logger } from "@core/shared/application";
|
||||||
AchievementCategory,
|
|
||||||
DRIVER_ACHIEVEMENTS,
|
|
||||||
STEWARD_ACHIEVEMENTS,
|
|
||||||
ADMIN_ACHIEVEMENTS,
|
|
||||||
COMMUNITY_ACHIEVEMENTS,
|
|
||||||
} from '../../domain/entities/Achievement';
|
|
||||||
import { UserAchievement } from '../../domain/entities/UserAchievement';
|
|
||||||
import type { IAchievementRepository } from '../../domain/repositories/IAchievementRepository';
|
|
||||||
|
|
||||||
export class InMemoryAchievementRepository implements IAchievementRepository {
|
export class InMemoryAchievementRepository implements IAchievementRepository {
|
||||||
private achievements: Map<string, Achievement> = new Map();
|
private achievements: Map<string, Achievement> = new Map();
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
|
import { User } from '@core/identity/domain/entities/User';
|
||||||
import { IAuthRepository } from '@core/identity/domain/repositories/IAuthRepository';
|
import { IAuthRepository } from '@core/identity/domain/repositories/IAuthRepository';
|
||||||
import { IUserRepository, StoredUser } from '@core/identity/domain/repositories/IUserRepository';
|
import { IUserRepository, StoredUser } from '@core/identity/domain/repositories/IUserRepository';
|
||||||
import { IPasswordHashingService } from '@core/identity/domain/services/PasswordHashingService';
|
import { IPasswordHashingService } from '@core/identity/domain/services/PasswordHashingService';
|
||||||
import { User } from '@core/identity/domain/entities/User';
|
|
||||||
|
|
||||||
import { EmailAddress } from '@core/identity/domain/value-objects/EmailAddress';
|
import { EmailAddress } from '@core/identity/domain/value-objects/EmailAddress';
|
||||||
import { randomUUID } from 'crypto';
|
|
||||||
import { Logger } from '@core/shared/application';
|
import { Logger } from '@core/shared/application';
|
||||||
|
|
||||||
export class InMemoryAuthRepository implements IAuthRepository {
|
export class InMemoryAuthRepository implements IAuthRepository {
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
* In-memory implementation of ISponsorAccountRepository for development/testing.
|
* In-memory implementation of ISponsorAccountRepository for development/testing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import type { ISponsorAccountRepository } from '../../domain/repositories/ISponsorAccountRepository';
|
import { ISponsorAccountRepository, SponsorAccount, UserId } from '@core/identity';
|
||||||
import type { SponsorAccount } from '../../domain/entities/SponsorAccount';
|
|
||||||
import type { UserId } from '../../domain/value-objects/UserId';
|
|
||||||
import { Logger } from '@core/shared/application';
|
import { Logger } from '@core/shared/application';
|
||||||
|
|
||||||
export class InMemorySponsorAccountRepository implements ISponsorAccountRepository {
|
export class InMemorySponsorAccountRepository implements ISponsorAccountRepository {
|
||||||
|
|||||||
@@ -4,8 +4,7 @@
|
|||||||
* In-memory implementation of IUserRatingRepository
|
* In-memory implementation of IUserRatingRepository
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { UserRating } from '../../domain/value-objects/UserRating';
|
import { IUserRatingRepository, UserRating } from '@core/identity';
|
||||||
import type { IUserRatingRepository } from '../../domain/repositories/IUserRatingRepository';
|
|
||||||
import { Logger } from '@core/shared/application';
|
import { Logger } from '@core/shared/application';
|
||||||
|
|
||||||
export class InMemoryUserRatingRepository implements IUserRatingRepository {
|
export class InMemoryUserRatingRepository implements IUserRatingRepository {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import { LeagueProviders } from './LeagueProviders';
|
|||||||
|
|
||||||
describe('LeagueController (integration)', () => {
|
describe('LeagueController (integration)', () => {
|
||||||
let controller: LeagueController;
|
let controller: LeagueController;
|
||||||
let service: LeagueService;
|
|
||||||
|
|
||||||
beforeEach(async () => {
|
beforeEach(async () => {
|
||||||
const module: TestingModule = await Test.createTestingModule({
|
const module: TestingModule = await Test.createTestingModule({
|
||||||
@@ -14,7 +13,6 @@ describe('LeagueController (integration)', () => {
|
|||||||
}).compile();
|
}).compile();
|
||||||
|
|
||||||
controller = module.get<LeagueController>(LeagueController);
|
controller = module.get<LeagueController>(LeagueController);
|
||||||
service = module.get<LeagueService>(LeagueService);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should get total leagues', async () => {
|
it('should get total leagues', async () => {
|
||||||
@@ -37,7 +35,7 @@ describe('LeagueController (integration)', () => {
|
|||||||
expect(Array.isArray(result.standings)).toBe(true);
|
expect(Array.isArray(result.standings)).toBe(true);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// Expected for non-existent league
|
// Expected for non-existent league
|
||||||
expect(error.message).toContain('not found');
|
expect(error).toBeInstanceOf(Error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -30,6 +30,7 @@ import { GetLeagueAdminConfigQueryDTO } from './dtos/GetLeagueAdminConfigQueryDT
|
|||||||
import { GetLeagueProtestsQueryDTO } from './dtos/GetLeagueProtestsQueryDTO';
|
import { GetLeagueProtestsQueryDTO } from './dtos/GetLeagueProtestsQueryDTO';
|
||||||
import { GetLeagueSeasonsQueryDTO } from './dtos/GetLeagueSeasonsQueryDTO';
|
import { GetLeagueSeasonsQueryDTO } from './dtos/GetLeagueSeasonsQueryDTO';
|
||||||
import { GetLeagueWalletOutputDTO } from './dtos/GetLeagueWalletOutputDTO';
|
import { GetLeagueWalletOutputDTO } from './dtos/GetLeagueWalletOutputDTO';
|
||||||
|
import { TotalLeaguesDTO } from './dtos/TotalLeaguesDTO';
|
||||||
import { WithdrawFromLeagueWalletInputDTO } from './dtos/WithdrawFromLeagueWalletInputDTO';
|
import { WithdrawFromLeagueWalletInputDTO } from './dtos/WithdrawFromLeagueWalletInputDTO';
|
||||||
import { WithdrawFromLeagueWalletOutputDTO } from './dtos/WithdrawFromLeagueWalletOutputDTO';
|
import { WithdrawFromLeagueWalletOutputDTO } from './dtos/WithdrawFromLeagueWalletOutputDTO';
|
||||||
|
|
||||||
@@ -47,8 +48,8 @@ export class LeagueController {
|
|||||||
|
|
||||||
@Get('total-leagues')
|
@Get('total-leagues')
|
||||||
@ApiOperation({ summary: 'Get the total number of leagues' })
|
@ApiOperation({ summary: 'Get the total number of leagues' })
|
||||||
@ApiResponse({ status: 200, description: 'Total number of leagues', type: LeagueStatsDTO })
|
@ApiResponse({ status: 200, description: 'Total number of leagues', type: TotalLeaguesDTO })
|
||||||
async getTotalLeagues(): Promise<LeagueStatsDTO> {
|
async getTotalLeagues(): Promise<TotalLeaguesDTO> {
|
||||||
return this.leagueService.getTotalLeagues();
|
return this.leagueService.getTotalLeagues();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,61 +2,68 @@ import { Provider } from '@nestjs/common';
|
|||||||
import { LeagueService } from './LeagueService';
|
import { LeagueService } from './LeagueService';
|
||||||
|
|
||||||
// Import core interfaces
|
// Import core interfaces
|
||||||
import type { Logger } from '@core/shared/application/Logger';
|
|
||||||
import type { ISeasonSponsorshipRepository } from '@core/racing/domain/repositories/ISeasonSponsorshipRepository';
|
|
||||||
import type { ISeasonRepository } from '@core/racing/domain/repositories/ISeasonRepository';
|
|
||||||
import type { ILeagueRepository } from '@core/racing/domain/repositories/ILeagueRepository';
|
|
||||||
import type { ILeagueMembershipRepository } from '@core/racing/domain/repositories/ILeagueMembershipRepository';
|
|
||||||
import type { IRaceRepository } from '@core/racing/domain/repositories/IRaceRepository';
|
|
||||||
import type { IProtestRepository } from '@core/racing/domain/repositories/IProtestRepository';
|
|
||||||
import type { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository';
|
import type { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository';
|
||||||
|
import type { ILeagueMembershipRepository } from '@core/racing/domain/repositories/ILeagueMembershipRepository';
|
||||||
|
import type { ILeagueRepository } from '@core/racing/domain/repositories/ILeagueRepository';
|
||||||
|
import type { IProtestRepository } from '@core/racing/domain/repositories/IProtestRepository';
|
||||||
|
import type { IRaceRepository } from '@core/racing/domain/repositories/IRaceRepository';
|
||||||
|
import type { ISeasonRepository } from '@core/racing/domain/repositories/ISeasonRepository';
|
||||||
|
import type { ISeasonSponsorshipRepository } from '@core/racing/domain/repositories/ISeasonSponsorshipRepository';
|
||||||
|
import type { IStandingRepository } from '@core/racing/domain/repositories/IStandingRepository';
|
||||||
|
import type { Logger } from '@core/shared/application/Logger';
|
||||||
|
|
||||||
// Import concrete in-memory implementations
|
// Import concrete in-memory implementations
|
||||||
import { InMemoryLeagueRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueRepository';
|
import { listLeagueScoringPresets } from '@adapters/bootstrap/LeagueScoringPresets';
|
||||||
import { InMemoryLeagueMembershipRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueMembershipRepository';
|
import { getPointsSystems } from '@adapters/bootstrap/PointsSystems';
|
||||||
import { InMemoryLeagueStandingsRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueStandingsRepository';
|
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
|
||||||
import { InMemorySeasonRepository } from '@adapters/racing/persistence/inmemory/InMemorySeasonRepository';
|
import { InMemoryDriverRepository } from '@adapters/racing/persistence/inmemory/InMemoryDriverRepository';
|
||||||
import { InMemorySeasonSponsorshipRepository } from '@adapters/racing/persistence/inmemory/InMemorySeasonSponsorshipRepository';
|
|
||||||
import { InMemoryLeagueScoringConfigRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueScoringConfigRepository';
|
|
||||||
import { InMemoryGameRepository } from '@adapters/racing/persistence/inmemory/InMemoryGameRepository';
|
import { InMemoryGameRepository } from '@adapters/racing/persistence/inmemory/InMemoryGameRepository';
|
||||||
|
import { InMemoryLeagueMembershipRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueMembershipRepository';
|
||||||
|
import { InMemoryLeagueRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueRepository';
|
||||||
|
import { InMemoryLeagueScoringConfigRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueScoringConfigRepository';
|
||||||
|
import { InMemoryLeagueStandingsRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueStandingsRepository';
|
||||||
|
import { InMemoryLeagueWalletRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueWalletRepository';
|
||||||
import { InMemoryProtestRepository } from '@adapters/racing/persistence/inmemory/InMemoryProtestRepository';
|
import { InMemoryProtestRepository } from '@adapters/racing/persistence/inmemory/InMemoryProtestRepository';
|
||||||
import { InMemoryRaceRepository } from '@adapters/racing/persistence/inmemory/InMemoryRaceRepository';
|
import { InMemoryRaceRepository } from '@adapters/racing/persistence/inmemory/InMemoryRaceRepository';
|
||||||
import { InMemoryDriverRepository } from '@adapters/racing/persistence/inmemory/InMemoryDriverRepository';
|
import { InMemorySeasonRepository } from '@adapters/racing/persistence/inmemory/InMemorySeasonRepository';
|
||||||
|
import { InMemorySeasonSponsorshipRepository } from '@adapters/racing/persistence/inmemory/InMemorySeasonSponsorshipRepository';
|
||||||
import { InMemoryStandingRepository } from '@adapters/racing/persistence/inmemory/InMemoryStandingRepository';
|
import { InMemoryStandingRepository } from '@adapters/racing/persistence/inmemory/InMemoryStandingRepository';
|
||||||
import { InMemoryLeagueWalletRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueWalletRepository';
|
|
||||||
import { InMemoryTransactionRepository } from '@adapters/racing/persistence/inmemory/InMemoryTransactionRepository';
|
import { InMemoryTransactionRepository } from '@adapters/racing/persistence/inmemory/InMemoryTransactionRepository';
|
||||||
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
|
|
||||||
import { listLeagueScoringPresets } from '@adapters/bootstrap/LeagueScoringPresets';
|
|
||||||
|
|
||||||
// Import use cases
|
// Import use cases
|
||||||
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
|
|
||||||
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 { GetSeasonSponsorshipsUseCase } from '@core/racing/application/use-cases/GetSeasonSponsorshipsUseCase';
|
|
||||||
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 { ApproveLeagueJoinRequestUseCase } from '@core/racing/application/use-cases/ApproveLeagueJoinRequestUseCase';
|
||||||
import { RejectLeagueJoinRequestUseCase } from '@core/racing/application/use-cases/RejectLeagueJoinRequestUseCase';
|
import { CreateLeagueWithSeasonAndScoringUseCase } from '@core/racing/application/use-cases/CreateLeagueWithSeasonAndScoringUseCase';
|
||||||
import { RemoveLeagueMemberUseCase } from '@core/racing/application/use-cases/RemoveLeagueMemberUseCase';
|
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
|
||||||
import { UpdateLeagueMemberRoleUseCase } from '@core/racing/application/use-cases/UpdateLeagueMemberRoleUseCase';
|
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 { GetLeagueOwnerSummaryUseCase } from '@core/racing/application/use-cases/GetLeagueOwnerSummaryUseCase';
|
||||||
import { GetLeagueProtestsUseCase } from '@core/racing/application/use-cases/GetLeagueProtestsUseCase';
|
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 { 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 { GetLeagueStatsUseCase } from '@core/racing/application/use-cases/GetLeagueStatsUseCase';
|
||||||
import { GetLeagueAdminPermissionsUseCase } from '@core/racing/application/use-cases/GetLeagueAdminPermissionsUseCase';
|
|
||||||
import { GetLeagueWalletUseCase } from '@core/racing/application/use-cases/GetLeagueWalletUseCase';
|
import { GetLeagueWalletUseCase } from '@core/racing/application/use-cases/GetLeagueWalletUseCase';
|
||||||
|
import { GetRaceProtestsUseCase } from '@core/racing/application/use-cases/GetRaceProtestsUseCase';
|
||||||
|
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';
|
import { WithdrawFromLeagueWalletUseCase } from '@core/racing/application/use-cases/WithdrawFromLeagueWalletUseCase';
|
||||||
|
|
||||||
// Import presenters
|
// Import presenters
|
||||||
import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter';
|
import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter';
|
||||||
import { GetLeagueProtestsPresenter } from './presenters/GetLeagueProtestsPresenter';
|
import { GetLeagueProtestsPresenter } from './presenters/GetLeagueProtestsPresenter';
|
||||||
|
import { GetSeasonSponsorshipsPresenter } from './presenters/GetSeasonSponsorshipsPresenter';
|
||||||
|
import { LeagueScoringPresetsPresenter } from './presenters/LeagueScoringPresetsPresenter';
|
||||||
|
import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter';
|
||||||
|
|
||||||
// Define injection tokens
|
|
||||||
export const LEAGUE_REPOSITORY_TOKEN = 'ILeagueRepository';
|
export const LEAGUE_REPOSITORY_TOKEN = 'ILeagueRepository';
|
||||||
export const LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN = 'ILeagueMembershipRepository';
|
export const LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN = 'ILeagueMembershipRepository';
|
||||||
export const LEAGUE_STANDINGS_REPOSITORY_TOKEN = 'ILeagueStandingsRepository';
|
export const LEAGUE_STANDINGS_REPOSITORY_TOKEN = 'ILeagueStandingsRepository';
|
||||||
@@ -71,6 +78,30 @@ export const LEAGUE_WALLET_REPOSITORY_TOKEN = 'ILeagueWalletRepository';
|
|||||||
export const TRANSACTION_REPOSITORY_TOKEN = 'ITransactionRepository';
|
export const TRANSACTION_REPOSITORY_TOKEN = 'ITransactionRepository';
|
||||||
export const LOGGER_TOKEN = 'Logger'; // Already defined in AuthProviders, but good to have here too
|
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 GET_LEAGUE_STANDINGS_USE_CASE = 'GetLeagueStandingsUseCase';
|
||||||
|
export const GET_ALL_LEAGUES_WITH_CAPACITY_USE_CASE = 'GetAllLeaguesWithCapacityUseCase';
|
||||||
|
export const GET_LEAGUE_STATS_USE_CASE = 'GetLeagueStatsUseCase';
|
||||||
|
export const GET_LEAGUE_FULL_CONFIG_USE_CASE = 'GetLeagueFullConfigUseCase';
|
||||||
|
export const GET_LEAGUE_SCORING_CONFIG_USE_CASE = 'GetLeagueScoringConfigUseCase';
|
||||||
|
export const LIST_LEAGUE_SCORING_PRESETS_USE_CASE = 'ListLeagueScoringPresetsUseCase';
|
||||||
|
export const JOIN_LEAGUE_USE_CASE = 'JoinLeagueUseCase';
|
||||||
|
export const TRANSFER_LEAGUE_OWNERSHIP_USE_CASE = 'TransferLeagueOwnershipUseCase';
|
||||||
|
export const CREATE_LEAGUE_WITH_SEASON_AND_SCORING_USE_CASE = 'CreateLeagueWithSeasonAndScoringUseCase';
|
||||||
|
export const GET_RACE_PROTESTS_USE_CASE = 'GetRaceProtestsUseCase';
|
||||||
|
export const GET_TOTAL_LEAGUES_USE_CASE = 'GetTotalLeaguesUseCase';
|
||||||
|
export const GET_LEAGUE_JOIN_REQUESTS_USE_CASE = 'GetLeagueJoinRequestsUseCase';
|
||||||
|
export const APPROVE_LEAGUE_JOIN_REQUEST_USE_CASE = 'ApproveLeagueJoinRequestUseCase';
|
||||||
|
export const REJECT_LEAGUE_JOIN_REQUEST_USE_CASE = 'RejectLeagueJoinRequestUseCase';
|
||||||
|
export const REMOVE_LEAGUE_MEMBER_USE_CASE = 'RemoveLeagueMemberUseCase';
|
||||||
|
export const UPDATE_LEAGUE_MEMBER_ROLE_USE_CASE = 'UpdateLeagueMemberRoleUseCase';
|
||||||
|
export const GET_LEAGUE_OWNER_SUMMARY_USE_CASE = 'GetLeagueOwnerSummaryUseCase';
|
||||||
|
export const GET_LEAGUE_PROTESTS_USE_CASE = 'GetLeagueProtestsUseCase';
|
||||||
|
export const GET_LEAGUE_SEASONS_USE_CASE = 'GetLeagueSeasonsUseCase';
|
||||||
|
export const GET_LEAGUE_MEMBERSHIPS_USE_CASE = 'GetLeagueMembershipsUseCase';
|
||||||
|
export const GET_LEAGUE_SCHEDULE_USE_CASE = 'GetLeagueScheduleUseCase';
|
||||||
|
export const GET_LEAGUE_ADMIN_PERMISSIONS_USE_CASE = 'GetLeagueAdminPermissionsUseCase';
|
||||||
|
export const GET_LEAGUE_WALLET_USE_CASE = 'GetLeagueWalletUseCase';
|
||||||
|
export const WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE = 'WithdrawFromLeagueWalletUseCase';
|
||||||
|
export const GET_SEASON_SPONSORSHIPS_USE_CASE = 'GetSeasonSponsorshipsUseCase';
|
||||||
|
|
||||||
export const LeagueProviders: Provider[] = [
|
export const LeagueProviders: Provider[] = [
|
||||||
LeagueService, // Provide the service itself
|
LeagueService, // Provide the service itself
|
||||||
@@ -91,7 +122,7 @@ export const LeagueProviders: Provider[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: STANDING_REPOSITORY_TOKEN,
|
provide: STANDING_REPOSITORY_TOKEN,
|
||||||
useFactory: (logger: Logger) => new InMemoryStandingRepository(logger), // Factory for InMemoryStandingRepository
|
useFactory: (logger: Logger) => new InMemoryStandingRepository(logger, getPointsSystems()), // Factory for InMemoryStandingRepository
|
||||||
inject: [LOGGER_TOKEN],
|
inject: [LOGGER_TOKEN],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -143,15 +174,6 @@ export const LeagueProviders: Provider[] = [
|
|||||||
provide: LOGGER_TOKEN,
|
provide: LOGGER_TOKEN,
|
||||||
useClass: ConsoleLogger,
|
useClass: ConsoleLogger,
|
||||||
},
|
},
|
||||||
// Presenters
|
|
||||||
{
|
|
||||||
provide: 'AllLeaguesWithCapacityPresenter',
|
|
||||||
useClass: AllLeaguesWithCapacityPresenter,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
provide: 'GetLeagueProtestsPresenter',
|
|
||||||
useClass: GetLeagueProtestsPresenter,
|
|
||||||
},
|
|
||||||
// Use cases
|
// Use cases
|
||||||
{
|
{
|
||||||
provide: GetAllLeaguesWithCapacityUseCase,
|
provide: GetAllLeaguesWithCapacityUseCase,
|
||||||
@@ -161,21 +183,56 @@ export const LeagueProviders: Provider[] = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
provide: GET_LEAGUE_STANDINGS_USE_CASE,
|
provide: GET_LEAGUE_STANDINGS_USE_CASE,
|
||||||
useClass: GetLeagueStandingsUseCaseImpl,
|
useFactory: (standingRepo: IStandingRepository, driverRepo: IDriverRepository, presenter: LeagueStandingsPresenter) =>
|
||||||
|
new GetLeagueStandingsUseCase(standingRepo, driverRepo, presenter),
|
||||||
|
inject: [STANDING_REPOSITORY_TOKEN, DRIVER_REPOSITORY_TOKEN, 'LeagueStandingsPresenter'],
|
||||||
},
|
},
|
||||||
GetLeagueStatsUseCase,
|
|
||||||
GetLeagueFullConfigUseCase,
|
|
||||||
CreateLeagueWithSeasonAndScoringUseCase,
|
|
||||||
GetRaceProtestsUseCase,
|
|
||||||
GetTotalLeaguesUseCase,
|
|
||||||
GetLeagueJoinRequestsUseCase,
|
|
||||||
ApproveLeagueJoinRequestUseCase,
|
|
||||||
RejectLeagueJoinRequestUseCase,
|
|
||||||
RemoveLeagueMemberUseCase,
|
|
||||||
UpdateLeagueMemberRoleUseCase,
|
|
||||||
GetLeagueOwnerSummaryUseCase,
|
|
||||||
{
|
{
|
||||||
provide: GetLeagueProtestsUseCase,
|
provide: GET_LEAGUE_STATS_USE_CASE,
|
||||||
|
useClass: GetLeagueStatsUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_LEAGUE_FULL_CONFIG_USE_CASE,
|
||||||
|
useClass: GetLeagueFullConfigUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: CREATE_LEAGUE_WITH_SEASON_AND_SCORING_USE_CASE,
|
||||||
|
useClass: CreateLeagueWithSeasonAndScoringUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_RACE_PROTESTS_USE_CASE,
|
||||||
|
useClass: GetRaceProtestsUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_TOTAL_LEAGUES_USE_CASE,
|
||||||
|
useClass: GetTotalLeaguesUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_LEAGUE_JOIN_REQUESTS_USE_CASE,
|
||||||
|
useClass: GetLeagueJoinRequestsUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: APPROVE_LEAGUE_JOIN_REQUEST_USE_CASE,
|
||||||
|
useClass: ApproveLeagueJoinRequestUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: REJECT_LEAGUE_JOIN_REQUEST_USE_CASE,
|
||||||
|
useClass: RejectLeagueJoinRequestUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: REMOVE_LEAGUE_MEMBER_USE_CASE,
|
||||||
|
useClass: RemoveLeagueMemberUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: UPDATE_LEAGUE_MEMBER_ROLE_USE_CASE,
|
||||||
|
useClass: UpdateLeagueMemberRoleUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_LEAGUE_OWNER_SUMMARY_USE_CASE,
|
||||||
|
useClass: GetLeagueOwnerSummaryUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_LEAGUE_PROTESTS_USE_CASE,
|
||||||
useFactory: (
|
useFactory: (
|
||||||
raceRepo: IRaceRepository,
|
raceRepo: IRaceRepository,
|
||||||
protestRepo: IProtestRepository,
|
protestRepo: IProtestRepository,
|
||||||
@@ -185,32 +242,64 @@ export const LeagueProviders: Provider[] = [
|
|||||||
) => new GetLeagueProtestsUseCase(raceRepo, protestRepo, driverRepo, leagueRepo, presenter),
|
) => new GetLeagueProtestsUseCase(raceRepo, protestRepo, driverRepo, leagueRepo, presenter),
|
||||||
inject: [RACE_REPOSITORY_TOKEN, PROTEST_REPOSITORY_TOKEN, DRIVER_REPOSITORY_TOKEN, LEAGUE_REPOSITORY_TOKEN, 'GetLeagueProtestsPresenter'],
|
inject: [RACE_REPOSITORY_TOKEN, PROTEST_REPOSITORY_TOKEN, DRIVER_REPOSITORY_TOKEN, LEAGUE_REPOSITORY_TOKEN, 'GetLeagueProtestsPresenter'],
|
||||||
},
|
},
|
||||||
GetLeagueSeasonsUseCase,
|
|
||||||
GetLeagueMembershipsUseCase,
|
|
||||||
GetLeagueScheduleUseCase,
|
|
||||||
GetLeagueStatsUseCase,
|
|
||||||
GetLeagueAdminPermissionsUseCase,
|
|
||||||
GetLeagueWalletUseCase,
|
|
||||||
WithdrawFromLeagueWalletUseCase,
|
|
||||||
{
|
{
|
||||||
provide: GetSeasonSponsorshipsUseCase,
|
provide: GET_LEAGUE_SEASONS_USE_CASE,
|
||||||
|
useClass: GetLeagueSeasonsUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_LEAGUE_MEMBERSHIPS_USE_CASE,
|
||||||
|
useClass: GetLeagueMembershipsUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_LEAGUE_SCHEDULE_USE_CASE,
|
||||||
|
useClass: GetLeagueScheduleUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_LEAGUE_ADMIN_PERMISSIONS_USE_CASE,
|
||||||
|
useClass: GetLeagueAdminPermissionsUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_LEAGUE_WALLET_USE_CASE,
|
||||||
|
useClass: GetLeagueWalletUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE,
|
||||||
|
useClass: WithdrawFromLeagueWalletUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_SEASON_SPONSORSHIPS_USE_CASE,
|
||||||
useFactory: (
|
useFactory: (
|
||||||
seasonSponsorshipRepo: ISeasonSponsorshipRepository,
|
seasonSponsorshipRepo: ISeasonSponsorshipRepository,
|
||||||
seasonRepo: ISeasonRepository,
|
seasonRepo: ISeasonRepository,
|
||||||
leagueRepo: ILeagueRepository,
|
leagueRepo: ILeagueRepository,
|
||||||
leagueMembershipRepo: ILeagueMembershipRepository,
|
leagueMembershipRepo: ILeagueMembershipRepository,
|
||||||
raceRepo: IRaceRepository,
|
raceRepo: IRaceRepository,
|
||||||
) => new GetSeasonSponsorshipsUseCase(seasonSponsorshipRepo, seasonRepo, leagueRepo, leagueMembershipRepo, raceRepo),
|
presenter: GetSeasonSponsorshipsPresenter,
|
||||||
|
) => new GetSeasonSponsorshipsUseCase(seasonSponsorshipRepo, seasonRepo, leagueRepo, leagueMembershipRepo, raceRepo, presenter),
|
||||||
inject: [
|
inject: [
|
||||||
'ISeasonSponsorshipRepository',
|
'ISeasonSponsorshipRepository',
|
||||||
SEASON_REPOSITORY_TOKEN,
|
SEASON_REPOSITORY_TOKEN,
|
||||||
LEAGUE_REPOSITORY_TOKEN,
|
LEAGUE_REPOSITORY_TOKEN,
|
||||||
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
|
LEAGUE_MEMBERSHIP_REPOSITORY_TOKEN,
|
||||||
RACE_REPOSITORY_TOKEN,
|
RACE_REPOSITORY_TOKEN,
|
||||||
|
'GetSeasonSponsorshipsPresenter',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{ // TODO wtf is this here? doesn't look like it adhers to our concepts
|
||||||
provide: ListLeagueScoringPresetsUseCase,
|
provide: LIST_LEAGUE_SCORING_PRESETS_USE_CASE,
|
||||||
useFactory: () => new ListLeagueScoringPresetsUseCase(listLeagueScoringPresets()),
|
useFactory: (presenter: LeagueScoringPresetsPresenter) => new ListLeagueScoringPresetsUseCase(listLeagueScoringPresets(), presenter),
|
||||||
|
inject: ['LeagueScoringPresetsPresenter'],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
provide: JOIN_LEAGUE_USE_CASE,
|
||||||
|
useClass: JoinLeagueUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: TRANSFER_LEAGUE_OWNERSHIP_USE_CASE,
|
||||||
|
useClass: TransferLeagueOwnershipUseCase,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
provide: GET_LEAGUE_SCORING_CONFIG_USE_CASE,
|
||||||
|
useClass: GetLeagueScoringConfigUseCase,
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
|
import { vi, Mocked } from 'vitest';
|
||||||
import { LeagueService } from './LeagueService';
|
import { LeagueService } from './LeagueService';
|
||||||
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
|
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
|
||||||
import { GetLeagueStandingsUseCase } from '@core/league/application/use-cases/GetLeagueStandingsUseCase';
|
import { GetLeagueStandingsUseCase } from '@core/racing/application/use-cases/GetLeagueStandingsUseCase';
|
||||||
import { GetLeagueStatsUseCase } from '@core/racing/application/use-cases/GetLeagueStatsUseCase';
|
import { GetLeagueStatsUseCase } from '@core/racing/application/use-cases/GetLeagueStatsUseCase';
|
||||||
import { GetLeagueFullConfigUseCase } from '@core/racing/application/use-cases/GetLeagueFullConfigUseCase';
|
import { GetLeagueFullConfigUseCase } from '@core/racing/application/use-cases/GetLeagueFullConfigUseCase';
|
||||||
import { GetLeagueScoringConfigUseCase } from '@core/racing/application/use-cases/GetLeagueScoringConfigUseCase';
|
import { GetLeagueScoringConfigUseCase } from '@core/racing/application/use-cases/GetLeagueScoringConfigUseCase';
|
||||||
@@ -29,20 +30,19 @@ import { Result } from '@core/shared/application/Result';
|
|||||||
|
|
||||||
describe('LeagueService', () => {
|
describe('LeagueService', () => {
|
||||||
let service: LeagueService;
|
let service: LeagueService;
|
||||||
let mockGetTotalLeaguesUseCase: jest.Mocked<GetTotalLeaguesUseCase>;
|
let mockGetTotalLeaguesUseCase: Mocked<GetTotalLeaguesUseCase>;
|
||||||
let mockGetLeagueJoinRequestsUseCase: jest.Mocked<GetLeagueJoinRequestsUseCase>;
|
let mockGetLeagueJoinRequestsUseCase: Mocked<GetLeagueJoinRequestsUseCase>;
|
||||||
let mockApproveLeagueJoinRequestUseCase: jest.Mocked<ApproveLeagueJoinRequestUseCase>;
|
let mockApproveLeagueJoinRequestUseCase: Mocked<ApproveLeagueJoinRequestUseCase>;
|
||||||
let mockGetLeagueFullConfigUseCase: jest.Mocked<GetLeagueFullConfigUseCase>;
|
let mockGetLeagueFullConfigUseCase: Mocked<GetLeagueFullConfigUseCase>;
|
||||||
let mockGetLeagueOwnerSummaryUseCase: jest.Mocked<GetLeagueOwnerSummaryUseCase>;
|
let mockGetLeagueOwnerSummaryUseCase: Mocked<GetLeagueOwnerSummaryUseCase>;
|
||||||
let mockGetLeagueScheduleUseCase: jest.Mocked<GetLeagueScheduleUseCase>;
|
let mockGetLeagueScheduleUseCase: Mocked<GetLeagueScheduleUseCase>;
|
||||||
let mockGetSeasonSponsorshipsUseCase: jest.Mocked<GetSeasonSponsorshipsUseCase>;
|
let mockGetSeasonSponsorshipsUseCase: Mocked<GetSeasonSponsorshipsUseCase>;
|
||||||
let mockLogger: jest.Mocked<Logger>;
|
let mockLogger: Mocked<Logger>;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
const createUseCaseMock = <T extends { execute: unknown }>(): jest.Mocked<T> => ({
|
const createUseCaseMock = <T extends { execute: unknown }>(): Mocked<T> => ({
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
execute: vi.fn(),
|
||||||
execute: jest.fn() as any,
|
}) as Mocked<T>;
|
||||||
}) as jest.Mocked<T>;
|
|
||||||
|
|
||||||
mockGetTotalLeaguesUseCase = createUseCaseMock<GetTotalLeaguesUseCase>();
|
mockGetTotalLeaguesUseCase = createUseCaseMock<GetTotalLeaguesUseCase>();
|
||||||
mockGetLeagueJoinRequestsUseCase = createUseCaseMock<GetLeagueJoinRequestsUseCase>();
|
mockGetLeagueJoinRequestsUseCase = createUseCaseMock<GetLeagueJoinRequestsUseCase>();
|
||||||
@@ -52,11 +52,11 @@ describe('LeagueService', () => {
|
|||||||
mockGetLeagueScheduleUseCase = createUseCaseMock<GetLeagueScheduleUseCase>();
|
mockGetLeagueScheduleUseCase = createUseCaseMock<GetLeagueScheduleUseCase>();
|
||||||
mockGetSeasonSponsorshipsUseCase = createUseCaseMock<GetSeasonSponsorshipsUseCase>();
|
mockGetSeasonSponsorshipsUseCase = createUseCaseMock<GetSeasonSponsorshipsUseCase>();
|
||||||
mockLogger = {
|
mockLogger = {
|
||||||
debug: jest.fn(),
|
debug: vi.fn(),
|
||||||
info: jest.fn(),
|
info: vi.fn(),
|
||||||
warn: jest.fn(),
|
warn: vi.fn(),
|
||||||
error: jest.fn(),
|
error: vi.fn(),
|
||||||
} as unknown as jest.Mocked<Logger>;
|
} as unknown as Mocked<Logger>;
|
||||||
|
|
||||||
service = new LeagueService(
|
service = new LeagueService(
|
||||||
{} as unknown as GetAllLeaguesWithCapacityUseCase,
|
{} as unknown as GetAllLeaguesWithCapacityUseCase,
|
||||||
@@ -130,10 +130,10 @@ describe('LeagueService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should reject league join request', async () => {
|
it('should reject league join request', async () => {
|
||||||
const mockRejectUseCase: jest.Mocked<RejectLeagueJoinRequestUseCase> = {
|
const mockRejectUseCase: Mocked<RejectLeagueJoinRequestUseCase> = {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
execute: jest.fn() as any,
|
execute: vi.fn() as any,
|
||||||
} as unknown as jest.Mocked<RejectLeagueJoinRequestUseCase>;
|
} as unknown as Mocked<RejectLeagueJoinRequestUseCase>;
|
||||||
|
|
||||||
service = new LeagueService(
|
service = new LeagueService(
|
||||||
{} as unknown as GetAllLeaguesWithCapacityUseCase,
|
{} as unknown as GetAllLeaguesWithCapacityUseCase,
|
||||||
@@ -173,10 +173,10 @@ describe('LeagueService', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should remove league member', async () => {
|
it('should remove league member', async () => {
|
||||||
const mockRemoveUseCase: jest.Mocked<RemoveLeagueMemberUseCase> = {
|
const mockRemoveUseCase: Mocked<RemoveLeagueMemberUseCase> = {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
execute: jest.fn() as any,
|
execute: vi.fn() as any,
|
||||||
} as unknown as jest.Mocked<RemoveLeagueMemberUseCase>;
|
} as unknown as Mocked<RemoveLeagueMemberUseCase>;
|
||||||
|
|
||||||
service = new LeagueService(
|
service = new LeagueService(
|
||||||
{} as unknown as GetAllLeaguesWithCapacityUseCase,
|
{} as unknown as GetAllLeaguesWithCapacityUseCase,
|
||||||
@@ -227,15 +227,18 @@ describe('LeagueService', () => {
|
|||||||
} as any;
|
} as any;
|
||||||
|
|
||||||
mockGetLeagueFullConfigUseCase.execute.mockResolvedValue(Result.ok(fullConfig));
|
mockGetLeagueFullConfigUseCase.execute.mockResolvedValue(Result.ok(fullConfig));
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
mockGetLeagueOwnerSummaryUseCase.execute.mockResolvedValue(Result.ok({ summary: null } as any));
|
mockGetLeagueOwnerSummaryUseCase.execute.mockResolvedValue(Result.ok({ summary: null } as any));
|
||||||
|
|
||||||
const joinRequestsSpy = jest
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const joinRequestsSpy = vi
|
||||||
.spyOn(service, 'getLeagueJoinRequests')
|
.spyOn(service, 'getLeagueJoinRequests')
|
||||||
.mockResolvedValue({ joinRequests: [] } as any);
|
.mockResolvedValue({ joinRequests: [] } as any);
|
||||||
const protestsSpy = jest
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const protestsSpy = vi
|
||||||
.spyOn(service, 'getLeagueProtests')
|
.spyOn(service, 'getLeagueProtests')
|
||||||
.mockResolvedValue({ protests: [], racesById: {}, driversById: {} } as any);
|
.mockResolvedValue({ protests: [], racesById: {}, driversById: {} } as any);
|
||||||
const seasonsSpy = jest
|
const seasonsSpy = vi
|
||||||
.spyOn(service, 'getLeagueSeasons')
|
.spyOn(service, 'getLeagueSeasons')
|
||||||
.mockResolvedValue([]);
|
.mockResolvedValue([]);
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,8 @@ import { UpdateLeagueMemberRoleUseCase } from '@core/racing/application/use-case
|
|||||||
import { WithdrawFromLeagueWalletUseCase } from '@core/racing/application/use-cases/WithdrawFromLeagueWalletUseCase';
|
import { WithdrawFromLeagueWalletUseCase } from '@core/racing/application/use-cases/WithdrawFromLeagueWalletUseCase';
|
||||||
|
|
||||||
// API Presenters
|
// API Presenters
|
||||||
|
import { AllLeaguesWithCapacityPresenter } from './presenters/AllLeaguesWithCapacityPresenter';
|
||||||
|
import { ApproveLeagueJoinRequestPresenter } from './presenters/ApproveLeagueJoinRequestPresenter';
|
||||||
import { CreateLeaguePresenter } from './presenters/CreateLeaguePresenter';
|
import { CreateLeaguePresenter } from './presenters/CreateLeaguePresenter';
|
||||||
import { GetLeagueAdminPermissionsPresenter } from './presenters/GetLeagueAdminPermissionsPresenter';
|
import { GetLeagueAdminPermissionsPresenter } from './presenters/GetLeagueAdminPermissionsPresenter';
|
||||||
import { GetLeagueMembershipsPresenter } from './presenters/GetLeagueMembershipsPresenter';
|
import { GetLeagueMembershipsPresenter } from './presenters/GetLeagueMembershipsPresenter';
|
||||||
@@ -81,7 +83,7 @@ import { JoinLeaguePresenter } from './presenters/JoinLeaguePresenter';
|
|||||||
import { LeagueAdminPresenter } from './presenters/LeagueAdminPresenter';
|
import { LeagueAdminPresenter } from './presenters/LeagueAdminPresenter';
|
||||||
import { LeagueConfigPresenter } from './presenters/LeagueConfigPresenter';
|
import { LeagueConfigPresenter } from './presenters/LeagueConfigPresenter';
|
||||||
import { LeagueJoinRequestsPresenter } from './presenters/LeagueJoinRequestsPresenter';
|
import { LeagueJoinRequestsPresenter } from './presenters/LeagueJoinRequestsPresenter';
|
||||||
import { LeagueRacesPresenter, LeagueSchedulePresenter } from './presenters/LeagueSchedulePresenter';
|
import { LeagueSchedulePresenter } from './presenters/LeagueSchedulePresenter';
|
||||||
import { LeagueScoringConfigPresenter } from './presenters/LeagueScoringConfigPresenter';
|
import { LeagueScoringConfigPresenter } from './presenters/LeagueScoringConfigPresenter';
|
||||||
import { LeagueScoringPresetsPresenter } from './presenters/LeagueScoringPresetsPresenter';
|
import { LeagueScoringPresetsPresenter } from './presenters/LeagueScoringPresetsPresenter';
|
||||||
import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter';
|
import { LeagueStandingsPresenter } from './presenters/LeagueStandingsPresenter';
|
||||||
@@ -92,36 +94,36 @@ import { TotalLeaguesPresenter } from './presenters/TotalLeaguesPresenter';
|
|||||||
import { TransferLeagueOwnershipPresenter } from './presenters/TransferLeagueOwnershipPresenter';
|
import { TransferLeagueOwnershipPresenter } from './presenters/TransferLeagueOwnershipPresenter';
|
||||||
import { UpdateLeagueMemberRolePresenter } from './presenters/UpdateLeagueMemberRolePresenter';
|
import { UpdateLeagueMemberRolePresenter } from './presenters/UpdateLeagueMemberRolePresenter';
|
||||||
// Tokens
|
// Tokens
|
||||||
import { LOGGER_TOKEN } from './LeagueProviders';
|
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_RACE_PROTESTS_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 } from './LeagueProviders';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class LeagueService {
|
export class LeagueService {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly getAllLeaguesWithCapacityUseCase: GetAllLeaguesWithCapacityUseCase,
|
@Inject(GET_ALL_LEAGUES_WITH_CAPACITY_USE_CASE) private readonly getAllLeaguesWithCapacityUseCase: GetAllLeaguesWithCapacityUseCase,
|
||||||
private readonly getLeagueStandingsUseCase: GetLeagueStandingsUseCase,
|
@Inject(GET_LEAGUE_STANDINGS_USE_CASE) private readonly getLeagueStandingsUseCase: GetLeagueStandingsUseCase,
|
||||||
private readonly getLeagueStatsUseCase: GetLeagueStatsUseCase,
|
@Inject(GET_LEAGUE_STATS_USE_CASE) private readonly getLeagueStatsUseCase: GetLeagueStatsUseCase,
|
||||||
private readonly getLeagueFullConfigUseCase: GetLeagueFullConfigUseCase,
|
@Inject(GET_LEAGUE_FULL_CONFIG_USE_CASE) private readonly getLeagueFullConfigUseCase: GetLeagueFullConfigUseCase,
|
||||||
private readonly getLeagueScoringConfigUseCase: GetLeagueScoringConfigUseCase,
|
@Inject(GET_LEAGUE_SCORING_CONFIG_USE_CASE) private readonly getLeagueScoringConfigUseCase: GetLeagueScoringConfigUseCase,
|
||||||
private readonly listLeagueScoringPresetsUseCase: ListLeagueScoringPresetsUseCase,
|
@Inject(LIST_LEAGUE_SCORING_PRESETS_USE_CASE) private readonly listLeagueScoringPresetsUseCase: ListLeagueScoringPresetsUseCase,
|
||||||
private readonly joinLeagueUseCase: JoinLeagueUseCase,
|
@Inject(JOIN_LEAGUE_USE_CASE) private readonly joinLeagueUseCase: JoinLeagueUseCase,
|
||||||
private readonly transferLeagueOwnershipUseCase: TransferLeagueOwnershipUseCase,
|
@Inject(TRANSFER_LEAGUE_OWNERSHIP_USE_CASE) private readonly transferLeagueOwnershipUseCase: TransferLeagueOwnershipUseCase,
|
||||||
private readonly createLeagueWithSeasonAndScoringUseCase: CreateLeagueWithSeasonAndScoringUseCase,
|
@Inject(CREATE_LEAGUE_WITH_SEASON_AND_SCORING_USE_CASE) private readonly createLeagueWithSeasonAndScoringUseCase: CreateLeagueWithSeasonAndScoringUseCase,
|
||||||
private readonly getRaceProtestsUseCase: GetRaceProtestsUseCase,
|
@Inject(GET_RACE_PROTESTS_USE_CASE) private readonly getRaceProtestsUseCase: GetRaceProtestsUseCase,
|
||||||
private readonly getTotalLeaguesUseCase: GetTotalLeaguesUseCase,
|
@Inject(GET_TOTAL_LEAGUES_USE_CASE) private readonly getTotalLeaguesUseCase: GetTotalLeaguesUseCase,
|
||||||
private readonly getLeagueJoinRequestsUseCase: GetLeagueJoinRequestsUseCase,
|
@Inject(GET_LEAGUE_JOIN_REQUESTS_USE_CASE) private readonly getLeagueJoinRequestsUseCase: GetLeagueJoinRequestsUseCase,
|
||||||
private readonly approveLeagueJoinRequestUseCase: ApproveLeagueJoinRequestUseCase,
|
@Inject(APPROVE_LEAGUE_JOIN_REQUEST_USE_CASE) private readonly approveLeagueJoinRequestUseCase: ApproveLeagueJoinRequestUseCase,
|
||||||
private readonly rejectLeagueJoinRequestUseCase: RejectLeagueJoinRequestUseCase,
|
@Inject(REJECT_LEAGUE_JOIN_REQUEST_USE_CASE) private readonly rejectLeagueJoinRequestUseCase: RejectLeagueJoinRequestUseCase,
|
||||||
private readonly removeLeagueMemberUseCase: RemoveLeagueMemberUseCase,
|
@Inject(REMOVE_LEAGUE_MEMBER_USE_CASE) private readonly removeLeagueMemberUseCase: RemoveLeagueMemberUseCase,
|
||||||
private readonly updateLeagueMemberRoleUseCase: UpdateLeagueMemberRoleUseCase,
|
@Inject(UPDATE_LEAGUE_MEMBER_ROLE_USE_CASE) private readonly updateLeagueMemberRoleUseCase: UpdateLeagueMemberRoleUseCase,
|
||||||
private readonly getLeagueOwnerSummaryUseCase: GetLeagueOwnerSummaryUseCase,
|
@Inject(GET_LEAGUE_OWNER_SUMMARY_USE_CASE) private readonly getLeagueOwnerSummaryUseCase: GetLeagueOwnerSummaryUseCase,
|
||||||
private readonly getLeagueProtestsUseCase: GetLeagueProtestsUseCase,
|
@Inject(GET_LEAGUE_PROTESTS_USE_CASE) private readonly getLeagueProtestsUseCase: GetLeagueProtestsUseCase,
|
||||||
private readonly getLeagueSeasonsUseCase: GetLeagueSeasonsUseCase,
|
@Inject(GET_LEAGUE_SEASONS_USE_CASE) private readonly getLeagueSeasonsUseCase: GetLeagueSeasonsUseCase,
|
||||||
private readonly getLeagueMembershipsUseCase: GetLeagueMembershipsUseCase,
|
@Inject(GET_LEAGUE_MEMBERSHIPS_USE_CASE) private readonly getLeagueMembershipsUseCase: GetLeagueMembershipsUseCase,
|
||||||
private readonly getLeagueScheduleUseCase: GetLeagueScheduleUseCase,
|
@Inject(GET_LEAGUE_SCHEDULE_USE_CASE) private readonly getLeagueScheduleUseCase: GetLeagueScheduleUseCase,
|
||||||
private readonly getLeagueAdminPermissionsUseCase: GetLeagueAdminPermissionsUseCase,
|
@Inject(GET_LEAGUE_ADMIN_PERMISSIONS_USE_CASE) private readonly getLeagueAdminPermissionsUseCase: GetLeagueAdminPermissionsUseCase,
|
||||||
private readonly getLeagueWalletUseCase: GetLeagueWalletUseCase,
|
@Inject(GET_LEAGUE_WALLET_USE_CASE) private readonly getLeagueWalletUseCase: GetLeagueWalletUseCase,
|
||||||
private readonly withdrawFromLeagueWalletUseCase: WithdrawFromLeagueWalletUseCase,
|
@Inject(WITHDRAW_FROM_LEAGUE_WALLET_USE_CASE) private readonly withdrawFromLeagueWalletUseCase: WithdrawFromLeagueWalletUseCase,
|
||||||
private readonly getSeasonSponsorshipsUseCase: GetSeasonSponsorshipsUseCase,
|
@Inject(GET_SEASON_SPONSORSHIPS_USE_CASE) private readonly getSeasonSponsorshipsUseCase: GetSeasonSponsorshipsUseCase,
|
||||||
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
|
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
@@ -132,7 +134,7 @@ export class LeagueService {
|
|||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
throw new Error(result.unwrapErr().code);
|
throw new Error(result.unwrapErr().code);
|
||||||
}
|
}
|
||||||
return this.getAllLeaguesWithCapacityUseCase.outputPort.present(result); // TODO wrong, must use presenter
|
return (this.getAllLeaguesWithCapacityUseCase.outputPort as AllLeaguesWithCapacityPresenter).getViewModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
async getTotalLeagues(): Promise<TotalLeaguesDTO> {
|
async getTotalLeagues(): Promise<TotalLeaguesDTO> {
|
||||||
@@ -148,12 +150,8 @@ export class LeagueService {
|
|||||||
|
|
||||||
async getLeagueJoinRequests(leagueId: string): Promise<LeagueJoinRequestWithDriverDTO[]> {
|
async getLeagueJoinRequests(leagueId: string): Promise<LeagueJoinRequestWithDriverDTO[]> {
|
||||||
this.logger.debug(`[LeagueService] Fetching join requests for league: ${leagueId}.`);
|
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();
|
const presenter = new LeagueJoinRequestsPresenter();
|
||||||
presenter.present(result.unwrap());
|
await this.getLeagueJoinRequestsUseCase.execute({ leagueId }, presenter);
|
||||||
return presenter.getViewModel()!.joinRequests;
|
return presenter.getViewModel()!.joinRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,12 +222,8 @@ export class LeagueService {
|
|||||||
|
|
||||||
async getLeagueOwnerSummary(query: GetLeagueOwnerSummaryQueryDTO): Promise<LeagueOwnerSummaryDTO> {
|
async getLeagueOwnerSummary(query: GetLeagueOwnerSummaryQueryDTO): Promise<LeagueOwnerSummaryDTO> {
|
||||||
this.logger.debug('Getting league owner summary:', query);
|
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();
|
const presenter = new GetLeagueOwnerSummaryPresenter();
|
||||||
presenter.present(result.unwrap());
|
await this.getLeagueOwnerSummaryUseCase.execute({ leagueId: query.leagueId } as any, presenter);
|
||||||
return presenter.getViewModel()!;
|
return presenter.getViewModel()!;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -243,7 +237,7 @@ export class LeagueService {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const presenter = new LeagueConfigPresenter();
|
const presenter = new LeagueConfigPresenter();
|
||||||
presenter.present(result.unwrap());
|
presenter.present(result.unwrap() as any);
|
||||||
return presenter.getViewModel();
|
return presenter.getViewModel();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('Error getting league full config', error instanceof Error ? error : new Error(String(error)));
|
this.logger.error('Error getting league full config', error instanceof Error ? error : new Error(String(error)));
|
||||||
@@ -271,12 +265,8 @@ export class LeagueService {
|
|||||||
|
|
||||||
async getLeagueMemberships(leagueId: string): Promise<LeagueMembershipsDTO> {
|
async getLeagueMemberships(leagueId: string): Promise<LeagueMembershipsDTO> {
|
||||||
this.logger.debug('Getting league memberships', { leagueId });
|
this.logger.debug('Getting league memberships', { leagueId });
|
||||||
const result = await this.getLeagueMembershipsUseCase.execute({ leagueId });
|
|
||||||
if (result.isErr()) {
|
|
||||||
throw new Error(result.unwrapErr().code);
|
|
||||||
}
|
|
||||||
const presenter = new GetLeagueMembershipsPresenter();
|
const presenter = new GetLeagueMembershipsPresenter();
|
||||||
presenter.present(result.unwrap());
|
await this.getLeagueMembershipsUseCase.execute({ leagueId }, presenter);
|
||||||
return presenter.getViewModel()!.memberships;
|
return presenter.getViewModel()!.memberships;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,9 +276,7 @@ export class LeagueService {
|
|||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
throw new Error(result.unwrapErr().code);
|
throw new Error(result.unwrapErr().code);
|
||||||
}
|
}
|
||||||
const presenter = new LeagueStandingsPresenter();
|
return (this.getLeagueStandingsUseCase.outputPort as LeagueStandingsPresenter).getResponseModel()!;
|
||||||
presenter.present(result.unwrap());
|
|
||||||
return presenter.getViewModel()!;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLeagueSchedule(leagueId: string): Promise<LeagueScheduleDTO> {
|
async getLeagueSchedule(leagueId: string): Promise<LeagueScheduleDTO> {
|
||||||
@@ -318,9 +306,7 @@ export class LeagueService {
|
|||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
throw new Error(result.unwrapErr().code);
|
throw new Error(result.unwrapErr().code);
|
||||||
}
|
}
|
||||||
const presenter = new LeagueStatsPresenter();
|
return this.leagueStatsPresenter.getResponseModel()!;
|
||||||
presenter.present(result.unwrap());
|
|
||||||
return presenter.getViewModel()!;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getLeagueAdminComposite(leagueId: string): Promise<LeagueAdminDTO> {
|
private async getLeagueAdminComposite(leagueId: string): Promise<LeagueAdminDTO> {
|
||||||
@@ -388,23 +374,19 @@ export class LeagueService {
|
|||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
throw new Error(result.unwrapErr().code);
|
throw new Error(result.unwrapErr().code);
|
||||||
}
|
}
|
||||||
const presenter = new CreateLeaguePresenter();
|
return this.createLeaguePresenter.getViewModel()!;
|
||||||
presenter.present(result.unwrap());
|
|
||||||
return presenter.getViewModel()!;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getLeagueScoringConfig(leagueId: string): Promise<LeagueScoringConfigViewModel | null> {
|
async getLeagueScoringConfig(leagueId: string): Promise<LeagueScoringConfigViewModel | null> {
|
||||||
this.logger.debug('Getting league scoring config', { leagueId });
|
this.logger.debug('Getting league scoring config', { leagueId });
|
||||||
|
|
||||||
const presenter = new LeagueScoringConfigPresenter();
|
|
||||||
try {
|
try {
|
||||||
const result = await this.getLeagueScoringConfigUseCase.execute({ leagueId });
|
const result = await this.getLeagueScoringConfigUseCase.execute({ leagueId });
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
this.logger.error('Error getting league scoring config', new Error(result.unwrapErr().code));
|
this.logger.error('Error getting league scoring config', new Error(result.unwrapErr().code));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
presenter.present(result.unwrap());
|
return this.leagueScoringConfigPresenter.getViewModel();
|
||||||
return presenter.getViewModel();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.logger.error('Error getting league scoring config', error instanceof Error ? error : new Error(String(error)));
|
this.logger.error('Error getting league scoring config', error instanceof Error ? error : new Error(String(error)));
|
||||||
return null;
|
return null;
|
||||||
@@ -414,14 +396,12 @@ export class LeagueService {
|
|||||||
async listLeagueScoringPresets(): Promise<LeagueScoringPresetsViewModel> {
|
async listLeagueScoringPresets(): Promise<LeagueScoringPresetsViewModel> {
|
||||||
this.logger.debug('Listing league scoring presets');
|
this.logger.debug('Listing league scoring presets');
|
||||||
|
|
||||||
const result = await this.listLeagueScoringPresetsUseCase.execute();
|
const result = await this.listLeagueScoringPresetsUseCase.execute({});
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
throw new Error(result.unwrapErr().code);
|
throw new Error(result.unwrapErr().code);
|
||||||
}
|
}
|
||||||
|
|
||||||
const presenter = new LeagueScoringPresetsPresenter();
|
return this.leagueScoringPresetsPresenter.getViewModel()!;
|
||||||
await presenter.present(result.unwrap());
|
|
||||||
return presenter.getViewModel()!;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async joinLeague(leagueId: string, driverId: string): Promise<JoinLeagueOutputDTO> {
|
async joinLeague(leagueId: string, driverId: string): Promise<JoinLeagueOutputDTO> {
|
||||||
@@ -435,9 +415,7 @@ export class LeagueService {
|
|||||||
error: error.code,
|
error: error.code,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const presenter = new JoinLeaguePresenter();
|
return this.joinLeaguePresenter.getViewModel()!;
|
||||||
presenter.present(result.unwrap());
|
|
||||||
return presenter.getViewModel()!;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async transferLeagueOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<TransferLeagueOwnershipOutputDTO> {
|
async transferLeagueOwnership(leagueId: string, currentOwnerId: string, newOwnerId: string): Promise<TransferLeagueOwnershipOutputDTO> {
|
||||||
@@ -451,9 +429,7 @@ export class LeagueService {
|
|||||||
error: error.code,
|
error: error.code,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const presenter = new TransferLeagueOwnershipPresenter();
|
return this.transferLeagueOwnershipPresenter.getViewModel()!;
|
||||||
presenter.present(result.unwrap());
|
|
||||||
return presenter.getViewModel()!;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSeasonSponsorships(seasonId: string): Promise<GetSeasonSponsorshipsOutputDTO> {
|
async getSeasonSponsorships(seasonId: string): Promise<GetSeasonSponsorshipsOutputDTO> {
|
||||||
@@ -464,9 +440,7 @@ export class LeagueService {
|
|||||||
throw new Error(result.unwrapErr().code);
|
throw new Error(result.unwrapErr().code);
|
||||||
}
|
}
|
||||||
|
|
||||||
const presenter = new GetSeasonSponsorshipsPresenter();
|
return this.getSeasonSponsorshipsPresenter.getViewModel()!;
|
||||||
presenter.present(result.unwrap());
|
|
||||||
return presenter.getViewModel()!;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getRaces(leagueId: string): Promise<GetLeagueRacesOutputDTO> {
|
async getRaces(leagueId: string): Promise<GetLeagueRacesOutputDTO> {
|
||||||
@@ -477,11 +451,8 @@ export class LeagueService {
|
|||||||
throw new Error(result.unwrapErr().code);
|
throw new Error(result.unwrapErr().code);
|
||||||
}
|
}
|
||||||
|
|
||||||
const presenter = new LeagueRacesPresenter();
|
|
||||||
presenter.present(result.unwrap());
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
races: presenter.getViewModel()!,
|
races: this.leagueRacesPresenter.getViewModel()!,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -491,7 +462,7 @@ export class LeagueService {
|
|||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
throw new Error(result.unwrapErr().code);
|
throw new Error(result.unwrapErr().code);
|
||||||
}
|
}
|
||||||
return result.unwrap();
|
return result.unwrap() as GetLeagueWalletOutputDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
async withdrawFromLeagueWallet(leagueId: string, input: WithdrawFromLeagueWalletInputDTO): Promise<WithdrawFromLeagueWalletOutputDTO> {
|
async withdrawFromLeagueWallet(leagueId: string, input: WithdrawFromLeagueWalletInputDTO): Promise<WithdrawFromLeagueWalletOutputDTO> {
|
||||||
@@ -499,17 +470,14 @@ export class LeagueService {
|
|||||||
const result = await this.withdrawFromLeagueWalletUseCase.execute({
|
const result = await this.withdrawFromLeagueWalletUseCase.execute({
|
||||||
leagueId,
|
leagueId,
|
||||||
amount: input.amount,
|
amount: input.amount,
|
||||||
currency: input.currency,
|
currency: input.currency as 'USD' | 'EUR' | 'GBP',
|
||||||
seasonId: input.seasonId,
|
seasonId: input.seasonId,
|
||||||
destinationAccount: input.destinationAccount,
|
destinationAccount: input.destinationAccount,
|
||||||
});
|
});
|
||||||
if (result.isErr()) {
|
if (result.isErr()) {
|
||||||
const error = result.unwrapErr();
|
const error = result.unwrapErr();
|
||||||
if (error.code === 'WITHDRAWAL_NOT_ALLOWED') {
|
return { success: false, message: error.code };
|
||||||
return { success: false, message: error.code };
|
|
||||||
}
|
|
||||||
throw new Error(error.code);
|
|
||||||
}
|
}
|
||||||
return result.unwrap();
|
return result.unwrap() as WithdrawFromLeagueWalletOutputDTO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||||
import { Result } from '@core/shared/application/Result';
|
|
||||||
import { AllLeaguesWithCapacityDTO, LeagueWithCapacityDTO } from '../dtos/AllLeaguesWithCapacityDTO';
|
import { AllLeaguesWithCapacityDTO, LeagueWithCapacityDTO } from '../dtos/AllLeaguesWithCapacityDTO';
|
||||||
import type { GetAllLeaguesWithCapacityResult } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
|
import type { GetAllLeaguesWithCapacityResult } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
|
||||||
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
|
||||||
|
|
||||||
export class AllLeaguesWithCapacityPresenter implements UseCaseOutputPort<GetAllLeaguesWithCapacityResult, 'REPOSITORY_ERROR'> {
|
export class AllLeaguesWithCapacityPresenter implements UseCaseOutputPort<GetAllLeaguesWithCapacityResult> {
|
||||||
present(result: Result<GetAllLeaguesWithCapacityResult, ApplicationErrorCode<'REPOSITORY_ERROR'>>): AllLeaguesWithCapacityDTO {
|
private result: AllLeaguesWithCapacityDTO | null = null;
|
||||||
const output = result.unwrap();
|
|
||||||
const leagues: LeagueWithCapacityDTO[] = output.leagues.map(league => ({
|
present(result: GetAllLeaguesWithCapacityResult): void {
|
||||||
|
const leagues: LeagueWithCapacityDTO[] = result.leagues.map(league => ({
|
||||||
id: league.league.id.toString(),
|
id: league.league.id.toString(),
|
||||||
name: league.league.name.toString(),
|
name: league.league.name.toString(),
|
||||||
description: league.league.description?.toString() || '',
|
description: league.league.description?.toString() || '',
|
||||||
@@ -17,9 +16,14 @@ export class AllLeaguesWithCapacityPresenter implements UseCaseOutputPort<GetAll
|
|||||||
usedSlots: league.currentDrivers,
|
usedSlots: league.currentDrivers,
|
||||||
socialLinks: league.league.socialLinks || {},
|
socialLinks: league.league.socialLinks || {},
|
||||||
}));
|
}));
|
||||||
return {
|
this.result = {
|
||||||
leagues,
|
leagues,
|
||||||
totalCount: leagues.length,
|
totalCount: leagues.length,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getViewModel(): AllLeaguesWithCapacityDTO {
|
||||||
|
if (!this.result) throw new Error('Presenter not presented');
|
||||||
|
return this.result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,16 @@
|
|||||||
import type { ApproveLeagueJoinRequestResultPort } from '@core/racing/application/ports/output/ApproveLeagueJoinRequestResultPort';
|
|
||||||
|
import type { UseCaseOutputPort } from '@core/shared/application';
|
||||||
|
import { ApproveLeagueJoinRequestResult } from '@core/racing/application/use-cases/ApproveLeagueJoinRequestUseCase';
|
||||||
import type { ApproveLeagueJoinRequestDTO } from '../dtos/ApproveLeagueJoinRequestDTO';
|
import type { ApproveLeagueJoinRequestDTO } from '../dtos/ApproveLeagueJoinRequestDTO';
|
||||||
|
|
||||||
export class ApproveLeagueJoinRequestPresenter {
|
export class ApproveLeagueJoinRequestPresenter implements UseCaseOutputPort<ApproveLeagueJoinRequestResult> {
|
||||||
private result: ApproveLeagueJoinRequestDTO | null = null;
|
private result: ApproveLeagueJoinRequestDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: ApproveLeagueJoinRequestResultPort) {
|
present(output: ApproveLeagueJoinRequestResult) {
|
||||||
this.result = output;
|
this.result = output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import type { CreateLeagueWithSeasonAndScoringOutputPort } from '@core/racing/application/ports/output/CreateLeagueWithSeasonAndScoringOutputPort';
|
import { CreateLeagueWithSeasonAndScoringResult } from '@core/racing/application/use-cases/CreateLeagueWithSeasonAndScoringUseCase';
|
||||||
import type { CreateLeagueViewModel } from '../dtos/CreateLeagueDTO';
|
import type { CreateLeagueViewModel } from '../dtos/CreateLeagueDTO';
|
||||||
|
|
||||||
export class CreateLeaguePresenter {
|
export class CreateLeaguePresenter {
|
||||||
@@ -8,9 +8,9 @@ export class CreateLeaguePresenter {
|
|||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(dto: CreateLeagueWithSeasonAndScoringOutputPort): void {
|
present(dto: CreateLeagueWithSeasonAndScoringResult): void {
|
||||||
this.result = {
|
this.result = {
|
||||||
leagueId: dto.leagueId,
|
leagueId: dto.league.id.toString(),
|
||||||
success: true,
|
success: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
import type { GetLeagueAdminPermissionsOutputPort } from '@core/racing/application/ports/output/GetLeagueAdminPermissionsOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application';
|
||||||
|
import type { GetLeagueAdminPermissionsResult } from '@core/racing/application/use-cases/GetLeagueAdminPermissionsUseCase';
|
||||||
import { LeagueAdminPermissionsDTO } from '../dtos/LeagueAdminPermissionsDTO';
|
import { LeagueAdminPermissionsDTO } from '../dtos/LeagueAdminPermissionsDTO';
|
||||||
import type { Presenter } from '@core/shared/presentation';
|
|
||||||
|
|
||||||
export class GetLeagueAdminPermissionsPresenter implements Presenter<GetLeagueAdminPermissionsOutputPort, LeagueAdminPermissionsDTO> {
|
export class GetLeagueAdminPermissionsPresenter implements UseCaseOutputPort<GetLeagueAdminPermissionsResult> {
|
||||||
private result: LeagueAdminPermissionsDTO | null = null;
|
private result: LeagueAdminPermissionsDTO | null = null;
|
||||||
|
|
||||||
reset(): void {
|
reset(): void {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(port: GetLeagueAdminPermissionsOutputPort): void {
|
present(port: GetLeagueAdminPermissionsResult): void {
|
||||||
this.result = {
|
this.result = {
|
||||||
canRemoveMember: port.canRemoveMember,
|
canRemoveMember: port.permissions.canManageMembers,
|
||||||
canUpdateRoles: port.canUpdateRoles,
|
canUpdateRoles: port.permissions.canManageMembers,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewModel(): LeagueAdminPermissionsDTO | null {
|
getResponseModel(): LeagueAdminPermissionsDTO | null {
|
||||||
return this.result;
|
return this.result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,28 +1,34 @@
|
|||||||
import { GetLeagueMembershipsPresenter } from './GetLeagueMembershipsPresenter';
|
import { GetLeagueMembershipsPresenter } from './GetLeagueMembershipsPresenter';
|
||||||
import type { GetLeagueMembershipsOutputPort } from '@core/racing/application/ports/output/GetLeagueMembershipsOutputPort';
|
import type { GetLeagueMembershipsResult } from '@core/racing/application/use-cases/GetLeagueMembershipsUseCase';
|
||||||
|
|
||||||
describe('GetLeagueMembershipsPresenter', () => {
|
describe('GetLeagueMembershipsPresenter', () => {
|
||||||
it('presents memberships correctly', () => {
|
it('presents memberships correctly', () => {
|
||||||
const presenter = new GetLeagueMembershipsPresenter();
|
const presenter = new GetLeagueMembershipsPresenter();
|
||||||
const output: GetLeagueMembershipsOutputPort = {
|
const output: GetLeagueMembershipsResult = {
|
||||||
memberships: {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
members: [
|
league: {} as any,
|
||||||
{
|
memberships: [
|
||||||
|
{
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
membership: {
|
||||||
driverId: 'driver-1',
|
driverId: 'driver-1',
|
||||||
driver: { id: 'driver-1', name: 'John Doe' },
|
|
||||||
role: 'member',
|
role: 'member',
|
||||||
joinedAt: new Date('2023-01-01'),
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
},
|
joinedAt: {} as any,
|
||||||
],
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
},
|
} as any,
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
driver: { id: 'driver-1', name: 'John Doe' } as any,
|
||||||
|
},
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
presenter.present(output);
|
presenter.present(output);
|
||||||
const vm = presenter.getViewModel();
|
const vm = presenter.getViewModel()!;
|
||||||
|
|
||||||
expect(vm).not.toBeNull();
|
expect(vm).not.toBeNull();
|
||||||
expect(vm!.memberships.members).toHaveLength(1);
|
expect(vm!.memberships.members).toHaveLength(1);
|
||||||
expect(vm!.memberships.members[0].driverId).toBe('driver-1');
|
expect(vm!.memberships.members[0]!.driverId).toBe('driver-1');
|
||||||
expect(vm!.memberships.members[0].driver.name).toBe('John Doe');
|
expect(vm!.memberships.members[0]!.driver.name).toBe('John Doe');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,24 +1,35 @@
|
|||||||
import type { GetLeagueMembershipsOutputPort } from '@core/racing/application/ports/output/GetLeagueMembershipsOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application';
|
||||||
import { LeagueMembershipsDTO, LeagueMemberDTO } from '../dtos/LeagueMembershipsDTO';
|
import { GetLeagueMembershipsResult } from '@core/racing/application/use-cases/GetLeagueMembershipsUseCase';
|
||||||
|
import { LeagueMembershipsDTO } from '../dtos/LeagueMembershipsDTO';
|
||||||
|
import type { LeagueMemberDTO } from '../dtos/LeagueMemberDTO';
|
||||||
|
|
||||||
export interface GetLeagueMembershipsViewModel {
|
export interface GetLeagueMembershipsViewModel {
|
||||||
memberships: LeagueMembershipsDTO;
|
memberships: LeagueMembershipsDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class GetLeagueMembershipsPresenter {
|
export class GetLeagueMembershipsPresenter implements UseCaseOutputPort<GetLeagueMembershipsResult> {
|
||||||
private result: GetLeagueMembershipsViewModel | null = null;
|
private result: GetLeagueMembershipsViewModel | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: GetLeagueMembershipsOutputPort) {
|
present(result: GetLeagueMembershipsResult) {
|
||||||
const members: LeagueMemberDTO[] = output.memberships.members.map(member => ({
|
const members: LeagueMemberDTO[] = result.memberships
|
||||||
driverId: member.driverId,
|
.filter(({ driver }) => driver !== null)
|
||||||
driver: member.driver,
|
.map(({ membership, driver }) => ({
|
||||||
role: member.role,
|
driverId: membership.driverId.toString(),
|
||||||
joinedAt: member.joinedAt,
|
driver: {
|
||||||
}));
|
id: driver!.id,
|
||||||
|
iracingId: driver!.iracingId.toString(),
|
||||||
|
name: driver!.name.toString(),
|
||||||
|
country: driver!.country.toString(),
|
||||||
|
joinedAt: driver!.joinedAt.toDate().toISOString(),
|
||||||
|
...(driver!.bio ? { bio: driver!.bio.toString() } : {}),
|
||||||
|
},
|
||||||
|
role: membership.role.toString() as 'owner' | 'manager' | 'member',
|
||||||
|
joinedAt: membership.joinedAt.toDate(),
|
||||||
|
}));
|
||||||
this.result = {
|
this.result = {
|
||||||
memberships: {
|
memberships: {
|
||||||
members,
|
members,
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ export class GetLeagueProtestsPresenter implements Presenter<GetLeagueProtestsRe
|
|||||||
iracingId: protestingDriver.iracingId.toString(),
|
iracingId: protestingDriver.iracingId.toString(),
|
||||||
name: protestingDriver.name.toString(),
|
name: protestingDriver.name.toString(),
|
||||||
country: protestingDriver.country.toString(),
|
country: protestingDriver.country.toString(),
|
||||||
bio: protestingDriver.bio?.toString(),
|
bio: protestingDriver.bio?.toString() || '',
|
||||||
joinedAt: protestingDriver.joinedAt.toDate().toISOString(),
|
joinedAt: protestingDriver.joinedAt.toDate().toISOString(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -76,8 +76,8 @@ export class GetLeagueProtestsPresenter implements Presenter<GetLeagueProtestsRe
|
|||||||
iracingId: accusedDriver.iracingId.toString(),
|
iracingId: accusedDriver.iracingId.toString(),
|
||||||
name: accusedDriver.name.toString(),
|
name: accusedDriver.name.toString(),
|
||||||
country: accusedDriver.country.toString(),
|
country: accusedDriver.country.toString(),
|
||||||
bio: accusedDriver.bio?.toString(),
|
bio: accusedDriver.bio?.toString() || '',
|
||||||
joinedAt: accusedDriver.joinedAt.toISOString(),
|
joinedAt: accusedDriver.joinedAt.toDate().toISOString(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,34 @@
|
|||||||
import type { GetSeasonSponsorshipsOutputPort } from '@core/racing/application/ports/output/GetSeasonSponsorshipsOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||||
|
import type { GetSeasonSponsorshipsResult } from '@core/racing/application/use-cases/GetSeasonSponsorshipsUseCase';
|
||||||
import { GetSeasonSponsorshipsOutputDTO } from '../dtos/GetSeasonSponsorshipsOutputDTO';
|
import { GetSeasonSponsorshipsOutputDTO } from '../dtos/GetSeasonSponsorshipsOutputDTO';
|
||||||
|
import { SponsorshipDetailDTO } from '../../sponsor/dtos/SponsorshipDetailDTO';
|
||||||
|
|
||||||
export class GetSeasonSponsorshipsPresenter {
|
export class GetSeasonSponsorshipsPresenter implements UseCaseOutputPort<GetSeasonSponsorshipsResult> {
|
||||||
private result: GetSeasonSponsorshipsOutputDTO | null = null;
|
private result: GetSeasonSponsorshipsOutputDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: GetSeasonSponsorshipsOutputPort) {
|
present(result: GetSeasonSponsorshipsResult): void {
|
||||||
this.result = {
|
this.result = {
|
||||||
sponsorships: output?.sponsorships ?? [],
|
sponsorships: result.sponsorships.map(s => ({
|
||||||
|
id: s.id,
|
||||||
|
leagueId: s.leagueId.toString(),
|
||||||
|
leagueName: s.leagueName.toString(),
|
||||||
|
seasonId: s.seasonId,
|
||||||
|
seasonName: s.seasonName,
|
||||||
|
seasonStartDate: s.seasonStartDate,
|
||||||
|
seasonEndDate: s.seasonEndDate,
|
||||||
|
tier: s.tier as 'main' | 'secondary',
|
||||||
|
status: s.status as 'pending' | 'active' | 'expired' | 'cancelled',
|
||||||
|
pricing: s.pricing,
|
||||||
|
platformFee: s.platformFee,
|
||||||
|
netAmount: s.netAmount,
|
||||||
|
metrics: s.metrics,
|
||||||
|
createdAt: s.createdAt,
|
||||||
|
activatedAt: s.activatedAt,
|
||||||
|
} as SponsorshipDetailDTO)),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,18 @@
|
|||||||
import type { JoinLeagueOutputPort } from '@core/racing/application/ports/output/JoinLeagueOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||||
|
import type { JoinLeagueResult } from '@core/racing/application/use-cases/JoinLeagueUseCase';
|
||||||
import type { JoinLeagueOutputDTO } from '../dtos/JoinLeagueOutputDTO';
|
import type { JoinLeagueOutputDTO } from '../dtos/JoinLeagueOutputDTO';
|
||||||
|
|
||||||
export class JoinLeaguePresenter {
|
export class JoinLeaguePresenter implements UseCaseOutputPort<JoinLeagueResult> {
|
||||||
private result: JoinLeagueOutputDTO | null = null;
|
private result: JoinLeagueOutputDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: JoinLeagueOutputPort) {
|
present(result: JoinLeagueResult): void {
|
||||||
this.result = {
|
this.result = {
|
||||||
success: true,
|
success: true,
|
||||||
membershipId: output.membershipId,
|
membershipId: result.membership.id.toString(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
import { LeagueAdminDTO } from '../dtos/LeagueAdminDTO';
|
import { LeagueAdminDTO } from '../dtos/LeagueAdminDTO';
|
||||||
|
import { LeagueJoinRequestDTO } from '../dtos/LeagueJoinRequestDTO';
|
||||||
|
import { LeagueOwnerSummaryDTO } from '../dtos/LeagueOwnerSummaryDTO';
|
||||||
|
import { LeagueConfigFormModelDTO } from '../dtos/LeagueConfigFormModelDTO';
|
||||||
|
import { LeagueAdminProtestsDTO } from '../dtos/LeagueAdminProtestsDTO';
|
||||||
|
import { LeagueSeasonSummaryDTO } from '../dtos/LeagueSeasonSummaryDTO';
|
||||||
|
|
||||||
export class LeagueAdminPresenter {
|
export class LeagueAdminPresenter {
|
||||||
private result: LeagueAdminDTO | null = null;
|
private result: LeagueAdminDTO | null = null;
|
||||||
@@ -15,11 +20,11 @@ export class LeagueAdminPresenter {
|
|||||||
seasons: unknown[];
|
seasons: unknown[];
|
||||||
}) {
|
}) {
|
||||||
this.result = {
|
this.result = {
|
||||||
joinRequests: data.joinRequests,
|
joinRequests: data.joinRequests as LeagueJoinRequestDTO[],
|
||||||
ownerSummary: data.ownerSummary,
|
ownerSummary: data.ownerSummary as LeagueOwnerSummaryDTO | null,
|
||||||
config: { form: data.config },
|
config: { form: data.config as LeagueConfigFormModelDTO | null },
|
||||||
protests: data.protests,
|
protests: data.protests as LeagueAdminProtestsDTO,
|
||||||
seasons: data.seasons,
|
seasons: data.seasons as LeagueSeasonSummaryDTO[],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
import { LeagueConfigPresenter } from './LeagueConfigPresenter';
|
import { LeagueConfigPresenter } from './LeagueConfigPresenter';
|
||||||
import type { LeagueFullConfigOutputPort } from '@core/racing/application/ports/output/LeagueFullConfigOutputPort';
|
|
||||||
|
|
||||||
describe('LeagueConfigPresenter', () => {
|
describe('LeagueConfigPresenter', () => {
|
||||||
const createFullConfig = (overrides: Partial<LeagueFullConfigOutputPort> = {}): LeagueFullConfigOutputPort => {
|
const createFullConfig = (overrides: Partial<any> = {}): any => {
|
||||||
const base: LeagueFullConfigOutputPort = {
|
const base: any = {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
league: {
|
league: {
|
||||||
id: 'league-1',
|
id: 'league-1',
|
||||||
@@ -65,8 +65,8 @@ describe('LeagueConfigPresenter', () => {
|
|||||||
const presenter = new LeagueConfigPresenter();
|
const presenter = new LeagueConfigPresenter();
|
||||||
const fullConfig = createFullConfig();
|
const fullConfig = createFullConfig();
|
||||||
|
|
||||||
presenter.present(fullConfig);
|
presenter.present({ config: fullConfig });
|
||||||
const vm = presenter.getViewModel();
|
const vm = presenter.getViewModel()!;
|
||||||
|
|
||||||
expect(vm).not.toBeNull();
|
expect(vm).not.toBeNull();
|
||||||
expect(vm!.leagueId).toBe('league-1');
|
expect(vm!.leagueId).toBe('league-1');
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
import { LeagueFullConfigOutputPort } from '@core/racing/application/ports/output/LeagueFullConfigOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||||
|
import type { GetLeagueFullConfigResult } from '@core/racing/application/use-cases/GetLeagueFullConfigUseCase';
|
||||||
import { LeagueConfigFormModelDTO } from '../dtos/LeagueConfigFormModelDTO';
|
import { LeagueConfigFormModelDTO } from '../dtos/LeagueConfigFormModelDTO';
|
||||||
import type { Presenter } from '@core/shared/presentation';
|
|
||||||
|
|
||||||
export class LeagueConfigPresenter implements Presenter<LeagueFullConfigOutputPort, LeagueConfigFormModelDTO> {
|
export class LeagueConfigPresenter implements UseCaseOutputPort<GetLeagueFullConfigResult> {
|
||||||
private result: LeagueConfigFormModelDTO | null = null;
|
private result: LeagueConfigFormModelDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(dto: LeagueFullConfigOutputPort) {
|
present(result: GetLeagueFullConfigResult): void {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
const dto = result.config as any;
|
||||||
const league = dto.league;
|
const league = dto.league;
|
||||||
const settings = league.settings;
|
const settings = league.settings;
|
||||||
const stewarding = dto.activeSeason?.stewardingConfig;
|
const stewarding = dto.activeSeason?.stewardingConfig;
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
import { LeagueJoinRequestsPresenter } from './LeagueJoinRequestsPresenter';
|
import { LeagueJoinRequestsPresenter } from './LeagueJoinRequestsPresenter';
|
||||||
import type { GetLeagueJoinRequestsOutputPort } from '@core/racing/application/ports/output/GetLeagueJoinRequestsOutputPort';
|
import type { GetLeagueJoinRequestsResult } from '@core/racing/application/use-cases/GetLeagueJoinRequestsUseCase';
|
||||||
|
|
||||||
describe('LeagueJoinRequestsPresenter', () => {
|
describe('LeagueJoinRequestsPresenter', () => {
|
||||||
it('presents join requests correctly', () => {
|
it('presents join requests correctly', () => {
|
||||||
const presenter = new LeagueJoinRequestsPresenter();
|
const presenter = new LeagueJoinRequestsPresenter();
|
||||||
const output: GetLeagueJoinRequestsOutputPort = {
|
const output: GetLeagueJoinRequestsResult = {
|
||||||
joinRequests: [
|
joinRequests: [
|
||||||
{
|
{
|
||||||
id: 'req-1',
|
id: 'req-1',
|
||||||
@@ -12,17 +12,18 @@ describe('LeagueJoinRequestsPresenter', () => {
|
|||||||
driverId: 'driver-1',
|
driverId: 'driver-1',
|
||||||
requestedAt: new Date('2023-01-01'),
|
requestedAt: new Date('2023-01-01'),
|
||||||
message: 'Please accept me',
|
message: 'Please accept me',
|
||||||
driver: { id: 'driver-1', name: 'John Doe' },
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
driver: { id: 'driver-1', name: 'John Doe' } as any,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
presenter.present(output);
|
presenter.present(output);
|
||||||
const vm = presenter.getViewModel();
|
const vm = presenter.getViewModel()!;
|
||||||
|
|
||||||
expect(vm).not.toBeNull();
|
expect(vm).not.toBeNull();
|
||||||
expect(vm!.joinRequests).toHaveLength(1);
|
expect(vm.joinRequests).toHaveLength(1);
|
||||||
expect(vm!.joinRequests[0].id).toBe('req-1');
|
expect(vm.joinRequests[0]!.id).toBe('req-1');
|
||||||
expect(vm!.joinRequests[0].driver.name).toBe('John Doe');
|
expect(vm.joinRequests[0]!.driver.name).toBe('John Doe');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,25 +1,29 @@
|
|||||||
import type { GetLeagueJoinRequestsOutputPort } from '@core/racing/application/ports/output/GetLeagueJoinRequestsOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application';
|
||||||
|
import { GetLeagueJoinRequestsResult } from '@core/racing/application/use-cases/GetLeagueJoinRequestsUseCase';
|
||||||
import { LeagueJoinRequestWithDriverDTO } from '../dtos/LeagueJoinRequestWithDriverDTO';
|
import { LeagueJoinRequestWithDriverDTO } from '../dtos/LeagueJoinRequestWithDriverDTO';
|
||||||
|
|
||||||
export interface LeagueJoinRequestsViewModel {
|
export interface LeagueJoinRequestsViewModel {
|
||||||
joinRequests: LeagueJoinRequestWithDriverDTO[];
|
joinRequests: LeagueJoinRequestWithDriverDTO[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LeagueJoinRequestsPresenter {
|
export class LeagueJoinRequestsPresenter implements UseCaseOutputPort<GetLeagueJoinRequestsResult> {
|
||||||
private result: LeagueJoinRequestsViewModel | null = null;
|
private result: LeagueJoinRequestsViewModel | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: GetLeagueJoinRequestsOutputPort) {
|
present(result: GetLeagueJoinRequestsResult) {
|
||||||
const joinRequests: LeagueJoinRequestWithDriverDTO[] = output.joinRequests.map(request => ({
|
const joinRequests: LeagueJoinRequestWithDriverDTO[] = result.joinRequests.map(item => ({
|
||||||
id: request.id,
|
id: item.id,
|
||||||
leagueId: request.leagueId,
|
leagueId: item.leagueId,
|
||||||
driverId: request.driverId,
|
driverId: item.driverId,
|
||||||
requestedAt: request.requestedAt,
|
requestedAt: item.requestedAt,
|
||||||
message: request.message,
|
...(item.message ? { message: item.message } : {}),
|
||||||
driver: request.driver,
|
driver: {
|
||||||
|
id: item.driver.id,
|
||||||
|
name: item.driver.name.toString(),
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
this.result = {
|
this.result = {
|
||||||
joinRequests,
|
joinRequests,
|
||||||
|
|||||||
@@ -1,42 +1,33 @@
|
|||||||
import { LeagueOwnerSummaryPresenter } from './LeagueOwnerSummaryPresenter';
|
import { LeagueOwnerSummaryPresenter } from './LeagueOwnerSummaryPresenter';
|
||||||
import type { GetLeagueOwnerSummaryOutputPort } from '@core/racing/application/ports/output/GetLeagueOwnerSummaryOutputPort';
|
import type { GetLeagueOwnerSummaryResult } from '@core/racing/application/use-cases/GetLeagueOwnerSummaryUseCase';
|
||||||
|
|
||||||
describe('LeagueOwnerSummaryPresenter', () => {
|
describe('LeagueOwnerSummaryPresenter', () => {
|
||||||
it('presents owner summary correctly', () => {
|
it('presents owner summary correctly', () => {
|
||||||
const presenter = new LeagueOwnerSummaryPresenter();
|
const presenter = new LeagueOwnerSummaryPresenter();
|
||||||
const output: GetLeagueOwnerSummaryOutputPort = {
|
const output: GetLeagueOwnerSummaryResult = {
|
||||||
summary: {
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
driver: {
|
league: {} as any,
|
||||||
id: 'driver-1',
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
iracingId: '12345',
|
owner: {
|
||||||
name: 'John Doe',
|
id: 'driver-1',
|
||||||
country: 'US',
|
iracingId: '12345',
|
||||||
bio: 'Racing enthusiast',
|
name: 'John Doe',
|
||||||
joinedAt: '2023-01-01',
|
country: 'US',
|
||||||
},
|
bio: 'Racing enthusiast',
|
||||||
rating: 1500,
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
rank: 100,
|
joinedAt: {} as any,
|
||||||
},
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
} as any,
|
||||||
|
rating: 1500,
|
||||||
|
rank: 100,
|
||||||
};
|
};
|
||||||
|
|
||||||
presenter.present(output);
|
presenter.present(output);
|
||||||
const vm = presenter.getViewModel();
|
const vm = presenter.getViewModel()!;
|
||||||
|
|
||||||
expect(vm).not.toBeNull();
|
expect(vm).not.toBeNull();
|
||||||
expect(vm!.driver.id).toBe('driver-1');
|
expect(vm.driver.id).toBe('driver-1');
|
||||||
expect(vm!.rating).toBe(1500);
|
expect(vm.rating).toBe(1500);
|
||||||
expect(vm!.rank).toBe(100);
|
expect(vm.rank).toBe(100);
|
||||||
});
|
|
||||||
|
|
||||||
it('handles null summary', () => {
|
|
||||||
const presenter = new LeagueOwnerSummaryPresenter();
|
|
||||||
const output: GetLeagueOwnerSummaryOutputPort = {
|
|
||||||
summary: null,
|
|
||||||
};
|
|
||||||
|
|
||||||
presenter.present(output);
|
|
||||||
const vm = presenter.getViewModel();
|
|
||||||
|
|
||||||
expect(vm).toBeNull();
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -1,29 +1,26 @@
|
|||||||
import type { GetLeagueOwnerSummaryOutputPort } from '@core/racing/application/ports/output/GetLeagueOwnerSummaryOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application';
|
||||||
|
import { GetLeagueOwnerSummaryResult } from '@core/racing/application/use-cases/GetLeagueOwnerSummaryUseCase';
|
||||||
import { LeagueOwnerSummaryDTO } from '../dtos/LeagueOwnerSummaryDTO';
|
import { LeagueOwnerSummaryDTO } from '../dtos/LeagueOwnerSummaryDTO';
|
||||||
|
|
||||||
export class LeagueOwnerSummaryPresenter {
|
export class LeagueOwnerSummaryPresenter implements UseCaseOutputPort<GetLeagueOwnerSummaryResult> {
|
||||||
private result: LeagueOwnerSummaryDTO | null = null;
|
private result: LeagueOwnerSummaryDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: GetLeagueOwnerSummaryOutputPort) {
|
present(result: GetLeagueOwnerSummaryResult) {
|
||||||
if (!output.summary) {
|
|
||||||
this.result = null;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
this.result = {
|
this.result = {
|
||||||
driver: {
|
driver: {
|
||||||
id: output.summary.driver.id,
|
id: result.owner.id,
|
||||||
iracingId: output.summary.driver.iracingId,
|
iracingId: result.owner.iracingId.toString(),
|
||||||
name: output.summary.driver.name,
|
name: result.owner.name.toString(),
|
||||||
country: output.summary.driver.country,
|
country: result.owner.country.toString(),
|
||||||
bio: output.summary.driver.bio,
|
joinedAt: result.owner.joinedAt.toDate().toISOString(),
|
||||||
joinedAt: output.summary.driver.joinedAt,
|
...(result.owner.bio ? { bio: result.owner.bio.toString() } : {}),
|
||||||
},
|
},
|
||||||
rating: output.summary.rating,
|
rating: result.rating,
|
||||||
rank: output.summary.rank,
|
rank: result.rank,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,22 @@
|
|||||||
import { GetLeagueScheduleOutputPort } from '@core/racing/application/ports/output/GetLeagueScheduleOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application';
|
||||||
|
import { GetLeagueScheduleResult } from '@core/racing/application/use-cases/GetLeagueScheduleUseCase';
|
||||||
import { LeagueScheduleDTO } from '../dtos/LeagueScheduleDTO';
|
import { LeagueScheduleDTO } from '../dtos/LeagueScheduleDTO';
|
||||||
import { RaceDTO } from '../../race/dtos/RaceDTO';
|
import { RaceDTO } from '../../race/dtos/RaceDTO';
|
||||||
|
|
||||||
export class LeagueSchedulePresenter {
|
export class LeagueSchedulePresenter implements UseCaseOutputPort<GetLeagueScheduleResult> {
|
||||||
private result: LeagueScheduleDTO | null = null;
|
private result: LeagueScheduleDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: GetLeagueScheduleOutputPort, leagueName?: string) {
|
present(result: GetLeagueScheduleResult, leagueName?: string) {
|
||||||
this.result = {
|
this.result = {
|
||||||
races: output.races.map<RaceDTO>(race => ({
|
races: result.races.map(race => ({
|
||||||
id: race.id,
|
id: race.race.id,
|
||||||
name: race.name,
|
name: `${race.race.track} - ${race.race.car}`,
|
||||||
date: race.scheduledAt.toISOString(),
|
date: race.race.scheduledAt.toISOString(),
|
||||||
leagueName,
|
...(leagueName ? { leagueName } : {}),
|
||||||
})),
|
})),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -25,19 +26,19 @@ export class LeagueSchedulePresenter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LeagueRacesPresenter {
|
export class LeagueRacesPresenter implements UseCaseOutputPort<GetLeagueScheduleResult> {
|
||||||
private result: RaceDTO[] | null = null;
|
private result: RaceDTO[] | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: GetLeagueScheduleOutputPort, leagueName?: string) {
|
present(result: GetLeagueScheduleResult, leagueName?: string) {
|
||||||
this.result = output.races.map<RaceDTO>(race => ({
|
this.result = result.races.map(race => ({
|
||||||
id: race.id,
|
id: race.race.id,
|
||||||
name: race.name,
|
name: `${race.race.track} - ${race.race.car}`,
|
||||||
date: race.scheduledAt.toISOString(),
|
date: race.race.scheduledAt.toISOString(),
|
||||||
leagueName,
|
...(leagueName ? { leagueName } : {}),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||||
|
import type { GetLeagueScoringConfigResult } from '@core/racing/application/use-cases/GetLeagueScoringConfigUseCase';
|
||||||
import type { ChampionshipConfig } from '@core/racing/domain/types/ChampionshipConfig';
|
import type { ChampionshipConfig } from '@core/racing/domain/types/ChampionshipConfig';
|
||||||
import type { BonusRule } from '@core/racing/domain/types/BonusRule';
|
import type { BonusRule } from '@core/racing/domain/types/BonusRule';
|
||||||
import type { LeagueScoringConfigOutputPort } from '@core/racing/application/ports/output/LeagueScoringConfigOutputPort';
|
|
||||||
import type { LeagueScoringPresetOutputPort } from '@core/racing/application/ports/output/LeagueScoringPresetOutputPort';
|
|
||||||
|
|
||||||
export interface LeagueScoringChampionshipViewModel {
|
export interface LeagueScoringChampionshipViewModel {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -24,33 +24,31 @@ export interface LeagueScoringConfigViewModel {
|
|||||||
championships: LeagueScoringChampionshipViewModel[];
|
championships: LeagueScoringChampionshipViewModel[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LeagueScoringConfigPresenter {
|
export class LeagueScoringConfigPresenter implements UseCaseOutputPort<GetLeagueScoringConfigResult> {
|
||||||
private viewModel: LeagueScoringConfigViewModel | null = null;
|
private viewModel: LeagueScoringConfigViewModel | null = null;
|
||||||
|
|
||||||
reset(): void {
|
reset(): void {
|
||||||
this.viewModel = null;
|
this.viewModel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(data: LeagueScoringConfigOutputPort): LeagueScoringConfigViewModel {
|
present(result: GetLeagueScoringConfigResult): void {
|
||||||
const championships: LeagueScoringChampionshipViewModel[] =
|
const championships: LeagueScoringChampionshipViewModel[] =
|
||||||
data.championships.map((champ) => this.mapChampionship(champ));
|
result.scoringConfig.championships.map((champ) => this.mapChampionship(champ));
|
||||||
|
|
||||||
const dropPolicySummary =
|
const dropPolicySummary =
|
||||||
data.preset?.dropPolicySummary ??
|
result.preset?.dropPolicySummary ??
|
||||||
this.deriveDropPolicyDescriptionFromChampionships(data.championships);
|
this.deriveDropPolicyDescriptionFromChampionships(result.scoringConfig.championships);
|
||||||
|
|
||||||
this.viewModel = {
|
this.viewModel = {
|
||||||
leagueId: data.leagueId,
|
leagueId: result.league.id.toString(),
|
||||||
seasonId: data.seasonId,
|
seasonId: result.season.id,
|
||||||
gameId: data.gameId,
|
gameId: result.game.id.toString(),
|
||||||
gameName: data.gameName,
|
gameName: result.game.name.toString(),
|
||||||
scoringPresetId: data.scoringPresetId ?? 'custom',
|
scoringPresetId: result.scoringConfig.scoringPresetId?.toString() ?? 'custom',
|
||||||
scoringPresetName: data.preset?.name ?? 'Custom',
|
scoringPresetName: result.preset?.name ?? 'Custom',
|
||||||
dropPolicySummary,
|
dropPolicySummary,
|
||||||
championships,
|
championships,
|
||||||
};
|
};
|
||||||
|
|
||||||
return this.viewModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewModel(): LeagueScoringConfigViewModel | null {
|
getViewModel(): LeagueScoringConfigViewModel | null {
|
||||||
|
|||||||
@@ -1,22 +1,22 @@
|
|||||||
import type { LeagueScoringPresetsOutputPort } from '@core/racing/application/ports/output/LeagueScoringPresetsOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||||
import type { LeagueScoringPresetOutputPort } from '@core/racing/application/ports/output/LeagueScoringPresetOutputPort';
|
import type { ListLeagueScoringPresetsResult, LeagueScoringPreset } from '@core/racing/application/use-cases/ListLeagueScoringPresetsUseCase';
|
||||||
|
|
||||||
export interface LeagueScoringPresetsViewModel {
|
export interface LeagueScoringPresetsViewModel {
|
||||||
presets: LeagueScoringPresetOutputPort[];
|
presets: LeagueScoringPreset[];
|
||||||
totalCount: number;
|
totalCount: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export class LeagueScoringPresetsPresenter {
|
export class LeagueScoringPresetsPresenter implements UseCaseOutputPort<ListLeagueScoringPresetsResult> {
|
||||||
private viewModel: LeagueScoringPresetsViewModel | null = null;
|
private viewModel: LeagueScoringPresetsViewModel | null = null;
|
||||||
|
|
||||||
reset(): void {
|
reset(): void {
|
||||||
this.viewModel = null;
|
this.viewModel = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: LeagueScoringPresetsOutputPort): void {
|
present(result: ListLeagueScoringPresetsResult): void {
|
||||||
this.viewModel = {
|
this.viewModel = {
|
||||||
presets: output.presets,
|
presets: result.presets,
|
||||||
totalCount: output.presets.length,
|
totalCount: result.presets.length,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,24 @@
|
|||||||
import { LeagueStandingsOutputPort } from '@core/racing/application/ports/output/LeagueStandingsOutputPort';
|
import type { GetLeagueStandingsResult } from '@core/racing/application/use-cases/GetLeagueStandingsUseCase';
|
||||||
import { LeagueStandingsDTO } from '../dtos/LeagueStandingsDTO';
|
import { LeagueStandingsDTO } from '../dtos/LeagueStandingsDTO';
|
||||||
import type { Presenter } from '@core/shared/presentation';
|
import type { Presenter } from '@core/shared/presentation';
|
||||||
|
|
||||||
export class LeagueStandingsPresenter implements Presenter<LeagueStandingsOutputPort, LeagueStandingsDTO> {
|
export class LeagueStandingsPresenter implements Presenter<GetLeagueStandingsResult, LeagueStandingsDTO> {
|
||||||
private result: LeagueStandingsDTO | null = null;
|
private result: LeagueStandingsDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(dto: LeagueStandingsOutputPort) {
|
present(dto: GetLeagueStandingsResult) {
|
||||||
const standings = dto.standings.map(standing => ({
|
const standings = dto.standings.map(standing => ({
|
||||||
driverId: standing.driverId,
|
driverId: standing.driverId,
|
||||||
driver: {
|
driver: {
|
||||||
id: standing.driver.id,
|
id: standing.driver.id,
|
||||||
name: standing.driver.name,
|
iracingId: standing.driver.iracingId.toString(),
|
||||||
// Add other DriverDto fields if needed, but for now just id and name
|
name: standing.driver.name.toString(),
|
||||||
|
country: standing.driver.country.toString(),
|
||||||
|
...(standing.driver.bio ? { bio: standing.driver.bio.toString() } : {}),
|
||||||
|
joinedAt: standing.driver.joinedAt.toString(),
|
||||||
},
|
},
|
||||||
points: standing.points,
|
points: standing.points,
|
||||||
rank: standing.rank,
|
rank: standing.rank,
|
||||||
@@ -23,7 +26,7 @@ export class LeagueStandingsPresenter implements Presenter<LeagueStandingsOutput
|
|||||||
this.result = { standings };
|
this.result = { standings };
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewModel(): LeagueStandingsDTO {
|
getResponseModel(): LeagueStandingsDTO {
|
||||||
if (!this.result) throw new Error('Presenter not presented');
|
if (!this.result) throw new Error('Presenter not presented');
|
||||||
return this.result;
|
return this.result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,23 @@
|
|||||||
import { LeagueStatsOutputPort } from '@core/racing/application/ports/output/LeagueStatsOutputPort';
|
import type { GetLeagueStatsResult } from '@core/racing/application/use-cases/GetLeagueStatsUseCase';
|
||||||
import { LeagueStatsDTO } from '../dtos/LeagueStatsDTO';
|
import { LeagueStatsDTO } from '../dtos/LeagueStatsDTO';
|
||||||
import type { Presenter } from '@core/shared/presentation';
|
import type { Presenter } from '@core/shared/presentation';
|
||||||
|
|
||||||
export class LeagueStatsPresenter implements Presenter<LeagueStatsOutputPort, LeagueStatsDTO> {
|
export class LeagueStatsPresenter implements Presenter<GetLeagueStatsResult, LeagueStatsDTO> {
|
||||||
private result: LeagueStatsDTO | null = null;
|
private result: LeagueStatsDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(dto: LeagueStatsOutputPort) {
|
present(dto: GetLeagueStatsResult) {
|
||||||
this.result = dto;
|
this.result = {
|
||||||
|
totalMembers: dto.driverCount,
|
||||||
|
totalRaces: dto.raceCount,
|
||||||
|
averageRating: dto.averageRating,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewModel(): LeagueStatsDTO | null {
|
getResponseModel(): LeagueStatsDTO | null {
|
||||||
return this.result;
|
return this.result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,18 @@
|
|||||||
import type { RejectLeagueJoinRequestOutputPort } from '@core/racing/application/ports/output/RejectLeagueJoinRequestOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||||
|
import type { RejectLeagueJoinRequestResult } from '@core/racing/application/use-cases/RejectLeagueJoinRequestUseCase';
|
||||||
import type { RejectJoinRequestOutputDTO } from '../dtos/RejectJoinRequestOutputDTO';
|
import type { RejectJoinRequestOutputDTO } from '../dtos/RejectJoinRequestOutputDTO';
|
||||||
|
|
||||||
export class RejectLeagueJoinRequestPresenter {
|
export class RejectLeagueJoinRequestPresenter implements UseCaseOutputPort<RejectLeagueJoinRequestResult> {
|
||||||
private result: RejectJoinRequestOutputDTO | null = null;
|
private result: RejectJoinRequestOutputDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: RejectLeagueJoinRequestOutputPort) {
|
present(_result: RejectLeagueJoinRequestResult): void {
|
||||||
this.result = {
|
this.result = {
|
||||||
success: output.success,
|
success: true,
|
||||||
message: output.message,
|
message: 'Join request rejected successfully',
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
import type { RemoveLeagueMemberOutputPort } from '@core/racing/application/ports/output/RemoveLeagueMemberOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||||
|
import type { RemoveLeagueMemberResult } from '@core/racing/application/use-cases/RemoveLeagueMemberUseCase';
|
||||||
import type { RemoveLeagueMemberOutputDTO } from '../dtos/RemoveLeagueMemberOutputDTO';
|
import type { RemoveLeagueMemberOutputDTO } from '../dtos/RemoveLeagueMemberOutputDTO';
|
||||||
|
|
||||||
export class RemoveLeagueMemberPresenter {
|
export class RemoveLeagueMemberPresenter implements UseCaseOutputPort<RemoveLeagueMemberResult> {
|
||||||
private result: RemoveLeagueMemberOutputDTO | null = null;
|
private result: RemoveLeagueMemberOutputDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: RemoveLeagueMemberOutputPort) {
|
present(_result: RemoveLeagueMemberResult): void {
|
||||||
this.result = {
|
this.result = {
|
||||||
success: output.success,
|
success: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { GetTotalLeaguesOutputPort } from '@core/racing/application/ports/output/GetTotalLeaguesOutputPort';
|
import type { GetTotalLeaguesResult } from '@core/racing/application/use-cases/GetTotalLeaguesUseCase';
|
||||||
import { TotalLeaguesDTO } from '../dtos/TotalLeaguesDTO';
|
import { TotalLeaguesDTO } from '../dtos/TotalLeaguesDTO';
|
||||||
|
|
||||||
export class TotalLeaguesPresenter {
|
export class TotalLeaguesPresenter {
|
||||||
@@ -8,13 +8,13 @@ export class TotalLeaguesPresenter {
|
|||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: GetTotalLeaguesOutputPort) {
|
present(output: GetTotalLeaguesResult) {
|
||||||
this.result = {
|
this.result = {
|
||||||
totalLeagues: output.totalLeagues,
|
totalLeagues: output.totalLeagues,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
getViewModel(): TotalLeaguesDTO | null {
|
getResponseModel(): TotalLeaguesDTO | null {
|
||||||
return this.result;
|
return this.result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,17 @@
|
|||||||
import type { TransferLeagueOwnershipOutputPort } from '@core/racing/application/ports/output/TransferLeagueOwnershipOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||||
|
import type { TransferLeagueOwnershipResult } from '@core/racing/application/use-cases/TransferLeagueOwnershipUseCase';
|
||||||
import type { TransferLeagueOwnershipOutputDTO } from '../dtos/TransferLeagueOwnershipOutputDTO';
|
import type { TransferLeagueOwnershipOutputDTO } from '../dtos/TransferLeagueOwnershipOutputDTO';
|
||||||
|
|
||||||
export class TransferLeagueOwnershipPresenter {
|
export class TransferLeagueOwnershipPresenter implements UseCaseOutputPort<TransferLeagueOwnershipResult> {
|
||||||
private result: TransferLeagueOwnershipOutputDTO | null = null;
|
private result: TransferLeagueOwnershipOutputDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: TransferLeagueOwnershipOutputPort) {
|
present(_result: TransferLeagueOwnershipResult): void {
|
||||||
this.result = {
|
this.result = {
|
||||||
success: output.success,
|
success: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,17 @@
|
|||||||
import type { UpdateLeagueMemberRoleOutputPort } from '@core/racing/application/ports/output/UpdateLeagueMemberRoleOutputPort';
|
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
|
||||||
|
import type { UpdateLeagueMemberRoleResult } from '@core/racing/application/use-cases/UpdateLeagueMemberRoleUseCase';
|
||||||
import type { UpdateLeagueMemberRoleOutputDTO } from '../dtos/UpdateLeagueMemberRoleOutputDTO';
|
import type { UpdateLeagueMemberRoleOutputDTO } from '../dtos/UpdateLeagueMemberRoleOutputDTO';
|
||||||
|
|
||||||
export class UpdateLeagueMemberRolePresenter {
|
export class UpdateLeagueMemberRolePresenter implements UseCaseOutputPort<UpdateLeagueMemberRoleResult> {
|
||||||
private result: UpdateLeagueMemberRoleOutputDTO | null = null;
|
private result: UpdateLeagueMemberRoleOutputDTO | null = null;
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
this.result = null;
|
this.result = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
present(output: UpdateLeagueMemberRoleOutputPort) {
|
present(_result: UpdateLeagueMemberRoleResult): void {
|
||||||
this.result = {
|
this.result = {
|
||||||
success: output.success,
|
success: true,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ export interface ApproveLeagueJoinRequestResult {
|
|||||||
export class ApproveLeagueJoinRequestUseCase {
|
export class ApproveLeagueJoinRequestUseCase {
|
||||||
constructor(
|
constructor(
|
||||||
private readonly leagueMembershipRepository: ILeagueMembershipRepository,
|
private readonly leagueMembershipRepository: ILeagueMembershipRepository,
|
||||||
private readonly output: UseCaseOutputPort<ApproveLeagueJoinRequestResult>,
|
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async execute(
|
async execute(
|
||||||
input: ApproveLeagueJoinRequestInput,
|
input: ApproveLeagueJoinRequestInput,
|
||||||
|
output: UseCaseOutputPort<ApproveLeagueJoinRequestResult>,
|
||||||
): Promise<Result<void, ApplicationErrorCode<'JOIN_REQUEST_NOT_FOUND'>>> {
|
): Promise<Result<void, ApplicationErrorCode<'JOIN_REQUEST_NOT_FOUND'>>> {
|
||||||
const requests = await this.leagueMembershipRepository.getJoinRequests(input.leagueId);
|
const requests = await this.leagueMembershipRepository.getJoinRequests(input.leagueId);
|
||||||
const request = requests.find(r => r.id === input.requestId);
|
const request = requests.find(r => r.id === input.requestId);
|
||||||
@@ -41,7 +41,7 @@ export class ApproveLeagueJoinRequestUseCase {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const result: ApproveLeagueJoinRequestResult = { success: true, message: 'Join request approved.' };
|
const result: ApproveLeagueJoinRequestResult = { success: true, message: 'Join request approved.' };
|
||||||
this.output.present(result);
|
output.present(result);
|
||||||
|
|
||||||
return Result.ok(undefined);
|
return Result.ok(undefined);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user