import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ILeagueMembershipRepository } from '../../domain/repositories/ILeagueMembershipRepository'; import { LeagueMembership } from '../../domain/entities/LeagueMembership'; import type { MembershipRoleValue } from '../../domain/entities/MembershipRole'; export type UpdateLeagueMemberRoleInput = { leagueId: string; targetDriverId: string; newRole: string; }; export type UpdateLeagueMemberRoleResult = { membership: LeagueMembership; }; export type UpdateLeagueMemberRoleErrorCode = | 'MEMBERSHIP_NOT_FOUND' | 'INVALID_ROLE' | 'CANNOT_DOWNGRADE_LAST_OWNER' | 'REPOSITORY_ERROR'; export class UpdateLeagueMemberRoleUseCase { constructor(private readonly leagueMembershipRepository: ILeagueMembershipRepository) {} async execute( input: UpdateLeagueMemberRoleInput, ): Promise< Result> > { try { const memberships = await this.leagueMembershipRepository.getLeagueMembers(input.leagueId); const membership = memberships.find(m => m.driverId.toString() === input.targetDriverId); if (!membership) { return Result.err({ code: 'MEMBERSHIP_NOT_FOUND', details: { message: 'League membership not found' }, }); } const allowedRoles: MembershipRoleValue[] = ['owner', 'admin', 'steward', 'member']; const requestedRole = input.newRole as MembershipRoleValue; if (!allowedRoles.includes(requestedRole)) { return Result.err({ code: 'INVALID_ROLE', details: { message: 'Invalid membership role' }, }); } const ownerCount = memberships.filter(m => m.role.toString() === 'owner').length; const isTargetOwner = membership.role.toString() === 'owner'; if (isTargetOwner && requestedRole !== 'owner' && ownerCount <= 1) { return Result.err({ code: 'CANNOT_DOWNGRADE_LAST_OWNER', details: { message: 'Cannot downgrade the last owner' }, }); } const updatedMembership = LeagueMembership.create({ id: membership.id, leagueId: membership.leagueId.toString(), driverId: membership.driverId.toString(), role: requestedRole, status: membership.status.toString(), joinedAt: membership.joinedAt.toDate(), }); await this.leagueMembershipRepository.saveMembership(updatedMembership); const result: UpdateLeagueMemberRoleResult = { membership: updatedMembership, }; return Result.ok(result); } catch (error: unknown) { const message = error instanceof Error && typeof error.message === 'string' ? error.message : 'Failed to update league member role'; return Result.err({ code: 'REPOSITORY_ERROR', details: { message }, }); } } }