/** * Application Use Case: GetPendingSponsorshipRequestsUseCase * * Retrieves pending sponsorship requests for an entity owner to review. */ import type { ISponsorshipRequestRepository } from '../../domain/repositories/ISponsorshipRequestRepository'; import type { ISponsorRepository } from '../../domain/repositories/ISponsorRepository'; import type { SponsorableEntityType } from '../../domain/entities/SponsorshipRequest'; import type { SponsorshipTier } from '../../domain/entities/SeasonSponsorship'; import type { UseCase } from '@gridpilot/shared/application/UseCase'; import type { IPendingSponsorshipRequestsPresenter, PendingSponsorshipRequestsViewModel, } from '../presenters/IPendingSponsorshipRequestsPresenter'; export interface GetPendingSponsorshipRequestsDTO { entityType: SponsorableEntityType; entityId: string; } export interface PendingSponsorshipRequestDTO { id: string; sponsorId: string; sponsorName: string; sponsorLogo?: string; tier: SponsorshipTier; offeredAmount: number; currency: string; formattedAmount: string; message?: string; createdAt: Date; platformFee: number; netAmount: number; } export interface GetPendingSponsorshipRequestsResultDTO { entityType: SponsorableEntityType; entityId: string; requests: PendingSponsorshipRequestDTO[]; totalCount: number; } export class GetPendingSponsorshipRequestsUseCase implements UseCase< GetPendingSponsorshipRequestsDTO, GetPendingSponsorshipRequestsResultDTO, PendingSponsorshipRequestsViewModel, IPendingSponsorshipRequestsPresenter > { constructor( private readonly sponsorshipRequestRepo: ISponsorshipRequestRepository, private readonly sponsorRepo: ISponsorRepository, ) {} async execute( dto: GetPendingSponsorshipRequestsDTO, presenter: IPendingSponsorshipRequestsPresenter, ): Promise { presenter.reset(); const requests = await this.sponsorshipRequestRepo.findPendingByEntity( dto.entityType, dto.entityId ); const requestDTOs: PendingSponsorshipRequestDTO[] = []; for (const request of requests) { const sponsor = await this.sponsorRepo.findById(request.sponsorId); requestDTOs.push({ id: request.id, sponsorId: request.sponsorId, sponsorName: sponsor?.name ?? 'Unknown Sponsor', ...(sponsor?.logoUrl !== undefined ? { sponsorLogo: sponsor.logoUrl } : {}), tier: request.tier, offeredAmount: request.offeredAmount.amount, currency: request.offeredAmount.currency, formattedAmount: request.offeredAmount.format(), ...(request.message !== undefined ? { message: request.message } : {}), createdAt: request.createdAt, platformFee: request.getPlatformFee().amount, netAmount: request.getNetAmount().amount, }); } // Sort by creation date (newest first) requestDTOs.sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime()); presenter.present({ entityType: dto.entityType, entityId: dto.entityId, requests: requestDTOs, totalCount: requestDTOs.length, }); } }