import type { ILeagueRepository } from '../../domain/repositories/ILeagueRepository'; import type { ILeagueMembershipRepository } from '../../domain/repositories/ILeagueMembershipRepository'; import type { League } from '../../domain/entities/League'; import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { UseCaseOutputPort } from '@core/shared/application/UseCaseOutputPort'; export type GetAllLeaguesWithCapacityInput = {}; export type LeagueCapacitySummary = { league: League; currentDrivers: number; maxDrivers: number; }; export type GetAllLeaguesWithCapacityResult = { leagues: LeagueCapacitySummary[]; }; export type GetAllLeaguesWithCapacityErrorCode = 'REPOSITORY_ERROR'; /** * Use Case for retrieving all leagues with capacity information. * Orchestrates domain logic and delegates presentation to an output port. */ export class GetAllLeaguesWithCapacityUseCase { constructor( private readonly leagueRepository: ILeagueRepository, private readonly leagueMembershipRepository: ILeagueMembershipRepository, private readonly output: UseCaseOutputPort, ) {} async execute( _input: GetAllLeaguesWithCapacityInput = {}, ): Promise< Result< void, ApplicationErrorCode > > { try { const leagues = await this.leagueRepository.findAll(); const summaries: LeagueCapacitySummary[] = []; for (const league of leagues) { const members = await this.leagueMembershipRepository.getLeagueMembers(league.id); const currentDrivers = members.filter( (m) => m.status === 'active' && (m.role === 'owner' || m.role === 'admin' || m.role === 'steward' || m.role === 'member'), ).length; const maxDrivers = league.settings.maxDrivers ?? 0; summaries.push({ league, currentDrivers, maxDrivers }); } this.output.present({ leagues: summaries }); return Result.ok(undefined); } catch (error: unknown) { const message = error instanceof Error && error.message ? error.message : 'Failed to load leagues with capacity'; return Result.err({ code: 'REPOSITORY_ERROR', details: { message }, }); } } }