Files
gridpilot.gg/core/racing/application/use-cases/SubmitProtestDefenseUseCase.ts
2025-12-16 21:05:01 +01:00

48 lines
1.6 KiB
TypeScript

/**
* Application Use Case: SubmitProtestDefenseUseCase
*
* Allows the accused driver to submit their defense statement for a protest.
*/
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { IProtestRepository } from '../../domain/repositories/IProtestRepository';
export interface SubmitProtestDefenseCommand {
protestId: string;
driverId: string;
statement: string;
videoUrl?: string;
}
type SubmitProtestDefenseErrorCode = 'PROTEST_NOT_FOUND' | 'NOT_ACCUSED_DRIVER' | 'DEFENSE_CANNOT_BE_SUBMITTED';
export class SubmitProtestDefenseUseCase {
constructor(
private readonly protestRepository: IProtestRepository,
) {}
async execute(command: SubmitProtestDefenseCommand): Promise<Result<{ protestId: string }, ApplicationErrorCode<SubmitProtestDefenseErrorCode>>> {
// Get the protest
const protest = await this.protestRepository.findById(command.protestId);
if (!protest) {
return Result.err({ code: 'PROTEST_NOT_FOUND' });
}
// Verify the submitter is the accused driver
if (protest.accusedDriverId !== command.driverId) {
return Result.err({ code: 'NOT_ACCUSED_DRIVER' });
}
// Check if defense can be submitted
if (!protest.canSubmitDefense()) {
return Result.err({ code: 'DEFENSE_CANNOT_BE_SUBMITTED' });
}
// Submit defense
const updatedProtest = protest.submitDefense(command.statement, command.videoUrl);
await this.protestRepository.update(updatedProtest);
return Result.ok({ protestId: protest.id });
}
}