refactor racing use cases
This commit is contained in:
@@ -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',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user