89 lines
2.7 KiB
TypeScript
89 lines
2.7 KiB
TypeScript
import type { ISeasonRepository } from '../../domain/repositories/ISeasonRepository';
|
|
import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository';
|
|
import { Result } from '@core/shared/application/Result';
|
|
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
|
|
|
export type SeasonLifecycleTransition =
|
|
| 'activate'
|
|
| 'complete'
|
|
| 'archive'
|
|
| 'cancel';
|
|
|
|
export interface ManageSeasonLifecycleCommand {
|
|
leagueId: string;
|
|
seasonId: string;
|
|
transition: SeasonLifecycleTransition;
|
|
}
|
|
|
|
export interface ManageSeasonLifecycleResultDTO {
|
|
seasonId: string;
|
|
status: import('../../domain/entities/Season').SeasonStatus;
|
|
startDate?: Date;
|
|
endDate?: Date;
|
|
}
|
|
|
|
type ManageSeasonLifecycleErrorCode = 'LEAGUE_NOT_FOUND' | 'SEASON_NOT_FOUND' | 'INVALID_TRANSITION';
|
|
|
|
/**
|
|
* ManageSeasonLifecycleUseCase
|
|
*/
|
|
export class ManageSeasonLifecycleUseCase {
|
|
constructor(
|
|
private readonly leagueRepository: ILeagueRepository,
|
|
private readonly seasonRepository: ISeasonRepository,
|
|
) {}
|
|
|
|
async execute(
|
|
command: ManageSeasonLifecycleCommand,
|
|
): Promise<Result<ManageSeasonLifecycleResultDTO, ApplicationErrorCode<ManageSeasonLifecycleErrorCode>>> {
|
|
const league = await this.leagueRepository.findById(command.leagueId);
|
|
if (!league) {
|
|
return Result.err({
|
|
code: 'LEAGUE_NOT_FOUND',
|
|
details: { message: `League not found: ${command.leagueId}` },
|
|
});
|
|
}
|
|
|
|
const season = await this.seasonRepository.findById(command.seasonId);
|
|
if (!season || season.leagueId !== league.id) {
|
|
return Result.err({
|
|
code: 'SEASON_NOT_FOUND',
|
|
details: { message: `Season ${command.seasonId} does not belong to league ${league.id}` },
|
|
});
|
|
}
|
|
|
|
let updated;
|
|
try {
|
|
switch (command.transition) {
|
|
case 'activate':
|
|
updated = season.activate();
|
|
break;
|
|
case 'complete':
|
|
updated = season.complete();
|
|
break;
|
|
case 'archive':
|
|
updated = season.archive();
|
|
break;
|
|
case 'cancel':
|
|
updated = season.cancel();
|
|
break;
|
|
default:
|
|
throw new Error(`Unsupported Season lifecycle transition`);
|
|
}
|
|
} catch (error) {
|
|
return Result.err({
|
|
code: 'INVALID_TRANSITION',
|
|
details: { message: `Invalid transition: ${(error as Error).message}` },
|
|
});
|
|
}
|
|
|
|
await this.seasonRepository.update(updated);
|
|
|
|
return Result.ok({
|
|
seasonId: updated.id,
|
|
status: updated.status,
|
|
...(updated.startDate !== undefined ? { startDate: updated.startDate } : {}),
|
|
...(updated.endDate !== undefined ? { endDate: updated.endDate } : {}),
|
|
});
|
|
}
|
|
} |