This commit is contained in:
2025-12-10 12:38:55 +01:00
parent 0f7fe67d3c
commit fbbcf414a4
87 changed files with 11972 additions and 390 deletions

View File

@@ -7,6 +7,9 @@ import { Penalty } from '@gridpilot/racing/domain/entities/Penalty';
import { Protest } from '@gridpilot/racing/domain/entities/Protest';
import { Game } from '@gridpilot/racing/domain/entities/Game';
import { Season } from '@gridpilot/racing/domain/entities/Season';
import { Sponsor } from '@gridpilot/racing/domain/entities/Sponsor';
import { SeasonSponsorship } from '@gridpilot/racing/domain/entities/SeasonSponsorship';
import { Money } from '@gridpilot/racing/domain/value-objects/Money';
import type { LeagueMembership, JoinRequest } from '@gridpilot/racing/domain/entities/LeagueMembership';
import type { IDriverRepository } from '@gridpilot/racing/domain/repositories/IDriverRepository';
@@ -25,6 +28,10 @@ import type {
ITeamRepository,
ITeamMembershipRepository,
IRaceRegistrationRepository,
ISponsorRepository,
ISeasonSponsorshipRepository,
ISponsorshipRequestRepository,
ISponsorshipPricingRepository,
} from '@gridpilot/racing';
import type { ILeagueMembershipRepository } from '@gridpilot/racing/domain/repositories/ILeagueMembershipRepository';
import type { IFeedRepository } from '@gridpilot/social/domain/repositories/IFeedRepository';
@@ -62,6 +69,10 @@ import {
getLeagueScoringPresetById,
} from '@gridpilot/racing/infrastructure/repositories/InMemoryScoringRepositories';
import { InMemoryLeagueScoringPresetProvider } from '@gridpilot/racing/infrastructure/repositories/InMemoryLeagueScoringPresetProvider';
import { InMemorySponsorRepository } from '@gridpilot/racing/infrastructure/repositories/InMemorySponsorRepository';
import { InMemorySeasonSponsorshipRepository } from '@gridpilot/racing/infrastructure/repositories/InMemorySeasonSponsorshipRepository';
import { InMemorySponsorshipRequestRepository } from '@gridpilot/racing/infrastructure/repositories/InMemorySponsorshipRequestRepository';
import { InMemorySponsorshipPricingRepository } from '@gridpilot/racing/infrastructure/repositories/InMemorySponsorshipPricingRepository';
import { InMemoryTeamRepository } from '@gridpilot/racing/infrastructure/repositories/InMemoryTeamRepository';
import { InMemoryTeamMembershipRepository } from '@gridpilot/racing/infrastructure/repositories/InMemoryTeamMembershipRepository';
import { InMemoryRaceRegistrationRepository } from '@gridpilot/racing/infrastructure/repositories/InMemoryRaceRegistrationRepository';
@@ -107,6 +118,13 @@ import {
GetRacePenaltiesQuery,
RequestProtestDefenseUseCase,
SubmitProtestDefenseUseCase,
GetSponsorDashboardQuery,
GetSponsorSponsorshipsQuery,
GetPendingSponsorshipRequestsQuery,
GetEntitySponsorshipPricingQuery,
ApplyForSponsorshipUseCase,
AcceptSponsorshipRequestUseCase,
RejectSponsorshipRequestUseCase,
} from '@gridpilot/racing/application';
import { TransferLeagueOwnershipUseCase } from '@gridpilot/racing/application/use-cases/TransferLeagueOwnershipUseCase';
import type { DriverRatingProvider } from '@gridpilot/racing/application';
@@ -571,6 +589,74 @@ export function configureDIContainer(): void {
new InMemoryCarRepository(DEMO_CARS)
);
// Sponsor repositories - seed with demo sponsors
const seededSponsors = seedData.sponsors.map(s =>
Sponsor.create({
id: s.id,
name: s.name,
contactEmail: s.contactEmail,
logoUrl: s.logoUrl,
websiteUrl: s.websiteUrl,
})
);
const sponsorRepo = new InMemorySponsorRepository();
// Use synchronous seeding via internal method
seededSponsors.forEach(sponsor => {
(sponsorRepo as any).sponsors.set(sponsor.id, sponsor);
});
container.registerInstance<ISponsorRepository>(
DI_TOKENS.SponsorRepository,
sponsorRepo
);
const seededSponsorships = seedData.seasonSponsorships.map(ss =>
SeasonSponsorship.create({
id: ss.id,
seasonId: ss.seasonId,
sponsorId: ss.sponsorId,
tier: ss.tier,
pricing: Money.create(ss.pricingAmount, ss.pricingCurrency),
status: ss.status,
description: ss.description,
})
);
const seasonSponsorshipRepo = new InMemorySeasonSponsorshipRepository();
// Use synchronous seeding via internal method
seededSponsorships.forEach(sponsorship => {
(seasonSponsorshipRepo as any).sponsorships.set(sponsorship.id, sponsorship);
});
container.registerInstance<ISeasonSponsorshipRepository>(
DI_TOKENS.SeasonSponsorshipRepository,
seasonSponsorshipRepo
);
// Sponsorship Request and Pricing repositories
const sponsorshipRequestRepo = new InMemorySponsorshipRequestRepository();
container.registerInstance<ISponsorshipRequestRepository>(
DI_TOKENS.SponsorshipRequestRepository,
sponsorshipRequestRepo
);
const sponsorshipPricingRepo = new InMemorySponsorshipPricingRepository();
// Seed sponsorship pricings from demo data
seedData.sponsorshipPricings?.forEach(pricing => {
(sponsorshipPricingRepo as any).pricings.set(
`${pricing.entityType}-${pricing.entityId}`,
pricing
);
});
container.registerInstance<ISponsorshipPricingRepository>(
DI_TOKENS.SponsorshipPricingRepository,
sponsorshipPricingRepo
);
// Seed sponsorship requests from demo data
seedData.sponsorshipRequests?.forEach(request => {
(sponsorshipRequestRepo as any).requests.set(request.id, request);
});
// Social repositories
container.registerInstance<IFeedRepository>(
DI_TOKENS.FeedRepository,
@@ -908,6 +994,74 @@ export function configureDIContainer(): void {
DI_TOKENS.GetUnreadNotificationsQuery,
new GetUnreadNotificationsQuery(notificationRepository)
);
// Register queries - Sponsors
const sponsorRepository = container.resolve<ISponsorRepository>(DI_TOKENS.SponsorRepository);
const seasonSponsorshipRepository = container.resolve<ISeasonSponsorshipRepository>(DI_TOKENS.SeasonSponsorshipRepository);
container.registerInstance(
DI_TOKENS.GetSponsorDashboardQuery,
new GetSponsorDashboardQuery(
sponsorRepository,
seasonSponsorshipRepository,
seasonRepository,
leagueRepository,
leagueMembershipRepository,
raceRepository
)
);
container.registerInstance(
DI_TOKENS.GetSponsorSponsorshipsQuery,
new GetSponsorSponsorshipsQuery(
sponsorRepository,
seasonSponsorshipRepository,
seasonRepository,
leagueRepository,
leagueMembershipRepository,
raceRepository
)
);
// Sponsorship request repositories and use cases
const sponsorshipRequestRepository = container.resolve<ISponsorshipRequestRepository>(DI_TOKENS.SponsorshipRequestRepository);
const sponsorshipPricingRepository = container.resolve<ISponsorshipPricingRepository>(DI_TOKENS.SponsorshipPricingRepository);
container.registerInstance(
DI_TOKENS.GetPendingSponsorshipRequestsQuery,
new GetPendingSponsorshipRequestsQuery(
sponsorshipRequestRepository,
sponsorRepository
)
);
container.registerInstance(
DI_TOKENS.GetEntitySponsorshipPricingQuery,
new GetEntitySponsorshipPricingQuery(
sponsorshipPricingRepository,
sponsorshipRequestRepository,
seasonSponsorshipRepository
)
);
container.registerInstance(
DI_TOKENS.ApplyForSponsorshipUseCase,
new ApplyForSponsorshipUseCase(
sponsorshipRequestRepository,
sponsorshipPricingRepository,
sponsorRepository
)
);
container.registerInstance(
DI_TOKENS.AcceptSponsorshipRequestUseCase,
new AcceptSponsorshipRequestUseCase(sponsorshipRequestRepository, seasonSponsorshipRepository)
);
container.registerInstance(
DI_TOKENS.RejectSponsorshipRequestUseCase,
new RejectSponsorshipRequestUseCase(sponsorshipRequestRepository)
);
}
/**

View File

@@ -71,7 +71,18 @@ import type {
GetRacePenaltiesQuery,
RequestProtestDefenseUseCase,
SubmitProtestDefenseUseCase,
GetSponsorDashboardQuery,
GetSponsorSponsorshipsQuery,
ApplyForSponsorshipUseCase,
AcceptSponsorshipRequestUseCase,
RejectSponsorshipRequestUseCase,
GetPendingSponsorshipRequestsQuery,
GetEntitySponsorshipPricingQuery,
} from '@gridpilot/racing/application';
import type { ISponsorRepository } from '@gridpilot/racing/domain/repositories/ISponsorRepository';
import type { ISeasonSponsorshipRepository } from '@gridpilot/racing/domain/repositories/ISeasonSponsorshipRepository';
import type { ISponsorshipRequestRepository } from '@gridpilot/racing/domain/repositories/ISponsorshipRequestRepository';
import type { ISponsorshipPricingRepository } from '@gridpilot/racing/domain/repositories/ISponsorshipPricingRepository';
import type { TransferLeagueOwnershipUseCase } from '@gridpilot/racing/application/use-cases/TransferLeagueOwnershipUseCase';
import type { DriverRatingProvider } from '@gridpilot/racing/application';
import type { PreviewLeagueScheduleQuery } from '@gridpilot/racing/application';
@@ -424,6 +435,61 @@ class DIContainer {
this.ensureInitialized();
return getDIContainer().resolve<TransferLeagueOwnershipUseCase>(DI_TOKENS.TransferLeagueOwnershipUseCase);
}
get sponsorRepository(): ISponsorRepository {
this.ensureInitialized();
return getDIContainer().resolve<ISponsorRepository>(DI_TOKENS.SponsorRepository);
}
get seasonSponsorshipRepository(): ISeasonSponsorshipRepository {
this.ensureInitialized();
return getDIContainer().resolve<ISeasonSponsorshipRepository>(DI_TOKENS.SeasonSponsorshipRepository);
}
get getSponsorDashboardQuery(): GetSponsorDashboardQuery {
this.ensureInitialized();
return getDIContainer().resolve<GetSponsorDashboardQuery>(DI_TOKENS.GetSponsorDashboardQuery);
}
get getSponsorSponsorshipsQuery(): GetSponsorSponsorshipsQuery {
this.ensureInitialized();
return getDIContainer().resolve<GetSponsorSponsorshipsQuery>(DI_TOKENS.GetSponsorSponsorshipsQuery);
}
get sponsorshipRequestRepository(): ISponsorshipRequestRepository {
this.ensureInitialized();
return getDIContainer().resolve<ISponsorshipRequestRepository>(DI_TOKENS.SponsorshipRequestRepository);
}
get sponsorshipPricingRepository(): ISponsorshipPricingRepository {
this.ensureInitialized();
return getDIContainer().resolve<ISponsorshipPricingRepository>(DI_TOKENS.SponsorshipPricingRepository);
}
get applyForSponsorshipUseCase(): ApplyForSponsorshipUseCase {
this.ensureInitialized();
return getDIContainer().resolve<ApplyForSponsorshipUseCase>(DI_TOKENS.ApplyForSponsorshipUseCase);
}
get acceptSponsorshipRequestUseCase(): AcceptSponsorshipRequestUseCase {
this.ensureInitialized();
return getDIContainer().resolve<AcceptSponsorshipRequestUseCase>(DI_TOKENS.AcceptSponsorshipRequestUseCase);
}
get rejectSponsorshipRequestUseCase(): RejectSponsorshipRequestUseCase {
this.ensureInitialized();
return getDIContainer().resolve<RejectSponsorshipRequestUseCase>(DI_TOKENS.RejectSponsorshipRequestUseCase);
}
get getPendingSponsorshipRequestsQuery(): GetPendingSponsorshipRequestsQuery {
this.ensureInitialized();
return getDIContainer().resolve<GetPendingSponsorshipRequestsQuery>(DI_TOKENS.GetPendingSponsorshipRequestsQuery);
}
get getEntitySponsorshipPricingQuery(): GetEntitySponsorshipPricingQuery {
this.ensureInitialized();
return getDIContainer().resolve<GetEntitySponsorshipPricingQuery>(DI_TOKENS.GetEntitySponsorshipPricingQuery);
}
}
/**
@@ -606,6 +672,10 @@ export function getCarRepository(): ICarRepository {
return DIContainer.getInstance().carRepository;
}
export function getSeasonRepository(): ISeasonRepository {
return DIContainer.getInstance().seasonRepository;
}
export function getNotificationRepository(): INotificationRepository {
return DIContainer.getInstance().notificationRepository;
}
@@ -658,6 +728,50 @@ export function getTransferLeagueOwnershipUseCase(): TransferLeagueOwnershipUseC
return DIContainer.getInstance().transferLeagueOwnershipUseCase;
}
export function getSponsorRepository(): ISponsorRepository {
return DIContainer.getInstance().sponsorRepository;
}
export function getSeasonSponsorshipRepository(): ISeasonSponsorshipRepository {
return DIContainer.getInstance().seasonSponsorshipRepository;
}
export function getGetSponsorDashboardQuery(): GetSponsorDashboardQuery {
return DIContainer.getInstance().getSponsorDashboardQuery;
}
export function getGetSponsorSponsorshipsQuery(): GetSponsorSponsorshipsQuery {
return DIContainer.getInstance().getSponsorSponsorshipsQuery;
}
export function getSponsorshipRequestRepository(): ISponsorshipRequestRepository {
return DIContainer.getInstance().sponsorshipRequestRepository;
}
export function getSponsorshipPricingRepository(): ISponsorshipPricingRepository {
return DIContainer.getInstance().sponsorshipPricingRepository;
}
export function getApplyForSponsorshipUseCase(): ApplyForSponsorshipUseCase {
return DIContainer.getInstance().applyForSponsorshipUseCase;
}
export function getAcceptSponsorshipRequestUseCase(): AcceptSponsorshipRequestUseCase {
return DIContainer.getInstance().acceptSponsorshipRequestUseCase;
}
export function getRejectSponsorshipRequestUseCase(): RejectSponsorshipRequestUseCase {
return DIContainer.getInstance().rejectSponsorshipRequestUseCase;
}
export function getGetPendingSponsorshipRequestsQuery(): GetPendingSponsorshipRequestsQuery {
return DIContainer.getInstance().getPendingSponsorshipRequestsQuery;
}
export function getGetEntitySponsorshipPricingQuery(): GetEntitySponsorshipPricingQuery {
return DIContainer.getInstance().getEntitySponsorshipPricingQuery;
}
/**
* Reset function for testing
*/

