import type { LeagueMembershipRepository, } from '@core/racing/domain/repositories/LeagueMembershipRepository'; import type { Logger } from '@core/shared/domain/Logger'; import { Result } from '@core/shared/domain/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import { LeagueRepository } from '../../domain/repositories/LeagueRepository'; export interface TransferLeagueOwnershipInput { leagueId: string; currentOwnerId: string; newOwnerId: string; } export type TransferLeagueOwnershipResult = { leagueId: string; previousOwnerId: string; newOwnerId: string; }; export type TransferLeagueOwnershipErrorCode = | 'LEAGUE_NOT_FOUND' | 'NOT_LEAGUE_OWNER' | 'NEW_OWNER_NOT_MEMBER' | 'REPOSITORY_ERROR'; export class TransferLeagueOwnershipUseCase { constructor( private readonly leagueRepository: LeagueRepository, private readonly membershipRepository: LeagueMembershipRepository, private readonly logger: Logger, ) {} async execute( input: TransferLeagueOwnershipInput, ): Promise< Result> > { const { leagueId, currentOwnerId, newOwnerId } = input; try { const league = await this.leagueRepository.findById(leagueId); if (!league) { return Result.err({ code: 'LEAGUE_NOT_FOUND', details: { message: `League with id ${leagueId} not found` }, } as ApplicationErrorCode); } if (league.ownerId.toString() !== currentOwnerId) { return Result.err({ code: 'NOT_LEAGUE_OWNER', details: { message: 'Current user is not the league owner' }, } as ApplicationErrorCode); } const newOwnerMembership = await this.membershipRepository.getMembership( leagueId, newOwnerId, ); if (!newOwnerMembership || newOwnerMembership.status.toString() !== 'active') { return Result.err({ code: 'NEW_OWNER_NOT_MEMBER', details: { message: 'New owner must be an active league member' }, } as ApplicationErrorCode); } const currentOwnerMembership = await this.membershipRepository.getMembership( leagueId, currentOwnerId, ); const updatedNewOwnerMembership = { ...(newOwnerMembership as unknown as { role: string }), role: 'owner', } as unknown as import('../../domain/entities/LeagueMembership').LeagueMembership; await this.membershipRepository.saveMembership(updatedNewOwnerMembership); if (currentOwnerMembership) { const updatedCurrentOwnerMembership = { ...(currentOwnerMembership as unknown as { role: string }), role: 'admin', } as unknown as import('../../domain/entities/LeagueMembership').LeagueMembership; await this.membershipRepository.saveMembership(updatedCurrentOwnerMembership); } const updatedLeague = league.update({ ownerId: newOwnerId }); await this.leagueRepository.update(updatedLeague); const result: TransferLeagueOwnershipResult = { leagueId, previousOwnerId: currentOwnerId, newOwnerId, }; return Result.ok(result); } catch (error) { const message = error instanceof Error && error.message ? error.message : 'Failed to transfer league ownership'; this.logger.error(message, error as Error, { leagueId, currentOwnerId, newOwnerId, }); return Result.err({ code: 'REPOSITORY_ERROR', details: { message }, } as ApplicationErrorCode); } } }