import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ILeagueMembershipRepository, } from '@core/racing/domain/repositories/ILeagueMembershipRepository'; import type { ILeagueRepository } from '@core/racing/domain/repositories/ILeagueRepository'; import type { MembershipRole, } from '@core/racing/domain/entities/LeagueMembership'; import type { TransferLeagueOwnershipResultDTO } from '../presenters/ITransferLeagueOwnershipPresenter'; export interface TransferLeagueOwnershipCommandDTO { leagueId: string; currentOwnerId: string; newOwnerId: string; } type TransferLeagueOwnershipErrorCode = 'LEAGUE_NOT_FOUND' | 'NOT_CURRENT_OWNER' | 'NEW_OWNER_NOT_ACTIVE_MEMBER'; export class TransferLeagueOwnershipUseCase { constructor( private readonly leagueRepository: ILeagueRepository, private readonly membershipRepository: ILeagueMembershipRepository ) {} async execute(command: TransferLeagueOwnershipCommandDTO): Promise>> { const { leagueId, currentOwnerId, newOwnerId } = command; const league = await this.leagueRepository.findById(leagueId); if (!league) { return Result.err({ code: 'LEAGUE_NOT_FOUND' }); } if (league.ownerId !== currentOwnerId) { return Result.err({ code: 'NOT_CURRENT_OWNER' }); } const newOwnerMembership = await this.membershipRepository.getMembership(leagueId, newOwnerId); if (!newOwnerMembership || newOwnerMembership.status !== 'active') { return Result.err({ code: 'NEW_OWNER_NOT_ACTIVE_MEMBER' }); } const currentOwnerMembership = await this.membershipRepository.getMembership(leagueId, currentOwnerId); await this.membershipRepository.saveMembership({ ...newOwnerMembership, role: 'owner' as MembershipRole, }); if (currentOwnerMembership) { await this.membershipRepository.saveMembership({ ...currentOwnerMembership, role: 'admin' as MembershipRole, }); } const updatedLeague = league.update({ ownerId: newOwnerId }); await this.leagueRepository.update(updatedLeague); return Result.ok(undefined); } }