View File

@@ -24,6 +24,10 @@ export const DI_TOKENS = {
SocialRepository: Symbol.for('ISocialGraphRepository'),
NotificationRepository: Symbol.for('INotificationRepository'),
NotificationPreferenceRepository: Symbol.for('INotificationPreferenceRepository'),
SponsorRepository: Symbol.for('ISponsorRepository'),
SeasonSponsorshipRepository: Symbol.for('ISeasonSponsorshipRepository'),
SponsorshipRequestRepository: Symbol.for('ISponsorshipRequestRepository'),
SponsorshipPricingRepository: Symbol.for('ISponsorshipPricingRepository'),
// Providers
LeagueScoringPresetProvider: Symbol.for('LeagueScoringPresetProvider'),
@@ -87,6 +91,17 @@ export const DI_TOKENS = {
// Queries - Notifications
GetUnreadNotificationsQuery: Symbol.for('GetUnreadNotificationsQuery'),
// Queries - Sponsors
GetSponsorDashboardQuery: Symbol.for('GetSponsorDashboardQuery'),
GetSponsorSponsorshipsQuery: Symbol.for('GetSponsorSponsorshipsQuery'),
GetPendingSponsorshipRequestsQuery: Symbol.for('GetPendingSponsorshipRequestsQuery'),
GetEntitySponsorshipPricingQuery: Symbol.for('GetEntitySponsorshipPricingQuery'),
// Use Cases - Sponsorship
ApplyForSponsorshipUseCase: Symbol.for('ApplyForSponsorshipUseCase'),
AcceptSponsorshipRequestUseCase: Symbol.for('AcceptSponsorshipRequestUseCase'),
RejectSponsorshipRequestUseCase: Symbol.for('RejectSponsorshipRequestUseCase'),
// Data
DriverStats: Symbol.for('DriverStats'),
} as const;