more seeds
This commit is contained in:
@@ -10,16 +10,28 @@ export class RacingLeagueFactory {
|
||||
|
||||
create(): League[] {
|
||||
const leagueCount = 20;
|
||||
const pointsSystems = ['f1-2024', 'indycar', 'custom'] as const;
|
||||
const qualifyingFormats = ['open', 'single-lap'] as const;
|
||||
|
||||
// Create diverse league configurations
|
||||
const leagueConfigs = [
|
||||
// Small sprint leagues
|
||||
{ maxDrivers: 16, sessionDuration: 30, pointsSystem: 'f1-2024' as const, qualifyingFormat: 'single-lap' as const },
|
||||
{ maxDrivers: 20, sessionDuration: 45, pointsSystem: 'f1-2024' as const, qualifyingFormat: 'open' as const },
|
||||
// Medium endurance leagues
|
||||
{ maxDrivers: 24, sessionDuration: 60, pointsSystem: 'indycar' as const, qualifyingFormat: 'open' as const },
|
||||
{ maxDrivers: 28, sessionDuration: 90, pointsSystem: 'custom' as const, qualifyingFormat: 'open' as const },
|
||||
// Large mixed leagues
|
||||
{ maxDrivers: 32, sessionDuration: 120, pointsSystem: 'f1-2024' as const, qualifyingFormat: 'open' as const },
|
||||
{ maxDrivers: 36, sessionDuration: 75, pointsSystem: 'indycar' as const, qualifyingFormat: 'single-lap' as const },
|
||||
{ maxDrivers: 40, sessionDuration: 100, pointsSystem: 'custom' as const, qualifyingFormat: 'open' as const },
|
||||
{ maxDrivers: 44, sessionDuration: 85, pointsSystem: 'f1-2024' as const, qualifyingFormat: 'open' as const },
|
||||
{ maxDrivers: 48, sessionDuration: 110, pointsSystem: 'indycar' as const, qualifyingFormat: 'single-lap' as const },
|
||||
{ maxDrivers: 50, sessionDuration: 95, pointsSystem: 'custom' as const, qualifyingFormat: 'open' as const },
|
||||
];
|
||||
|
||||
return Array.from({ length: leagueCount }, (_, idx) => {
|
||||
const i = idx + 1;
|
||||
const owner = faker.helpers.arrayElement(this.drivers);
|
||||
const socialLinks: { discordUrl?: string; youtubeUrl?: string; websiteUrl?: string } = {};
|
||||
if (faker.datatype.boolean()) socialLinks.discordUrl = faker.internet.url();
|
||||
if (faker.datatype.boolean()) socialLinks.youtubeUrl = faker.internet.url();
|
||||
if (faker.datatype.boolean()) socialLinks.websiteUrl = faker.internet.url();
|
||||
const config = leagueConfigs[idx % leagueConfigs.length]!;
|
||||
|
||||
const leagueData: {
|
||||
id: string;
|
||||
@@ -39,15 +51,24 @@ export class RacingLeagueFactory {
|
||||
name: faker.company.name() + ' Racing League',
|
||||
description: faker.lorem.sentences(2),
|
||||
ownerId: owner.id.toString(),
|
||||
settings: {
|
||||
pointsSystem: faker.helpers.arrayElement(pointsSystems),
|
||||
maxDrivers: faker.number.int({ min: 20, max: 50 }),
|
||||
sessionDuration: faker.number.int({ min: 30, max: 180 }),
|
||||
qualifyingFormat: faker.helpers.arrayElement(qualifyingFormats),
|
||||
},
|
||||
settings: config,
|
||||
createdAt: faker.date.past({ years: 2, refDate: this.baseDate }),
|
||||
};
|
||||
|
||||
// Add social links with varying completeness
|
||||
const socialLinks: { discordUrl?: string; youtubeUrl?: string; websiteUrl?: string } = {};
|
||||
const socialLinkTypes = ['discord', 'youtube', 'website'] as const;
|
||||
|
||||
// Ensure some leagues have no social links, some have partial, some have all
|
||||
const numSocialLinks = idx % 4; // 0, 1, 2, or 3
|
||||
const selectedTypes = faker.helpers.arrayElements(socialLinkTypes, numSocialLinks);
|
||||
|
||||
selectedTypes.forEach(type => {
|
||||
if (type === 'discord') socialLinks.discordUrl = faker.internet.url();
|
||||
if (type === 'youtube') socialLinks.youtubeUrl = faker.internet.url();
|
||||
if (type === 'website') socialLinks.websiteUrl = faker.internet.url();
|
||||
});
|
||||
|
||||
if (Object.keys(socialLinks).length > 0) {
|
||||
leagueData.socialLinks = socialLinks;
|
||||
}
|
||||
|
||||
@@ -14,11 +14,41 @@ export class RacingRaceFactory {
|
||||
|
||||
const races: Race[] = [];
|
||||
|
||||
// Create races with systematic coverage of different statuses and scenarios
|
||||
const statuses: Array<'scheduled' | 'running' | 'completed' | 'cancelled'> = ['scheduled', 'running', 'completed', 'cancelled'];
|
||||
|
||||
for (let i = 1; i <= 50; i++) {
|
||||
const leagueId = leagueIds[(i - 1) % leagueIds.length] ?? demoLeagueId;
|
||||
const trackId = trackIds[(i - 1) % trackIds.length]!;
|
||||
const track = tracks.find(t => t.id === trackId)!;
|
||||
const scheduledAt = this.addDays(this.baseDate, i <= 10 ? -35 + i : 1 + (i - 10) * 2);
|
||||
|
||||
// Determine status systematically to ensure coverage
|
||||
let status: 'scheduled' | 'running' | 'completed' | 'cancelled';
|
||||
let scheduledAt: Date;
|
||||
|
||||
if (i <= 4) {
|
||||
// First 4 races: one of each status
|
||||
status = statuses[i - 1]!;
|
||||
scheduledAt = this.addDays(this.baseDate, i <= 2 ? -35 + i : 1 + (i - 2) * 2);
|
||||
} else if (i <= 10) {
|
||||
// Next 6: completed races
|
||||
status = 'completed';
|
||||
scheduledAt = this.addDays(this.baseDate, -35 + i);
|
||||
} else if (i <= 15) {
|
||||
// Next 5: scheduled future races
|
||||
status = 'scheduled';
|
||||
scheduledAt = this.addDays(this.baseDate, 1 + (i - 10) * 3);
|
||||
} else if (i <= 20) {
|
||||
// Next 5: cancelled races
|
||||
status = 'cancelled';
|
||||
scheduledAt = this.addDays(this.baseDate, -20 + (i - 15));
|
||||
} else {
|
||||
// Rest: mix of scheduled and completed
|
||||
status = i % 3 === 0 ? 'completed' : 'scheduled';
|
||||
scheduledAt = status === 'completed'
|
||||
? this.addDays(this.baseDate, -10 + (i - 20))
|
||||
: this.addDays(this.baseDate, 5 + (i - 20) * 2);
|
||||
}
|
||||
|
||||
const base = {
|
||||
id: `race-${i}`,
|
||||
@@ -29,34 +59,53 @@ export class RacingRaceFactory {
|
||||
car: cars[(i - 1) % cars.length]!,
|
||||
};
|
||||
|
||||
if (i === 1) {
|
||||
// Special case for running race
|
||||
if (status === 'running') {
|
||||
races.push(
|
||||
Race.create({
|
||||
...base,
|
||||
leagueId: demoLeagueId,
|
||||
scheduledAt: this.addMinutes(this.baseDate, -30),
|
||||
status: 'running',
|
||||
strengthOfField: 1530,
|
||||
registeredCount: 16,
|
||||
strengthOfField: 1400 + (i * 10), // Varying SOF
|
||||
registeredCount: 12 + (i % 5), // Varying registration counts
|
||||
}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (scheduledAt < this.baseDate) {
|
||||
// Add varying SOF and registration counts for completed races
|
||||
if (status === 'completed') {
|
||||
races.push(
|
||||
Race.create({
|
||||
...base,
|
||||
status: 'completed',
|
||||
strengthOfField: 1200 + (i * 15),
|
||||
registeredCount: 8 + (i % 8),
|
||||
}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Scheduled races with some having registration data
|
||||
if (status === 'scheduled') {
|
||||
const hasRegistrations = i % 4 !== 0; // 75% have registrations
|
||||
races.push(
|
||||
Race.create({
|
||||
...base,
|
||||
status: 'scheduled',
|
||||
...(hasRegistrations && {
|
||||
strengthOfField: 1300 + (i * 8),
|
||||
registeredCount: 5 + (i % 10),
|
||||
}),
|
||||
}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Cancelled races
|
||||
races.push(
|
||||
Race.create({
|
||||
...base,
|
||||
status: 'scheduled',
|
||||
status: 'cancelled',
|
||||
}),
|
||||
);
|
||||
}
|
||||
@@ -67,8 +116,4 @@ export class RacingRaceFactory {
|
||||
private addDays(date: Date, days: number): Date {
|
||||
return new Date(date.getTime() + days * 24 * 60 * 60 * 1000);
|
||||
}
|
||||
|
||||
private addMinutes(date: Date, minutes: number): Date {
|
||||
return new Date(date.getTime() + minutes * 60 * 1000);
|
||||
}
|
||||
}
|
||||
@@ -38,9 +38,35 @@ export class RacingTeamFactory {
|
||||
const memberships: TeamMembership[] = [];
|
||||
const usedDrivers = new Set<string>();
|
||||
|
||||
teams.forEach((team) => {
|
||||
teams.forEach((team, teamIndex) => {
|
||||
const availableDrivers = drivers.filter(d => !usedDrivers.has(d.id.toString()) && d.id.toString() !== team.ownerId.toString());
|
||||
const memberCount = faker.number.int({ min: 1, max: 8 });
|
||||
|
||||
// Create varied team compositions
|
||||
let memberCount: number;
|
||||
let hasManager: boolean;
|
||||
|
||||
if (teamIndex % 5 === 0) {
|
||||
// Solo teams (just owner)
|
||||
memberCount = 0;
|
||||
hasManager = false;
|
||||
} else if (teamIndex % 5 === 1) {
|
||||
// Small teams (2-3 members)
|
||||
memberCount = faker.number.int({ min: 1, max: 2 });
|
||||
hasManager = faker.datatype.boolean();
|
||||
} else if (teamIndex % 5 === 2) {
|
||||
// Medium teams (3-5 members)
|
||||
memberCount = faker.number.int({ min: 2, max: 4 });
|
||||
hasManager = true;
|
||||
} else if (teamIndex % 5 === 3) {
|
||||
// Large teams (5-7 members)
|
||||
memberCount = faker.number.int({ min: 4, max: 6 });
|
||||
hasManager = true;
|
||||
} else {
|
||||
// Mixed - sometimes with manager, sometimes without
|
||||
memberCount = faker.number.int({ min: 1, max: 5 });
|
||||
hasManager = faker.datatype.boolean();
|
||||
}
|
||||
|
||||
const members = faker.helpers.arrayElements(availableDrivers, memberCount);
|
||||
|
||||
// Add owner
|
||||
@@ -53,16 +79,32 @@ export class RacingTeamFactory {
|
||||
});
|
||||
usedDrivers.add(team.ownerId.toString());
|
||||
|
||||
// Add members
|
||||
members.forEach((driver) => {
|
||||
// Add manager if needed
|
||||
if (hasManager && members.length > 0) {
|
||||
const managerIndex = faker.number.int({ min: 0, max: members.length - 1 });
|
||||
const manager = members[managerIndex]!;
|
||||
memberships.push({
|
||||
teamId: team.id.toString(),
|
||||
driverId: driver.id.toString(),
|
||||
role: faker.helpers.arrayElement(['driver', 'manager']),
|
||||
driverId: manager.id.toString(),
|
||||
role: 'manager',
|
||||
status: 'active',
|
||||
joinedAt: faker.date.past({ years: 1, refDate: team.createdAt.toDate() }),
|
||||
});
|
||||
usedDrivers.add(driver.id.toString());
|
||||
usedDrivers.add(manager.id.toString());
|
||||
}
|
||||
|
||||
// Add remaining members as drivers
|
||||
members.forEach((driver) => {
|
||||
if (!usedDrivers.has(driver.id.toString())) {
|
||||
memberships.push({
|
||||
teamId: team.id.toString(),
|
||||
driverId: driver.id.toString(),
|
||||
role: 'driver',
|
||||
status: 'active',
|
||||
joinedAt: faker.date.past({ years: 1, refDate: team.createdAt.toDate() }),
|
||||
});
|
||||
usedDrivers.add(driver.id.toString());
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ import { Track } from '@core/racing/domain/entities/Track';
|
||||
export class RacingTrackFactory {
|
||||
create(): Track[] {
|
||||
return [
|
||||
// Road tracks - various difficulties
|
||||
Track.create({
|
||||
id: 'track-spa',
|
||||
name: 'Spa-Francorchamps',
|
||||
@@ -63,6 +64,67 @@ export class RacingTrackFactory {
|
||||
imageUrl: '/images/tracks/suzuka.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
Track.create({
|
||||
id: 'track-laguna',
|
||||
name: 'WeatherTech Raceway Laguna Seca',
|
||||
shortName: 'LAG',
|
||||
country: 'United States',
|
||||
category: 'road',
|
||||
difficulty: 'advanced',
|
||||
lengthKm: 3.602,
|
||||
turns: 11,
|
||||
imageUrl: '/images/tracks/laguna.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
Track.create({
|
||||
id: 'track-zandvoort',
|
||||
name: 'Circuit Zandvoort',
|
||||
shortName: 'ZAN',
|
||||
country: 'Netherlands',
|
||||
category: 'road',
|
||||
difficulty: 'intermediate',
|
||||
lengthKm: 4.259,
|
||||
turns: 14,
|
||||
imageUrl: '/images/tracks/zandvoort.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
Track.create({
|
||||
id: 'track-imola',
|
||||
name: 'Autodromo Enzo e Dino Ferrari',
|
||||
shortName: 'IMO',
|
||||
country: 'Italy',
|
||||
category: 'road',
|
||||
difficulty: 'advanced',
|
||||
lengthKm: 4.909,
|
||||
turns: 19,
|
||||
imageUrl: '/images/tracks/imola.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
Track.create({
|
||||
id: 'track-le-mans',
|
||||
name: 'Circuit de la Sarthe',
|
||||
shortName: 'LEM',
|
||||
country: 'France',
|
||||
category: 'road',
|
||||
difficulty: 'expert',
|
||||
lengthKm: 13.626,
|
||||
turns: 38,
|
||||
imageUrl: '/images/tracks/le-mans.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
Track.create({
|
||||
id: 'track-hockenheim',
|
||||
name: 'Hockenheimring',
|
||||
shortName: 'HOC',
|
||||
country: 'Germany',
|
||||
category: 'road',
|
||||
difficulty: 'intermediate',
|
||||
lengthKm: 4.574,
|
||||
turns: 17,
|
||||
imageUrl: '/images/tracks/hockenheim.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
// Oval tracks
|
||||
Track.create({
|
||||
id: 'track-daytona',
|
||||
name: 'Daytona International Speedway',
|
||||
@@ -76,15 +138,65 @@ export class RacingTrackFactory {
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
Track.create({
|
||||
id: 'track-laguna',
|
||||
name: 'WeatherTech Raceway Laguna Seca',
|
||||
shortName: 'LAG',
|
||||
id: 'track-indianapolis',
|
||||
name: 'Indianapolis Motor Speedway',
|
||||
shortName: 'IMS',
|
||||
country: 'United States',
|
||||
category: 'road',
|
||||
category: 'oval',
|
||||
difficulty: 'advanced',
|
||||
lengthKm: 3.602,
|
||||
turns: 11,
|
||||
imageUrl: '/images/tracks/laguna.jpg',
|
||||
lengthKm: 4.192,
|
||||
turns: 4,
|
||||
imageUrl: '/images/tracks/indianapolis.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
Track.create({
|
||||
id: 'track-talladega',
|
||||
name: 'Talladega Superspeedway',
|
||||
shortName: 'TAL',
|
||||
country: 'United States',
|
||||
category: 'oval',
|
||||
difficulty: 'beginner',
|
||||
lengthKm: 4.280,
|
||||
turns: 4,
|
||||
imageUrl: '/images/tracks/talladega.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
// Street tracks
|
||||
Track.create({
|
||||
id: 'track-miami',
|
||||
name: 'Miami Street Circuit',
|
||||
shortName: 'MIA',
|
||||
country: 'United States',
|
||||
category: 'street',
|
||||
difficulty: 'intermediate',
|
||||
lengthKm: 5.410,
|
||||
turns: 19,
|
||||
imageUrl: '/images/tracks/miami.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
Track.create({
|
||||
id: 'track-las-vegas',
|
||||
name: 'Las Vegas Street Circuit',
|
||||
shortName: 'VEG',
|
||||
country: 'United States',
|
||||
category: 'street',
|
||||
difficulty: 'advanced',
|
||||
lengthKm: 6.201,
|
||||
turns: 17,
|
||||
imageUrl: '/images/tracks/las-vegas.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
// Dirt tracks
|
||||
Track.create({
|
||||
id: 'track-eldo',
|
||||
name: 'Eldora Speedway',
|
||||
shortName: 'ELD',
|
||||
country: 'United States',
|
||||
category: 'dirt',
|
||||
difficulty: 'beginner',
|
||||
lengthKm: 0.805,
|
||||
turns: 4,
|
||||
imageUrl: '/images/tracks/eldora.jpg',
|
||||
gameId: 'iracing',
|
||||
}),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user