Files
gridpilot.gg/packages/racing/application/use-cases/GetSponsorSponsorshipsUseCase.ts
2025-12-11 00:57:32 +01:00

166 lines
5.1 KiB
TypeScript

/**
* Application Use Case: GetSponsorSponsorshipsUseCase
*
* Returns detailed sponsorship information for a sponsor's campaigns/sponsorships page.
*/
import type { ISponsorRepository } from '../../domain/repositories/ISponsorRepository';
import type { ISeasonSponsorshipRepository } from '../../domain/repositories/ISeasonSponsorshipRepository';
import type { ISeasonRepository } from '../../domain/repositories/ISeasonRepository';
import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository';
import type { ILeagueMembershipRepository } from '../../domain/repositories/ILeagueMembershipRepository';
import type { IRaceRepository } from '../../domain/repositories/IRaceRepository';
import type { SponsorshipTier, SponsorshipStatus } from '../../domain/entities/SeasonSponsorship';
import type { ISponsorSponsorshipsPresenter } from '../presenters/ISponsorSponsorshipsPresenter';
export interface GetSponsorSponsorshipsQueryParams {
sponsorId: string;
}
export interface SponsorshipDetailDTO {
id: string;
leagueId: string;
leagueName: string;
seasonId: string;
seasonName: string;
seasonStartDate?: Date;
seasonEndDate?: Date;
tier: SponsorshipTier;
status: SponsorshipStatus;
pricing: {
amount: number;
currency: string;
};
platformFee: {
amount: number;
currency: string;
};
netAmount: {
amount: number;
currency: string;
};
metrics: {
drivers: number;
races: number;
completedRaces: number;
impressions: number;
};
createdAt: Date;
activatedAt?: Date;
}
export interface SponsorSponsorshipsDTO {
sponsorId: string;
sponsorName: string;
sponsorships: SponsorshipDetailDTO[];
summary: {
totalSponsorships: number;
activeSponsorships: number;
totalInvestment: number;
totalPlatformFees: number;
currency: string;
};
}
export class GetSponsorSponsorshipsUseCase {
constructor(
private readonly sponsorRepository: ISponsorRepository,
private readonly seasonSponsorshipRepository: ISeasonSponsorshipRepository,
private readonly seasonRepository: ISeasonRepository,
private readonly leagueRepository: ILeagueRepository,
private readonly leagueMembershipRepository: ILeagueMembershipRepository,
private readonly raceRepository: IRaceRepository,
private readonly presenter: ISponsorSponsorshipsPresenter,
) {}
async execute(params: GetSponsorSponsorshipsQueryParams): Promise<void> {
const { sponsorId } = params;
const sponsor = await this.sponsorRepository.findById(sponsorId);
if (!sponsor) {
this.presenter.present(null);
return;
}
// Get all sponsorships for this sponsor
const sponsorships = await this.seasonSponsorshipRepository.findBySponsorId(sponsorId);
const sponsorshipDetails: SponsorshipDetailDTO[] = [];
let totalInvestment = 0;
let totalPlatformFees = 0;
for (const sponsorship of sponsorships) {
// Get season to find league
const season = await this.seasonRepository.findById(sponsorship.seasonId);
if (!season) continue;
const league = await this.leagueRepository.findById(season.leagueId);
if (!league) continue;
// Get membership count for this league
const memberships = await this.leagueMembershipRepository.getLeagueMembers(season.leagueId);
const driverCount = memberships.length;
// Get races for this league
const races = await this.raceRepository.findByLeagueId(season.leagueId);
const completedRaces = races.filter(r => r.status === 'completed').length;
// Calculate impressions
const impressions = completedRaces * driverCount * 100;
// Calculate platform fee (10%)
const platformFee = sponsorship.getPlatformFee();
const netAmount = sponsorship.getNetAmount();
totalInvestment += sponsorship.pricing.amount;
totalPlatformFees += platformFee.amount;
sponsorshipDetails.push({
id: sponsorship.id,
leagueId: league.id,
leagueName: league.name,
seasonId: season.id,
seasonName: season.name,
seasonStartDate: season.startDate,
seasonEndDate: season.endDate,
tier: sponsorship.tier,
status: sponsorship.status,
pricing: {
amount: sponsorship.pricing.amount,
currency: sponsorship.pricing.currency,
},
platformFee: {
amount: platformFee.amount,
currency: platformFee.currency,
},
netAmount: {
amount: netAmount.amount,
currency: netAmount.currency,
},
metrics: {
drivers: driverCount,
races: races.length,
completedRaces,
impressions,
},
createdAt: sponsorship.createdAt,
activatedAt: sponsorship.activatedAt,
});
}
const activeSponsorships = sponsorships.filter(s => s.status === 'active').length;
this.presenter.present({
sponsorId,
sponsorName: sponsor.name,
sponsorships: sponsorshipDetails,
summary: {
totalSponsorships: sponsorships.length,
activeSponsorships,
totalInvestment,
totalPlatformFees,
currency: 'USD',
},
});
}
}