import { League } from '@core/racing/domain/entities/League'; import { Driver } from '@core/racing/domain/entities/Driver'; import { faker } from '@faker-js/faker'; import { seedId } from './SeedIdHelper'; export class RacingLeagueFactory { constructor( private readonly baseDate: Date, private readonly drivers: Driver[], private readonly persistence: 'postgres' | 'inmemory' = 'inmemory', ) {} create(): League[] { const leagueCount = 20; // 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 config = leagueConfigs[idx % leagueConfigs.length]!; const createdAt = // Ensure some "New" leagues (created within 7 days) so `/leagues` featured categories are populated. idx % 6 === 0 ? faker.date.recent({ days: 6, refDate: this.baseDate }) : faker.date.past({ years: 2, refDate: this.baseDate }); const leagueData: { id: string; name: string; description: string; ownerId: string; settings: { pointsSystem: 'f1-2024' | 'indycar' | 'custom'; maxDrivers: number; sessionDuration: number; qualifyingFormat: 'open' | 'single-lap'; }; createdAt: Date; socialLinks?: { discordUrl?: string; youtubeUrl?: string; websiteUrl?: string }; participantCount?: number; } = { id: seedId(`league-${i}`, this.persistence), name: faker.company.name() + ' Racing League', description: faker.lorem.sentences(2), ownerId: owner.id.toString(), settings: config, createdAt, // Start with some participants for ranked leagues to meet minimum requirements // Note: ranked leagues require >= 10 participants (see LeagueVisibility) participantCount: i % 3 === 0 ? 12 : 0, }; // 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; } return League.create(leagueData); }); } }