wip league admin tools

This commit is contained in:
2025-12-28 12:04:12 +01:00
parent 5dc8c2399c
commit 6edf12fda8
401 changed files with 15365 additions and 6047 deletions

View File

@@ -95,7 +95,7 @@ export class SeedRacingData {
}
}
const activeSeasons = seed.seasons.filter((season) => season.status === 'active');
const activeSeasons = seed.seasons.filter((season) => season.status.isActive());
for (const season of activeSeasons) {
const presetId = this.selectScoringPresetIdForSeason(season);
const preset = getLeagueScoringPresetById(presetId);
@@ -270,7 +270,7 @@ export class SeedRacingData {
for (const league of leagues) {
const seasons = await this.seedDeps.seasonRepository.findByLeagueId(league.id.toString());
const activeSeasons = seasons.filter((season) => season.status === 'active');
const activeSeasons = seasons.filter((season) => season.status.isActive());
for (const season of activeSeasons) {
const existing = await this.seedDeps.leagueScoringConfigRepository.findBySeasonId(season.id);
@@ -298,7 +298,7 @@ export class SeedRacingData {
}
private selectScoringPresetIdForSeason(season: Season): string {
if (season.leagueId === 'league-5' && season.status === 'active') {
if (season.leagueId === 'league-5' && season.status.isActive()) {
return 'sprint-main-driver';
}

View File

@@ -11,8 +11,8 @@ export class RacingFeedFactory {
const items: FeedItem[] = [];
const friendMap = new Map(friendships.map((f) => [`${f.driverId}:${f.friendId}`, true] as const));
const completedRace = races.find((r) => r.status === 'completed');
const upcomingRace = races.find((r) => r.status === 'scheduled');
const completedRace = races.find((r) => r.status.toString() === 'completed');
const upcomingRace = races.find((r) => r.status.toString() === 'scheduled');
const league = leagues.find((l) => l.id.toString() === 'league-5') ?? leagues[0]!;
const now = this.addMinutes(this.baseDate, 10);

View File

@@ -61,7 +61,8 @@ export class RacingLeagueFactory {
settings: config,
createdAt,
// Start with some participants for ranked leagues to meet minimum requirements
participantCount: i % 3 === 0 ? 12 : i % 3 === 1 ? 8 : 0,
// Note: ranked leagues require >= 10 participants (see LeagueVisibility)
participantCount: i % 3 === 0 ? 12 : 0,
};
// Add social links with varying completeness

View File

@@ -249,7 +249,7 @@ export class RacingMembershipFactory {
.map(m => `${m.leagueId.toString()}:${m.driverId.toString()}`),
);
const scheduled = races.filter((r) => r.status === 'scheduled');
const scheduled = races.filter((r) => r.status.toString() === 'scheduled');
for (const race of scheduled) {
const leagueId = race.leagueId.toString();
@@ -311,7 +311,7 @@ export class RacingMembershipFactory {
}
// Keep a tiny curated "happy path" for the demo league as well
const upcomingDemoLeague = races.filter((r) => r.status === 'scheduled' && r.leagueId === 'league-5').slice(0, 3);
const upcomingDemoLeague = races.filter((r) => r.status.toString() === 'scheduled' && r.leagueId === 'league-5').slice(0, 3);
for (const race of upcomingDemoLeague) {
registrations.push(
RaceRegistration.create({

View File

@@ -5,7 +5,7 @@ import { Result as RaceResult } from '@core/racing/domain/entities/result/Result
export class RacingResultFactory {
create(drivers: Driver[], races: Race[]): RaceResult[] {
const results: RaceResult[] = [];
const completed = races.filter((r) => r.status === 'completed');
const completed = races.filter((r) => r.status.toString() === 'completed');
for (const race of completed) {
if (drivers.length === 0) continue;

View File

@@ -4,6 +4,7 @@ import { SponsorshipRequest } from '@core/racing/domain/entities/SponsorshipRequ
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 type { SeasonStatusValue } from '@core/racing/domain/value-objects/SeasonStatus';
import { Money } from '@core/racing/domain/value-objects/Money';
export class RacingSeasonSponsorshipFactory {
@@ -85,7 +86,7 @@ export class RacingSeasonSponsorshipFactory {
const id = `${leagueId}-season-${i + 1}`;
const isFirst = i === 0;
const status: Season['status'] =
const status: SeasonStatusValue =
leagueId === 'league-1' && isFirst
? 'active'
: leagueId === 'league-2'
@@ -133,7 +134,7 @@ export class RacingSeasonSponsorshipFactory {
const sponsorshipCount =
season.id === 'season-1'
? 2
: season.status === 'active'
: season.status.isActive()
? faker.number.int({ min: 0, max: 2 })
: faker.number.int({ min: 0, max: 1 });
@@ -162,12 +163,12 @@ export class RacingSeasonSponsorshipFactory {
),
createdAt: faker.date.recent({ days: 120, refDate: this.baseDate }),
description: tier === 'main' ? 'Main sponsor slot' : 'Secondary sponsor slot',
...(season.status === 'active'
...(season.status.isActive()
? {
status: faker.helpers.arrayElement(['active', 'pending'] as const),
activatedAt: faker.date.recent({ days: 30, refDate: this.baseDate }),
}
: season.status === 'completed' || season.status === 'archived'
: season.status.isCompleted() || season.status.isArchived()
? {
status: faker.helpers.arrayElement(['ended', 'cancelled'] as const),
endedAt: faker.date.recent({ days: 200, refDate: this.baseDate }),
@@ -191,7 +192,11 @@ export class RacingSeasonSponsorshipFactory {
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 });
isHighTrafficDemo
? 8
: season.status.isActive()
? 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'] =
@@ -219,7 +224,7 @@ export class RacingSeasonSponsorshipFactory {
// A mix of statuses for edge cases (pending is what the UI lists)
const status =
season.status === 'active'
season.status.isActive()
? faker.helpers.arrayElement(['pending', 'pending', 'pending', 'rejected', 'withdrawn'] as const)
: faker.helpers.arrayElement(['pending', 'rejected'] as const);

View File

@@ -10,7 +10,7 @@ export class RacingStandingFactory {
const racesByLeague = new Map<string, Set<string>>();
for (const race of races) {
if (race.status !== 'completed') continue;
if (!race.status.isCompleted()) continue;
const set = racesByLeague.get(race.leagueId) ?? new Set<string>();
set.add(race.id);