rating
This commit is contained in:
99
core/identity/application/use-cases/CastAdminVoteUseCase.ts
Normal file
99
core/identity/application/use-cases/CastAdminVoteUseCase.ts
Normal file
@@ -0,0 +1,99 @@
|
||||
import { IAdminVoteSessionRepository } from '../../domain/repositories/IAdminVoteSessionRepository';
|
||||
import { CastAdminVoteInput, CastAdminVoteOutput } from '../dtos/AdminVoteSessionDto';
|
||||
|
||||
/**
|
||||
* Use Case: CastAdminVoteUseCase
|
||||
*
|
||||
* Casts a vote in an active admin vote session.
|
||||
* Follows CQRS Light: command side operation.
|
||||
*
|
||||
* Per plans section 7.1.1
|
||||
*/
|
||||
export class CastAdminVoteUseCase {
|
||||
constructor(
|
||||
private readonly adminVoteSessionRepository: IAdminVoteSessionRepository,
|
||||
) {}
|
||||
|
||||
async execute(input: CastAdminVoteInput): Promise<CastAdminVoteOutput> {
|
||||
try {
|
||||
// Validate input
|
||||
const errors = this.validateInput(input);
|
||||
if (errors.length > 0) {
|
||||
return {
|
||||
success: false,
|
||||
voteSessionId: input.voteSessionId,
|
||||
voterId: input.voterId,
|
||||
errors,
|
||||
};
|
||||
}
|
||||
|
||||
// Load the vote session
|
||||
const session = await this.adminVoteSessionRepository.findById(input.voteSessionId);
|
||||
if (!session) {
|
||||
return {
|
||||
success: false,
|
||||
voteSessionId: input.voteSessionId,
|
||||
voterId: input.voterId,
|
||||
errors: ['Vote session not found'],
|
||||
};
|
||||
}
|
||||
|
||||
// Check if session is open
|
||||
const voteTime = input.votedAt ? new Date(input.votedAt) : new Date();
|
||||
if (!session.isVotingWindowOpen(voteTime)) {
|
||||
return {
|
||||
success: false,
|
||||
voteSessionId: input.voteSessionId,
|
||||
voterId: input.voterId,
|
||||
errors: ['Vote session is not open for voting'],
|
||||
};
|
||||
}
|
||||
|
||||
// Cast the vote
|
||||
session.castVote(input.voterId, input.positive, voteTime);
|
||||
|
||||
// Save updated session
|
||||
await this.adminVoteSessionRepository.save(session);
|
||||
|
||||
return {
|
||||
success: true,
|
||||
voteSessionId: input.voteSessionId,
|
||||
voterId: input.voterId,
|
||||
};
|
||||
|
||||
} catch (error) {
|
||||
const errorMsg = error instanceof Error ? error.message : 'Unknown error';
|
||||
return {
|
||||
success: false,
|
||||
voteSessionId: input.voteSessionId,
|
||||
voterId: input.voterId,
|
||||
errors: [`Failed to cast vote: ${errorMsg}`],
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private validateInput(input: CastAdminVoteInput): string[] {
|
||||
const errors: string[] = [];
|
||||
|
||||
if (!input.voteSessionId || input.voteSessionId.trim().length === 0) {
|
||||
errors.push('voteSessionId is required');
|
||||
}
|
||||
|
||||
if (!input.voterId || input.voterId.trim().length === 0) {
|
||||
errors.push('voterId is required');
|
||||
}
|
||||
|
||||
if (typeof input.positive !== 'boolean') {
|
||||
errors.push('positive must be a boolean value');
|
||||
}
|
||||
|
||||
if (input.votedAt) {
|
||||
const votedAt = new Date(input.votedAt);
|
||||
if (isNaN(votedAt.getTime())) {
|
||||
errors.push('votedAt must be a valid date if provided');
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user