Files
gridpilot.gg/packages/analytics/application/use-cases/RecordEngagementUseCase.ts
2025-12-11 13:50:38 +01:00

51 lines
1.5 KiB
TypeScript

/**
* Use Case: RecordEngagementUseCase
*
* Records an engagement event when a visitor interacts with an entity.
*/
import type { AsyncUseCase } from '@gridpilot/shared/application';
import { EngagementEvent, type EngagementAction, type EngagementEntityType } from '../../domain/entities/EngagementEvent';
import type { IEngagementRepository } from '../../domain/repositories/IEngagementRepository';
export interface RecordEngagementInput {
action: EngagementAction;
entityType: EngagementEntityType;
entityId: string;
actorId?: string;
actorType: 'anonymous' | 'driver' | 'sponsor';
sessionId: string;
metadata?: Record<string, string | number | boolean>;
}
export interface RecordEngagementOutput {
eventId: string;
engagementWeight: number;
}
export class RecordEngagementUseCase
implements AsyncUseCase<RecordEngagementInput, RecordEngagementOutput> {
constructor(private readonly engagementRepository: IEngagementRepository) {}
async execute(input: RecordEngagementInput): Promise<RecordEngagementOutput> {
const eventId = `eng-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
const event = EngagementEvent.create({
id: eventId,
action: input.action,
entityType: input.entityType,
entityId: input.entityId,
actorId: input.actorId,
actorType: input.actorType,
sessionId: input.sessionId,
metadata: input.metadata,
});
await this.engagementRepository.save(event);
return {
eventId,
engagementWeight: event.getEngagementWeight(),
};
}
}