/** * Application Use Case: GetEntitySponsorshipPricingUseCase * * Retrieves sponsorship pricing configuration for any entity. * Used by sponsors to see available slots and prices. */ import type { ISponsorshipPricingRepository } from '../../domain/repositories/ISponsorshipPricingRepository'; import type { ISponsorshipRequestRepository } from '../../domain/repositories/ISponsorshipRequestRepository'; import type { ISeasonSponsorshipRepository } from '../../domain/repositories/ISeasonSponsorshipRepository'; import type { AsyncUseCase, Logger } from '@core/shared/application'; import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { GetEntitySponsorshipPricingDTO } from '../dto/GetEntitySponsorshipPricingDTO'; import type { GetEntitySponsorshipPricingResultDTO } from '../dto/GetEntitySponsorshipPricingResultDTO'; export class GetEntitySponsorshipPricingUseCase implements AsyncUseCase { constructor( private readonly sponsorshipPricingRepo: ISponsorshipPricingRepository, private readonly sponsorshipRequestRepo: ISponsorshipRequestRepository, private readonly seasonSponsorshipRepo: ISeasonSponsorshipRepository, private readonly logger: Logger, ) {} async execute(dto: GetEntitySponsorshipPricingDTO): Promise>> { this.logger.debug(`Executing GetEntitySponsorshipPricingUseCase for entityType: ${dto.entityType}, entityId: ${dto.entityId}`); try { const pricing = await this.sponsorshipPricingRepo.findByEntity(dto.entityType, dto.entityId); if (!pricing) { this.logger.info(`No pricing found for entityType: ${dto.entityType}, entityId: ${dto.entityId}`); return Result.ok(null); } // Count pending requests by tier const pendingRequests = await this.sponsorshipRequestRepo.findPendingByEntity( dto.entityType, dto.entityId, ); const pendingMainCount = pendingRequests.filter(r => r.tier === 'main').length; const pendingSecondaryCount = pendingRequests.filter(r => r.tier === 'secondary').length; // Count filled slots (for seasons, check SeasonSponsorship table) let filledMainSlots = 0; let filledSecondarySlots = 0; if (dto.entityType === 'season') { const sponsorships = await this.seasonSponsorshipRepo.findBySeasonId(dto.entityId); const activeSponsorships = sponsorships.filter(s => s.isActive()); filledMainSlots = activeSponsorships.filter(s => s.tier === 'main').length; filledSecondarySlots = activeSponsorships.filter(s => s.tier === 'secondary').length; } const result: GetEntitySponsorshipPricingResultDTO = { entityType: dto.entityType, entityId: dto.entityId, acceptingApplications: pricing.acceptingApplications, ...(pricing.customRequirements !== undefined ? { customRequirements: pricing.customRequirements } : {}), }; if (pricing.mainSlot) { const mainMaxSlots = pricing.mainSlot.maxSlots; result.mainSlot = { tier: 'main', price: pricing.mainSlot.price.amount, currency: pricing.mainSlot.price.currency, formattedPrice: pricing.mainSlot.price.format(), benefits: pricing.mainSlot.benefits, available: pricing.mainSlot.available && filledMainSlots < mainMaxSlots, maxSlots: mainMaxSlots, filledSlots: filledMainSlots, pendingRequests: pendingMainCount, }; } if (pricing.secondarySlots) { const secondaryMaxSlots = pricing.secondarySlots.maxSlots; result.secondarySlot = { tier: 'secondary', price: pricing.secondarySlots.price.amount, currency: pricing.secondarySlots.price.currency, formattedPrice: pricing.secondarySlots.price.format(), benefits: pricing.secondarySlots.benefits, available: pricing.secondarySlots.available && filledSecondarySlots < secondaryMaxSlots, maxSlots: secondaryMaxSlots, filledSlots: filledSecondarySlots, pendingRequests: pendingSecondaryCount, }; } this.logger.info(`Successfully retrieved sponsorship pricing for entityType: ${dto.entityType}, entityId: ${dto.entityId}`); return Result.ok(result); } catch (error) { this.logger.error('Error executing GetEntitySponsorshipPricingUseCase', error instanceof Error ? error : new Error(String(error))); return Result.err({ code: 'REPOSITORY_ERROR', details: { message: error instanceof Error ? error.message : 'Unknown error occurred' } }); } } }