import { LeagueRepository, LeagueData } from '../ports/LeagueRepository'; import { LeagueEventPublisher, LeagueCreatedEvent } from '../ports/LeagueEventPublisher'; import { LeagueCreateCommand } from '../ports/LeagueCreateCommand'; export class CreateLeagueUseCase { constructor( private readonly leagueRepository: LeagueRepository, private readonly eventPublisher: LeagueEventPublisher, ) {} async execute(command: LeagueCreateCommand): Promise { // Validate command if (!command.name || command.name.trim() === '') { throw new Error('League name is required'); } if (command.name.length > 255) { throw new Error('League name is too long'); } if (!command.ownerId || command.ownerId.trim() === '') { throw new Error('Owner ID is required'); } if (command.maxDrivers !== undefined && command.maxDrivers < 1) { throw new Error('Max drivers must be at least 1'); } // Create league data const leagueId = `league-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`; const now = new Date(); const leagueData: LeagueData = { id: leagueId, name: command.name, description: command.description || null, visibility: command.visibility, ownerId: command.ownerId, status: 'active', createdAt: now, updatedAt: now, maxDrivers: command.maxDrivers || null, approvalRequired: command.approvalRequired, lateJoinAllowed: command.lateJoinAllowed, raceFrequency: command.raceFrequency || null, raceDay: command.raceDay || null, raceTime: command.raceTime || null, tracks: command.tracks || null, scoringSystem: command.scoringSystem || null, bonusPointsEnabled: command.bonusPointsEnabled, penaltiesEnabled: command.penaltiesEnabled, protestsEnabled: command.protestsEnabled, appealsEnabled: command.appealsEnabled, stewardTeam: command.stewardTeam || null, gameType: command.gameType || null, skillLevel: command.skillLevel || null, category: command.category || null, tags: command.tags || null, }; // Save league to repository const savedLeague = await this.leagueRepository.create(leagueData); // Initialize league stats const defaultStats = { leagueId, memberCount: 1, raceCount: 0, sponsorCount: 0, prizePool: 0, rating: 0, reviewCount: 0, }; await this.leagueRepository.updateStats(leagueId, defaultStats); // Initialize league financials const defaultFinancials = { leagueId, walletBalance: 0, totalRevenue: 0, totalFees: 0, pendingPayouts: 0, netBalance: 0, }; await this.leagueRepository.updateFinancials(leagueId, defaultFinancials); // Initialize stewarding metrics const defaultStewardingMetrics = { leagueId, averageResolutionTime: 0, averageProtestResolutionTime: 0, averagePenaltyAppealSuccessRate: 0, averageProtestSuccessRate: 0, averageStewardingActionSuccessRate: 0, }; await this.leagueRepository.updateStewardingMetrics(leagueId, defaultStewardingMetrics); // Initialize performance metrics const defaultPerformanceMetrics = { leagueId, averageLapTime: 0, averageFieldSize: 0, averageIncidentCount: 0, averagePenaltyCount: 0, averageProtestCount: 0, averageStewardingActionCount: 0, }; await this.leagueRepository.updatePerformanceMetrics(leagueId, defaultPerformanceMetrics); // Initialize rating metrics const defaultRatingMetrics = { leagueId, overallRating: 0, ratingTrend: 0, rankTrend: 0, pointsTrend: 0, winRateTrend: 0, podiumRateTrend: 0, dnfRateTrend: 0, }; await this.leagueRepository.updateRatingMetrics(leagueId, defaultRatingMetrics); // Initialize trend metrics const defaultTrendMetrics = { leagueId, incidentRateTrend: 0, penaltyRateTrend: 0, protestRateTrend: 0, stewardingActionRateTrend: 0, stewardingTimeTrend: 0, protestResolutionTimeTrend: 0, }; await this.leagueRepository.updateTrendMetrics(leagueId, defaultTrendMetrics); // Initialize success rate metrics const defaultSuccessRateMetrics = { leagueId, penaltyAppealSuccessRate: 0, protestSuccessRate: 0, stewardingActionSuccessRate: 0, stewardingActionAppealSuccessRate: 0, stewardingActionPenaltySuccessRate: 0, stewardingActionProtestSuccessRate: 0, }; await this.leagueRepository.updateSuccessRateMetrics(leagueId, defaultSuccessRateMetrics); // Initialize resolution time metrics const defaultResolutionTimeMetrics = { leagueId, averageStewardingTime: 0, averageProtestResolutionTime: 0, averageStewardingActionAppealPenaltyProtestResolutionTime: 0, }; await this.leagueRepository.updateResolutionTimeMetrics(leagueId, defaultResolutionTimeMetrics); // Initialize complex success rate metrics const defaultComplexSuccessRateMetrics = { leagueId, stewardingActionAppealPenaltyProtestSuccessRate: 0, stewardingActionAppealProtestSuccessRate: 0, stewardingActionPenaltyProtestSuccessRate: 0, stewardingActionAppealPenaltyProtestSuccessRate2: 0, }; await this.leagueRepository.updateComplexSuccessRateMetrics(leagueId, defaultComplexSuccessRateMetrics); // Initialize complex resolution time metrics const defaultComplexResolutionTimeMetrics = { leagueId, stewardingActionAppealPenaltyProtestResolutionTime: 0, stewardingActionAppealProtestResolutionTime: 0, stewardingActionPenaltyProtestResolutionTime: 0, stewardingActionAppealPenaltyProtestResolutionTime2: 0, }; await this.leagueRepository.updateComplexResolutionTimeMetrics(leagueId, defaultComplexResolutionTimeMetrics); // Emit event const event: LeagueCreatedEvent = { type: 'LeagueCreatedEvent', leagueId, ownerId: command.ownerId, timestamp: now, }; await this.eventPublisher.emitLeagueCreated(event); return savedLeague; } }