Files
gridpilot.gg/core/automation/application/use-cases/ConfirmCheckoutUseCase.ts
2025-12-15 13:46:07 +01:00

88 lines
3.2 KiB
TypeScript

import { Result } from '../../../shared/result/Result';
import type { ILogger } from '../../../shared/src/logging/ILogger';
import type { CheckoutServicePort } from '../ports/CheckoutServicePort';
import type { CheckoutConfirmationPort } from '../ports/CheckoutConfirmationPort';
import { CheckoutStateEnum } from '../../domain/value-objects/CheckoutState';
interface SessionMetadata {
sessionName: string;
trackId: string;
carIds: string[];
}
export class ConfirmCheckoutUseCase {
private static readonly DEFAULT_TIMEOUT_MS = 30000;
constructor(
private readonly checkoutService: CheckoutServicePort,
private readonly confirmationPort: CheckoutConfirmationPort,
private readonly logger: ILogger,
) {}
async execute(sessionMetadata?: SessionMetadata): Promise<Result<void>> {
this.logger.debug('Executing ConfirmCheckoutUseCase', { sessionMetadata });
const infoResult = await this.checkoutService.extractCheckoutInfo();
if (infoResult.isErr()) {
this.logger.error('Failed to extract checkout info', { error: infoResult.unwrapErr() });
return Result.err(infoResult.unwrapErr());
}
const info = infoResult.unwrap();
this.logger.info('Extracted checkout info', { state: info.state.getValue(), price: info.price });
if (info.state.getValue() === CheckoutStateEnum.INSUFFICIENT_FUNDS) {
this.logger.error('Insufficient funds to complete checkout');
return Result.err(new Error('Insufficient funds to complete checkout'));
}
if (!info.price) {
this.logger.error('Could not extract price from checkout page');
return Result.err(new Error('Could not extract price from checkout page'));
}
this.logger.debug('Requesting checkout confirmation', { price: info.price, state: info.state.getValue(), sessionMetadata });
// Request confirmation via port with full checkout context
const confirmationResult = await this.confirmationPort.requestCheckoutConfirmation({
price: info.price,
state: info.state,
sessionMetadata: sessionMetadata || {
sessionName: 'Unknown Session',
trackId: 'unknown',
carIds: [],
},
timeoutMs: ConfirmCheckoutUseCase.DEFAULT_TIMEOUT_MS,
});
if (confirmationResult.isErr()) {
this.logger.error('Checkout confirmation failed', { error: confirmationResult.unwrapErr() });
return Result.err(confirmationResult.unwrapErr());
}
const confirmation = confirmationResult.unwrap();
this.logger.info('Checkout confirmation received', { confirmation });
if (confirmation.isCancelled()) {
this.logger.error('Checkout cancelled by user');
return Result.err(new Error('Checkout cancelled by user'));
}
if (confirmation.isTimeout()) {
this.logger.error('Checkout confirmation timeout');
return Result.err(new Error('Checkout confirmation timeout'));
}
this.logger.info('Proceeding with checkout');
const checkoutResult = await this.checkoutService.proceedWithCheckout();
if (checkoutResult.isOk()) {
this.logger.info('Checkout process completed successfully.');
} else {
this.logger.error('Checkout process failed', { error: checkoutResult.unwrapErr() });
}
return checkoutResult;
}
}