import { IAdminVoteSessionRepository } from '../../domain/repositories/IAdminVoteSessionRepository'; import { AdminVoteSession } from '../../domain/entities/AdminVoteSession'; import { OpenAdminVoteSessionInput, OpenAdminVoteSessionOutput } from '../dtos/AdminVoteSessionDto'; /** * Use Case: OpenAdminVoteSessionUseCase * * Opens a new admin vote session for a league. * Follows CQRS Light: command side operation. * * Per plans section 7.1.1 */ export class OpenAdminVoteSessionUseCase { constructor( private readonly adminVoteSessionRepository: IAdminVoteSessionRepository, ) {} async execute(input: OpenAdminVoteSessionInput): Promise { try { // Validate input const errors = this.validateInput(input); if (errors.length > 0) { return { success: false, voteSessionId: input.voteSessionId, errors, }; } // Check if session already exists const existing = await this.adminVoteSessionRepository.findById(input.voteSessionId); if (existing) { return { success: false, voteSessionId: input.voteSessionId, errors: ['Vote session with this ID already exists'], }; } // Check for overlapping active sessions for this admin in this league const activeSessions = await this.adminVoteSessionRepository.findActiveForAdmin( input.adminId, input.leagueId ); const startDate = new Date(input.startDate); const endDate = new Date(input.endDate); for (const session of activeSessions) { // Check for overlap if ( (startDate >= session.startDate && startDate <= session.endDate) || (endDate >= session.startDate && endDate <= session.endDate) || (startDate <= session.startDate && endDate >= session.endDate) ) { return { success: false, voteSessionId: input.voteSessionId, errors: ['Active vote session already exists for this admin in this league with overlapping dates'], }; } } // Create the vote session const session = AdminVoteSession.create({ voteSessionId: input.voteSessionId, leagueId: input.leagueId, adminId: input.adminId, startDate, endDate, eligibleVoters: input.eligibleVoters, }); // Save to repository await this.adminVoteSessionRepository.save(session); return { success: true, voteSessionId: input.voteSessionId, }; } catch (error) { const errorMsg = error instanceof Error ? error.message : 'Unknown error'; return { success: false, voteSessionId: input.voteSessionId, errors: [`Failed to open vote session: ${errorMsg}`], }; } } private validateInput(input: OpenAdminVoteSessionInput): string[] { const errors: string[] = []; if (!input.voteSessionId || input.voteSessionId.trim().length === 0) { errors.push('voteSessionId is required'); } if (!input.leagueId || input.leagueId.trim().length === 0) { errors.push('leagueId is required'); } if (!input.adminId || input.adminId.trim().length === 0) { errors.push('adminId is required'); } if (!input.startDate) { errors.push('startDate is required'); } if (!input.endDate) { errors.push('endDate is required'); } if (input.startDate && input.endDate) { const startDate = new Date(input.startDate); const endDate = new Date(input.endDate); if (isNaN(startDate.getTime())) { errors.push('startDate must be a valid date'); } if (isNaN(endDate.getTime())) { errors.push('endDate must be a valid date'); } if (startDate >= endDate) { errors.push('startDate must be before endDate'); } } if (!input.eligibleVoters || input.eligibleVoters.length === 0) { errors.push('At least one eligible voter is required'); } else { // Check for duplicates const uniqueVoters = new Set(input.eligibleVoters); if (uniqueVoters.size !== input.eligibleVoters.length) { errors.push('Duplicate eligible voters are not allowed'); } } return errors; } }