rating
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
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<OpenAdminVoteSessionOutput> {
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user