import type { Logger, UseCase, UseCaseOutputPort } from '@core/shared/application'; import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import { EngagementEvent } from '../../domain/entities/EngagementEvent'; import type { IEngagementRepository } from '../../domain/repositories/IEngagementRepository'; import type { EngagementAction, EngagementEntityType } from '../../domain/types/EngagementEvent'; export interface RecordEngagementInput { action: EngagementAction; entityType: EngagementEntityType; entityId: string; actorId?: string; actorType: 'anonymous' | 'driver' | 'sponsor'; sessionId: string; metadata?: Record; } export interface RecordEngagementOutput { eventId: string; engagementWeight: number; } export type RecordEngagementErrorCode = 'REPOSITORY_ERROR'; export class RecordEngagementUseCase implements UseCase { constructor( private readonly engagementRepository: IEngagementRepository, private readonly logger: Logger, private readonly output: UseCaseOutputPort, ) {} async execute(input: RecordEngagementInput): Promise>> { try { const engagementEvent = EngagementEvent.create({ id: crypto.randomUUID(), action: input.action, entityType: input.entityType, entityId: input.entityId, actorType: input.actorType, sessionId: input.sessionId, ...(input.actorId !== undefined && { actorId: input.actorId }), ...(input.metadata !== undefined && { metadata: input.metadata }), }); await this.engagementRepository.save(engagementEvent); const resultModel: RecordEngagementOutput = { eventId: engagementEvent.id, engagementWeight: engagementEvent.getEngagementWeight(), }; this.output.present(resultModel); this.logger.info('Engagement event recorded', { engagementId: engagementEvent.id, action: input.action, entityId: input.entityId, entityType: input.entityType, }); return Result.ok(undefined); } catch (error) { const err = error as Error; this.logger.error('Failed to record engagement event', err, { input }); return Result.err({ code: 'REPOSITORY_ERROR', details: { message: err.message ?? 'Failed to record engagement event' }, }); } } }