Files
gridpilot.gg/core/racing/application/use-cases/RejectSponsorshipRequestUseCase.ts
2025-12-21 00:43:42 +01:00

103 lines
3.1 KiB
TypeScript

/**
* Use Case: RejectSponsorshipRequestUseCase
*
* Allows an entity owner to reject a sponsorship request.
*/
import type { Logger, UseCaseOutputPort } from '@core/shared/application';
import { Result } from '@core/shared/application/Result';
import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode';
import type { ISponsorshipRequestRepository } from '../../domain/repositories/ISponsorshipRequestRepository';
export type RejectSponsorshipRequestInput = {
requestId: string;
respondedBy: string;
reason?: string;
};
export type RejectSponsorshipRequestResult = {
requestId: string;
status: 'rejected';
respondedAt: Date;
rejectionReason: string | undefined;
};
export type RejectSponsorshipRequestErrorCode =
| 'SPONSORSHIP_REQUEST_NOT_FOUND'
| 'SPONSORSHIP_REQUEST_NOT_PENDING'
| 'REPOSITORY_ERROR';
export class RejectSponsorshipRequestUseCase {
constructor(
private readonly sponsorshipRequestRepo: ISponsorshipRequestRepository,
private readonly logger: Logger,
private readonly output: UseCaseOutputPort<RejectSponsorshipRequestResult>,
) {}
async execute(
input: RejectSponsorshipRequestInput,
): Promise<
Result<void, ApplicationErrorCode<RejectSponsorshipRequestErrorCode, { message: string }>>
> {
const { requestId, respondedBy, reason } = input;
this.logger.debug('Executing RejectSponsorshipRequestUseCase', {
requestId,
respondedBy,
});
try {
const request = await this.sponsorshipRequestRepo.findById(requestId);
if (!request) {
this.logger.warn('Sponsorship request not found', { requestId, respondedBy });
return Result.err({
code: 'SPONSORSHIP_REQUEST_NOT_FOUND',
details: { message: 'Sponsorship request not found' },
});
}
if (!request.isPending()) {
this.logger.warn('Sponsorship request is not pending', {
requestId,
respondedBy,
status: request.status,
});
return Result.err({
code: 'SPONSORSHIP_REQUEST_NOT_PENDING',
details: { message: 'Sponsorship request is not pending' },
});
}
const rejectedRequest = request.reject(respondedBy, reason);
await this.sponsorshipRequestRepo.update(rejectedRequest);
const result: RejectSponsorshipRequestResult = {
requestId: rejectedRequest.id,
status: 'rejected',
respondedAt: rejectedRequest.respondedAt ?? new Date(),
rejectionReason: rejectedRequest.rejectionReason,
};
this.output.present(result);
this.logger.info('Sponsorship request rejected successfully', {
requestId,
respondedBy,
});
return Result.ok(undefined);
} catch (error) {
const err = error instanceof Error ? error : new Error('Unknown error');
this.logger.error('Failed to reject sponsorship request', err, {
requestId,
respondedBy,
});
return Result.err({
code: 'REPOSITORY_ERROR',
details: { message: err.message ?? 'Failed to reject sponsorship request' },
});
}
}
}