more seeds
This commit is contained in:
248
adapters/bootstrap/racing/RacingSeasonSponsorshipFactory.ts
Normal file
248
adapters/bootstrap/racing/RacingSeasonSponsorshipFactory.ts
Normal file
@@ -0,0 +1,248 @@
|
||||
import { faker } from '@faker-js/faker';
|
||||
import type { League } from '@core/racing/domain/entities/League';
|
||||
import { SponsorshipRequest } from '@core/racing/domain/entities/SponsorshipRequest';
|
||||
import { Season } from '@core/racing/domain/entities/season/Season';
|
||||
import { SeasonSponsorship } from '@core/racing/domain/entities/season/SeasonSponsorship';
|
||||
import type { Sponsor } from '@core/racing/domain/entities/sponsor/Sponsor';
|
||||
import { Money } from '@core/racing/domain/value-objects/Money';
|
||||
|
||||
export class RacingSeasonSponsorshipFactory {
|
||||
constructor(private readonly baseDate: Date) {}
|
||||
|
||||
createSeasons(leagues: League[]): Season[] {
|
||||
const seasons: Season[] = [];
|
||||
|
||||
for (const league of leagues) {
|
||||
const leagueId = league.id.toString();
|
||||
|
||||
if (leagueId === 'league-5') {
|
||||
seasons.push(
|
||||
Season.create({
|
||||
id: 'season-1',
|
||||
leagueId,
|
||||
gameId: 'iracing',
|
||||
name: 'Season 1 (GT Sprint)',
|
||||
year: 2025,
|
||||
order: 1,
|
||||
status: 'active',
|
||||
startDate: this.daysFromBase(-30),
|
||||
}),
|
||||
Season.create({
|
||||
id: 'season-2',
|
||||
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: 'season-3',
|
||||
leagueId,
|
||||
gameId: 'iracing',
|
||||
name: 'Season 3 (Planned)',
|
||||
year: 2025,
|
||||
order: 2,
|
||||
status: 'planned',
|
||||
startDate: this.daysFromBase(14),
|
||||
}),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (leagueId === 'league-3') {
|
||||
seasons.push(
|
||||
Season.create({
|
||||
id: 'league-3-season-a',
|
||||
leagueId,
|
||||
gameId: 'iracing',
|
||||
name: 'Split Season A',
|
||||
year: 2025,
|
||||
order: 1,
|
||||
status: 'active',
|
||||
startDate: this.daysFromBase(-10),
|
||||
}),
|
||||
Season.create({
|
||||
id: 'league-3-season-b',
|
||||
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 === 'league-2' ? 1 : faker.number.int({ min: 1, max: 3 });
|
||||
|
||||
for (let i = 0; i < seasonCount; i++) {
|
||||
const id = `${leagueId}-season-${i + 1}`;
|
||||
const isFirst = i === 0;
|
||||
|
||||
const status: Season['status'] =
|
||||
leagueId === 'league-1' && isFirst
|
||||
? 'active'
|
||||
: leagueId === 'league-2'
|
||||
? 'planned'
|
||||
: isFirst
|
||||
? faker.helpers.arrayElement(['active', 'planned'] as const)
|
||||
: faker.helpers.arrayElement(['completed', 'archived', 'cancelled'] as const);
|
||||
|
||||
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 });
|
||||
|
||||
const endOffset =
|
||||
status === 'completed' || status === 'archived' || status === 'cancelled'
|
||||
? faker.number.int({ min: -89, max: -7 })
|
||||
: undefined;
|
||||
|
||||
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) } : {}),
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return seasons;
|
||||
}
|
||||
|
||||
createSeasonSponsorships(seasons: Season[], sponsors: Sponsor[]): SeasonSponsorship[] {
|
||||
const sponsorships: SeasonSponsorship[] = [];
|
||||
const sponsorIds = sponsors.map((s) => s.id.toString());
|
||||
|
||||
for (const season of seasons) {
|
||||
const sponsorshipCount =
|
||||
season.id === 'season-1'
|
||||
? 2
|
||||
: season.status === 'active'
|
||||
? faker.number.int({ min: 0, max: 2 })
|
||||
: faker.number.int({ min: 0, max: 1 });
|
||||
|
||||
const usedSponsorIds = new Set<string>();
|
||||
|
||||
for (let i = 0; i < sponsorshipCount; i++) {
|
||||
const tier: SeasonSponsorship['tier'] =
|
||||
i === 0 ? 'main' : faker.helpers.arrayElement(['secondary', 'secondary', 'main'] as const);
|
||||
|
||||
const sponsorIdCandidate = faker.helpers.arrayElement(sponsorIds);
|
||||
const sponsorId = usedSponsorIds.has(sponsorIdCandidate)
|
||||
? faker.helpers.arrayElement(sponsorIds)
|
||||
: sponsorIdCandidate;
|
||||
|
||||
usedSponsorIds.add(sponsorId);
|
||||
|
||||
const base = SeasonSponsorship.create({
|
||||
id: `season-sponsorship-${season.id}-${i + 1}`,
|
||||
seasonId: season.id,
|
||||
leagueId: season.leagueId,
|
||||
sponsorId,
|
||||
tier,
|
||||
pricing: Money.create(
|
||||
tier === 'main' ? faker.number.int({ min: 900, max: 2500 }) : faker.number.int({ min: 250, max: 900 }),
|
||||
'USD',
|
||||
),
|
||||
createdAt: faker.date.recent({ days: 120, refDate: this.baseDate }),
|
||||
description: tier === 'main' ? 'Main sponsor slot' : 'Secondary sponsor slot',
|
||||
...(season.status === 'active'
|
||||
? {
|
||||
status: faker.helpers.arrayElement(['active', 'pending'] as const),
|
||||
activatedAt: faker.date.recent({ days: 30, refDate: this.baseDate }),
|
||||
}
|
||||
: season.status === 'completed' || season.status === 'archived'
|
||||
? {
|
||||
status: faker.helpers.arrayElement(['ended', 'cancelled'] as const),
|
||||
endedAt: faker.date.recent({ days: 200, refDate: this.baseDate }),
|
||||
}
|
||||
: {
|
||||
status: faker.helpers.arrayElement(['pending', 'cancelled'] as const),
|
||||
}),
|
||||
});
|
||||
|
||||
sponsorships.push(base);
|
||||
}
|
||||
}
|
||||
|
||||
return sponsorships;
|
||||
}
|
||||
|
||||
createSponsorshipRequests(seasons: Season[], sponsors: Sponsor[]): SponsorshipRequest[] {
|
||||
const requests: SponsorshipRequest[] = [];
|
||||
const sponsorIds = sponsors.map((s) => s.id.toString());
|
||||
|
||||
for (const season of seasons) {
|
||||
const isHighTrafficDemo = season.id === 'season-1';
|
||||
const maxRequests =
|
||||
isHighTrafficDemo ? 8 : season.status === 'active' ? faker.number.int({ min: 0, max: 4 }) : faker.number.int({ min: 0, max: 1 });
|
||||
|
||||
for (let i = 0; i < maxRequests; i++) {
|
||||
const tier: SponsorshipRequest['tier'] =
|
||||
i === 0 ? 'main' : faker.helpers.arrayElement(['secondary', 'secondary', 'main'] as const);
|
||||
|
||||
const sponsorId =
|
||||
isHighTrafficDemo && i === 0
|
||||
? 'demo-sponsor-1'
|
||||
: faker.helpers.arrayElement(sponsorIds);
|
||||
|
||||
const offeredAmount = Money.create(
|
||||
tier === 'main' ? faker.number.int({ min: 1000, max: 3500 }) : faker.number.int({ min: 200, max: 1200 }),
|
||||
'USD',
|
||||
);
|
||||
|
||||
const includeMessage = i % 3 !== 0;
|
||||
const message = includeMessage
|
||||
? faker.helpers.arrayElement([
|
||||
'We would love to sponsor this season — high-quality sim racing content fits our brand.',
|
||||
'We can provide prize pool support + gear giveaways for podium finishers.',
|
||||
'Interested in the main slot: branding on liveries + broadcast overlays.',
|
||||
'We want a secondary slot to test engagement before a bigger commitment.',
|
||||
])
|
||||
: undefined;
|
||||
|
||||
// A mix of statuses for edge cases (pending is what the UI lists)
|
||||
const status =
|
||||
season.status === 'active'
|
||||
? faker.helpers.arrayElement(['pending', 'pending', 'pending', 'rejected', 'withdrawn'] as const)
|
||||
: faker.helpers.arrayElement(['pending', 'rejected'] as const);
|
||||
|
||||
requests.push(
|
||||
SponsorshipRequest.create({
|
||||
id: `sponsorship-request-${season.id}-${i + 1}`,
|
||||
sponsorId,
|
||||
entityType: 'season',
|
||||
entityId: season.id,
|
||||
tier,
|
||||
offeredAmount,
|
||||
...(message !== undefined ? { message } : {}),
|
||||
status,
|
||||
createdAt: faker.date.recent({ days: 60, refDate: this.baseDate }),
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return requests;
|
||||
}
|
||||
|
||||
private daysFromBase(days: number): Date {
|
||||
return new Date(this.baseDate.getTime() + days * 24 * 60 * 60 * 1000);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user