64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
import type { Logger } from '@core/shared/application';
|
|
import type { ILeagueMembershipRepository } from '@core/racing/domain/repositories/ILeagueMembershipRepository';
|
|
import { LeagueMembership } from '../../domain/entities/LeagueMembership';
|
|
import { Result } from '@core/shared/application/Result';
|
|
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
|
|
import type { UseCaseOutputPort } from '@core/shared/application';
|
|
|
|
export type JoinLeagueErrorCode = 'ALREADY_MEMBER' | 'REPOSITORY_ERROR';
|
|
|
|
export interface JoinLeagueInput {
|
|
leagueId: string;
|
|
driverId: string;
|
|
}
|
|
|
|
export interface JoinLeagueResult {
|
|
membership: LeagueMembership;
|
|
}
|
|
|
|
export class JoinLeagueUseCase {
|
|
constructor(
|
|
private readonly membershipRepository: ILeagueMembershipRepository,
|
|
private readonly logger: Logger,
|
|
private readonly output: UseCaseOutputPort<JoinLeagueResult>,
|
|
) {}
|
|
|
|
async execute(command: JoinLeagueInput): Promise<Result<void, ApplicationErrorCode<JoinLeagueErrorCode, { message: string }>>> {
|
|
this.logger.debug('Attempting to join league', { command });
|
|
const { leagueId, driverId } = command;
|
|
|
|
try {
|
|
const existing = await this.membershipRepository.getMembership(leagueId, driverId);
|
|
if (existing) {
|
|
this.logger.warn('Driver already a member or has pending request', { leagueId, driverId });
|
|
return Result.err({
|
|
code: 'ALREADY_MEMBER',
|
|
details: { message: 'Driver is already a member of this league or has a pending membership.' },
|
|
});
|
|
}
|
|
|
|
const membership = LeagueMembership.create({
|
|
leagueId,
|
|
driverId,
|
|
role: 'member',
|
|
status: 'active',
|
|
});
|
|
|
|
const savedMembership = await this.membershipRepository.saveMembership(membership);
|
|
this.logger.info('Successfully joined league', { membershipId: savedMembership.id });
|
|
|
|
this.output.present({
|
|
membership: savedMembership,
|
|
});
|
|
|
|
return Result.ok(undefined);
|
|
} catch (error) {
|
|
const err = error instanceof Error ? error : new Error('Unknown error');
|
|
this.logger.error('Failed to join league due to an unexpected error', err);
|
|
return Result.err({
|
|
code: 'REPOSITORY_ERROR',
|
|
details: { message: err.message ?? 'Failed to join league' },
|
|
});
|
|
}
|
|
}
|
|
} |