This commit is contained in:
2025-12-07 00:18:02 +01:00
parent 70d5f5689e
commit 5ca2454853
20 changed files with 4461 additions and 790 deletions

View File

@@ -9,12 +9,16 @@ import {
getDriverRepository,
getCreateLeagueWithSeasonAndScoringUseCase,
} from '@/lib/di-container';
import { LeagueName } from '@gridpilot/racing/domain/value-objects/LeagueName';
import { LeagueDescription } from '@gridpilot/racing/domain/value-objects/LeagueDescription';
import { GameConstraints } from '@gridpilot/racing/domain/value-objects/GameConstraints';
export type WizardStep = 1 | 2 | 3 | 4 | 5;
export type WizardStep = 1 | 2 | 3 | 4 | 5 | 6;
export interface WizardErrors {
basics?: {
name?: string;
description?: string;
visibility?: string;
};
structure?: {
@@ -43,42 +47,86 @@ export function validateLeagueWizardStep(
): WizardErrors {
const errors: WizardErrors = {};
// Step 1: Basics (name, description, game)
if (step === 1) {
const basicsErrors: NonNullable<WizardErrors['basics']> = {};
if (!form.basics.name.trim()) {
basicsErrors.name = 'Name is required';
// Use LeagueName value object for validation
const nameValidation = LeagueName.validate(form.basics.name);
if (!nameValidation.valid) {
basicsErrors.name = nameValidation.error;
}
if (!form.basics.visibility) {
basicsErrors.visibility = 'Visibility is required';
// Use LeagueDescription value object for validation
const descValidation = LeagueDescription.validate(form.basics.description ?? '');
if (!descValidation.valid) {
basicsErrors.description = descValidation.error;
}
if (Object.keys(basicsErrors).length > 0) {
errors.basics = basicsErrors;
}
}
// Step 2: Visibility (ranked/unranked)
if (step === 2) {
const basicsErrors: NonNullable<WizardErrors['basics']> = {};
if (!form.basics.visibility) {
basicsErrors.visibility = 'Visibility is required';
}
if (Object.keys(basicsErrors).length > 0) {
errors.basics = basicsErrors;
}
}
// Step 3: Structure (solo vs teams)
if (step === 3) {
const structureErrors: NonNullable<WizardErrors['structure']> = {};
const gameConstraints = GameConstraints.forGame(form.basics.gameId);
if (form.structure.mode === 'solo') {
if (!form.structure.maxDrivers || form.structure.maxDrivers <= 0) {
structureErrors.maxDrivers =
'Max drivers must be greater than 0 for solo leagues';
} else {
// Validate against game constraints
const driverValidation = gameConstraints.validateDriverCount(form.structure.maxDrivers);
if (!driverValidation.valid) {
structureErrors.maxDrivers = driverValidation.error;
}
}
} else if (form.structure.mode === 'fixedTeams') {
if (!form.structure.maxTeams || form.structure.maxTeams <= 0) {
structureErrors.maxTeams =
'Max teams must be greater than 0 for team leagues';
} else {
// Validate against game constraints
const teamValidation = gameConstraints.validateTeamCount(form.structure.maxTeams);
if (!teamValidation.valid) {
structureErrors.maxTeams = teamValidation.error;
}
}
if (!form.structure.driversPerTeam || form.structure.driversPerTeam <= 0) {
structureErrors.driversPerTeam =
'Drivers per team must be greater than 0';
}
// Validate total driver count
if (form.structure.maxDrivers) {
const driverValidation = gameConstraints.validateDriverCount(form.structure.maxDrivers);
if (!driverValidation.valid) {
structureErrors.maxDrivers = driverValidation.error;
}
}
}
if (Object.keys(structureErrors).length > 0) {
errors.structure = structureErrors;
}
}
if (step === 3) {
// Step 4: Schedule (timings)
if (step === 4) {
const timingsErrors: NonNullable<WizardErrors['timings']> = {};
if (!form.timings.qualifyingMinutes || form.timings.qualifyingMinutes <= 0) {
timingsErrors.qualifyingMinutes =
@@ -93,7 +141,8 @@ export function validateLeagueWizardStep(
}
}
if (step === 4) {
// Step 5: Scoring
if (step === 5) {
const scoringErrors: NonNullable<WizardErrors['scoring']> = {};
if (!form.scoring.patternId && !form.scoring.customScoringEnabled) {
scoringErrors.patternId =
@@ -104,6 +153,8 @@ export function validateLeagueWizardStep(
}
}
// Step 6: Review - no validation needed, it's just review
return errors;
}
@@ -137,6 +188,7 @@ export function validateAllLeagueWizardSteps(
merge(validateLeagueWizardStep(form, 2));
merge(validateLeagueWizardStep(form, 3));
merge(validateLeagueWizardStep(form, 4));
merge(validateLeagueWizardStep(form, 5));
return aggregate;
}