refactor racing use cases

This commit is contained in:
2025-12-21 00:43:42 +01:00
parent e9d6f90bb2
commit c12656d671
308 changed files with 14401 additions and 7419 deletions

View File

@@ -3,45 +3,91 @@ import type { ISeasonRepository } from '../../domain/repositories/ISeasonReposit
import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository';
import type { ILeagueMembershipRepository } from '../../domain/repositories/ILeagueMembershipRepository';
import type { IRaceRepository } from '../../domain/repositories/IRaceRepository';
import type { AsyncUseCase } from '@core/shared/application';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { SponsorshipDetailOutput } from '../ports/output/SponsorSponsorshipsOutputPort';
import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort';
export interface GetSeasonSponsorshipsParams {
export type GetSeasonSponsorshipsInput = {
seasonId: string;
}
};
export interface GetSeasonSponsorshipsOutputPort {
export type SeasonSponsorshipMetrics = {
drivers: number;
races: number;
completedRaces: number;
impressions: number;
};
export type SeasonSponsorshipFinancials = {
amount: number;
currency: string;
};
import type { LeagueId } from '../../domain/entities/LeagueId';
import type { LeagueName } from '../../domain/entities/LeagueName';
export type SeasonSponsorshipDetail = {
id: string;
leagueId: LeagueId;
leagueName: LeagueName;
seasonId: string;
sponsorships: SponsorshipDetailOutput[];
}
seasonName: string;
seasonStartDate?: Date;
seasonEndDate?: Date;
tier: string;
status: string;
pricing: SeasonSponsorshipFinancials;
platformFee: SeasonSponsorshipFinancials;
netAmount: SeasonSponsorshipFinancials;
metrics: SeasonSponsorshipMetrics;
createdAt: Date;
activatedAt?: Date;
};
export class GetSeasonSponsorshipsUseCase
implements AsyncUseCase<GetSeasonSponsorshipsParams, GetSeasonSponsorshipsOutputPort | null, 'REPOSITORY_ERROR'>
{
export type GetSeasonSponsorshipsResult = {
seasonId: string;
sponsorships: SeasonSponsorshipDetail[];
};
export type GetSeasonSponsorshipsErrorCode =
| 'SEASON_NOT_FOUND'
| 'LEAGUE_NOT_FOUND'
| 'REPOSITORY_ERROR';
export class GetSeasonSponsorshipsUseCase {
constructor(
private readonly seasonSponsorshipRepository: ISeasonSponsorshipRepository,
private readonly seasonRepository: ISeasonRepository,
private readonly leagueRepository: ILeagueRepository,
private readonly leagueMembershipRepository: ILeagueMembershipRepository,
private readonly raceRepository: IRaceRepository,
private readonly output: UseCaseOutputPort<GetSeasonSponsorshipsResult>,
) {}
async execute(
params: GetSeasonSponsorshipsParams,
): Promise<Result<GetSeasonSponsorshipsOutputPort | null, ApplicationErrorCode<'REPOSITORY_ERROR'>>> {
input: GetSeasonSponsorshipsInput,
): Promise<Result<void, ApplicationErrorCode<GetSeasonSponsorshipsErrorCode, { message: string }>>> {
try {
const { seasonId } = params;
const { seasonId } = input;
const season = await this.seasonRepository.findById(seasonId);
if (!season) {
return Result.ok(null);
return Result.err({
code: 'SEASON_NOT_FOUND',
details: {
message: 'Season not found',
},
});
}
const league = await this.leagueRepository.findById(season.leagueId);
if (!league) {
return Result.ok(null);
return Result.err({
code: 'LEAGUE_NOT_FOUND',
details: {
message: 'League not found for season',
},
});
}
const sponsorships = await this.seasonSponsorshipRepository.findBySeasonId(seasonId);
@@ -55,7 +101,7 @@ export class GetSeasonSponsorshipsUseCase
const completedRaces = races.filter(r => r.status === 'completed').length;
const impressions = completedRaces * driverCount * 100;
const sponsorshipDetails: SponsorshipDetailOutput[] = sponsorships.map(sponsorship => {
const sponsorshipDetails: SeasonSponsorshipDetail[] = sponsorships.map(sponsorship => {
const platformFee = sponsorship.getPlatformFee();
const netAmount = sponsorship.getNetAmount();
@@ -65,8 +111,8 @@ export class GetSeasonSponsorshipsUseCase
leagueName: league.name,
seasonId: season.id,
seasonName: season.name,
...(season.startDate !== undefined ? { seasonStartDate: season.startDate } : {}),
...(season.endDate !== undefined ? { seasonEndDate: season.endDate } : {}),
seasonStartDate: season.startDate,
seasonEndDate: season.endDate,
tier: sponsorship.tier,
status: sponsorship.status,
pricing: {
@@ -88,16 +134,25 @@ export class GetSeasonSponsorshipsUseCase
impressions,
},
createdAt: sponsorship.createdAt,
...(sponsorship.activatedAt !== undefined ? { activatedAt: sponsorship.activatedAt } : {}),
activatedAt: sponsorship.activatedAt,
};
});
return Result.ok({
this.output.present({
seasonId,
sponsorships: sponsorshipDetails,
});
} catch {
return Result.err({ code: 'REPOSITORY_ERROR', message: 'Failed to fetch season sponsorships' });
return Result.ok(undefined);
} catch (err) {
const error = err as { message?: string } | undefined;
return Result.err({
code: 'REPOSITORY_ERROR',
details: {
message: error?.message ?? 'Failed to fetch season sponsorships',
},
});
}
}
}