Some checks failed
CI / lint-typecheck (pull_request) Failing after 4m50s
CI / tests (pull_request) Has been skipped
CI / contract-tests (pull_request) Has been skipped
CI / e2e-tests (pull_request) Has been skipped
CI / comment-pr (pull_request) Has been skipped
CI / commit-types (pull_request) Has been skipped
188 lines
6.1 KiB
TypeScript
188 lines
6.1 KiB
TypeScript
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<LeagueData> {
|
|
// 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;
|
|
}
|
|
}
|