seed data

This commit is contained in:
2025-12-30 00:15:35 +01:00
parent 7a853d4e43
commit ccaa39c39c
22 changed files with 1342 additions and 173 deletions

View File

@@ -19,111 +19,143 @@ export class RacingSeasonSponsorshipFactory {
for (const league of leagues) {
const leagueId = league.id.toString();
const leagueIndex = parseInt(leagueId.split('-')[1] || '0');
if (leagueId === seedId('league-5', this.persistence)) {
seasons.push(
Season.create({
id: seedId('season-1', this.persistence),
leagueId,
gameId: 'iracing',
name: 'Season 1 (GT Sprint)',
year: 2025,
order: 1,
status: 'active',
startDate: this.daysFromBase(-30),
}),
Season.create({
id: seedId('season-2', this.persistence),
leagueId,
gameId: 'iracing',
name: 'Season 2 (Endurance Cup)',
year: 2024,
order: 0,
status: 'completed',
startDate: this.daysFromBase(-120),
endDate: this.daysFromBase(-60),
}),
Season.create({
id: seedId('season-3', this.persistence),
leagueId,
gameId: 'iracing',
name: 'Season 3 (Planned)',
year: 2025,
order: 2,
status: 'planned',
startDate: this.daysFromBase(14),
}),
);
continue;
}
if (leagueId === seedId('league-3', this.persistence)) {
seasons.push(
Season.create({
id: seedId('league-3-season-a', this.persistence),
leagueId,
gameId: 'iracing',
name: 'Split Season A',
year: 2025,
order: 1,
status: 'active',
startDate: this.daysFromBase(-10),
}),
Season.create({
id: seedId('league-3-season-b', this.persistence),
leagueId,
gameId: 'iracing',
name: 'Split Season B',
year: 2025,
order: 2,
status: 'active',
startDate: this.daysFromBase(-3),
}),
);
continue;
}
const baseYear = this.baseDate.getUTCFullYear();
const seasonCount = leagueId === seedId('league-2', this.persistence) ? 1 : faker.number.int({ min: 1, max: 3 });
// Create 2-4 seasons per league to reach ~100 total seasons
const seasonCount = faker.number.int({ min: 2, max: 4 });
for (let i = 0; i < seasonCount; i++) {
const id = seedId(`${leagueId}-season-${i + 1}`, this.persistence);
const isFirst = i === 0;
// Systematically cover all 5 statuses across all leagues
// planned: 20%, active: 20%, completed: 30%, archived: 20%, cancelled: 10%
let status: SeasonStatusValue;
if (i === 0 && leagueIndex % 5 === 0) {
status = 'planned';
} else if (i === 0 && leagueIndex % 5 === 1) {
status = 'active';
} else if (i === 1 && leagueIndex % 5 === 2) {
status = 'completed';
} else if (i === 2 && leagueIndex % 5 === 3) {
status = 'archived';
} else if (i === 3 && leagueIndex % 5 === 4) {
status = 'cancelled';
} else {
// Weighted random distribution
const statusWeights = [
{ weight: 2, value: 'planned' as const },
{ weight: 2, value: 'active' as const },
{ weight: 3, value: 'completed' as const },
{ weight: 2, value: 'archived' as const },
{ weight: 1, value: 'cancelled' as const },
];
const totalWeight = statusWeights.reduce((sum, item) => sum + item.weight, 0);
const random = faker.number.int({ min: 1, max: totalWeight });
let cumulative = 0;
status = 'planned';
for (const item of statusWeights) {
cumulative += item.weight;
if (random <= cumulative) {
status = item.value;
break;
}
}
}
const status: SeasonStatusValue =
leagueId === seedId('league-1', this.persistence) && isFirst
? 'active'
: leagueId === seedId('league-2', this.persistence)
? 'planned'
: isFirst
? faker.helpers.arrayElement(['active', 'planned'] as const)
: faker.helpers.arrayElement(['completed', 'archived', 'cancelled'] as const);
const baseYear = this.baseDate.getUTCFullYear() + faker.number.int({ min: -1, max: 1 });
const startOffset =
status === 'active'
? faker.number.int({ min: -60, max: -1 })
: status === 'planned'
? faker.number.int({ min: 7, max: 60 })
: faker.number.int({ min: -200, max: -90 });
// Calculate dates based on status
let startDate: Date | undefined;
let endDate: Date | undefined;
let schedulePublished: boolean | undefined;
let participantCount: number | undefined;
let maxDrivers: number | undefined;
const endOffset =
status === 'completed' || status === 'archived' || status === 'cancelled'
? faker.number.int({ min: -89, max: -7 })
: undefined;
switch (status) {
case 'planned':
startDate = this.daysFromBase(faker.number.int({ min: 7, max: 90 }));
schedulePublished = faker.datatype.boolean({ probability: 0.6 });
participantCount = 0;
break;
seasons.push(
Season.create({
id,
leagueId,
gameId: 'iracing',
name: `${faker.word.adjective()} ${faker.word.noun()} Season`,
year: baseYear + faker.number.int({ min: -1, max: 1 }),
order: i + 1,
status,
startDate: this.daysFromBase(startOffset),
...(endOffset !== undefined ? { endDate: this.daysFromBase(endOffset) } : {}),
}),
);
case 'active':
startDate = this.daysFromBase(faker.number.int({ min: -60, max: -1 }));
schedulePublished = true;
maxDrivers = faker.number.int({
min: 10,
max: Math.max(10, Math.min(league.settings.maxDrivers || 32, 100))
});
participantCount = faker.number.int({ min: 5, max: maxDrivers });
break;
case 'completed':
startDate = this.daysFromBase(faker.number.int({ min: -180, max: -60 }));
endDate = this.daysFromBase(faker.number.int({ min: -59, max: -7 }));
schedulePublished = true;
maxDrivers = faker.number.int({
min: 10,
max: Math.max(10, Math.min(league.settings.maxDrivers || 32, 100))
});
participantCount = faker.number.int({ min: 10, max: maxDrivers });
break;
case 'archived':
startDate = this.daysFromBase(faker.number.int({ min: -365, max: -200 }));
endDate = this.daysFromBase(faker.number.int({ min: -199, max: -150 }));
schedulePublished = true;
maxDrivers = faker.number.int({
min: 10,
max: Math.max(10, Math.min(league.settings.maxDrivers || 32, 100))
});
participantCount = faker.number.int({ min: 8, max: maxDrivers });
break;
case 'cancelled':
startDate = this.daysFromBase(faker.number.int({ min: -30, max: -1 }));
endDate = this.daysFromBase(faker.number.int({ min: -1, max: 1 })); // Cancelled early
schedulePublished = faker.datatype.boolean({ probability: 0.3 });
// Cancelled seasons can have maxDrivers but participantCount should be low
maxDrivers = faker.number.int({
min: 5,
max: Math.max(5, Math.min(league.settings.maxDrivers || 32, 100))
});
participantCount = faker.number.int({ min: 0, max: Math.min(5, maxDrivers) }); // Minimal participants
break;
}
// Build season data with proper undefined handling
const seasonData: {
id: string;
leagueId: string;
gameId: string;
name: string;
year?: number;
order?: number;
status: SeasonStatusValue;
startDate?: Date;
endDate?: Date;
schedulePublished?: boolean;
participantCount?: number;
maxDrivers?: number;
} = {
id,
leagueId,
gameId: 'iracing',
name: `${faker.word.adjective()} ${faker.word.noun()} Season`,
status,
};
// Add optional fields only if they have values
if (baseYear !== undefined) seasonData.year = baseYear;
if (i + 1 !== undefined) seasonData.order = i + 1;
if (startDate !== undefined) seasonData.startDate = startDate;
if (endDate !== undefined) seasonData.endDate = endDate;
if (schedulePublished !== undefined) seasonData.schedulePublished = schedulePublished;
if (participantCount !== undefined) seasonData.participantCount = participantCount;
if (maxDrivers !== undefined) seasonData.maxDrivers = maxDrivers;
const season = Season.create(seasonData);
seasons.push(season);
}
}