import { err, ok, Result } from 'src/shared/core/Result'; import { UseCase } from 'src/shared/core/UseCase'; import { IUserStatsRepository, UserGrowthStatsDTO, UserEngagementStatsDTO, DailyActivityStatsDTO, ContentBreakdownStatsDTO, UserStatType, TimeInterval, } from '../../../domain/IUserStatsRepository'; export interface GetUserStatsQuery { statType: UserStatType; interval?: TimeInterval; limit?: number; includeTimeSeries?: boolean; // For engagement stats // Future parameters can be added here for other stat types } export type GetUserStatsResult = | UserGrowthStatsDTO | UserEngagementStatsDTO | DailyActivityStatsDTO | ContentBreakdownStatsDTO; // Union type for different stat types export class ValidationError extends Error { constructor(message: string) { super(message); this.name = 'ValidationError'; } } export class GetUserStatsUseCase implements UseCase> { constructor(private userStatsRepository: IUserStatsRepository) {} async execute(query: GetUserStatsQuery): Promise> { try { // Validate query parameters if (!query.statType) { return err(new ValidationError('Stat type is required')); } // Route to appropriate repository method based on stat type switch (query.statType) { case 'growth': return await this.handleGrowthStats(query); case 'engagement': return await this.handleEngagementStats(query); case 'activity': return await this.handleActivityStats(query); case 'breakdown': return await this.handleBreakdownStats(query); default: return err( new ValidationError(`Invalid stat type: ${query.statType}`), ); } } catch (error) { return err( new Error( `Failed to retrieve user stats: ${error instanceof Error ? error.message : 'Unknown error'}`, ), ); } } private async handleGrowthStats( query: GetUserStatsQuery, ): Promise> { // Apply defaults const interval = query.interval || 'day'; const limit = query.limit || 30; // Validate parameters if (!['day', 'week', 'month'].includes(interval)) { return err(new ValidationError(`Invalid interval: ${interval}`)); } if (limit < 1 || limit > 365) { return err(new ValidationError('Limit must be between 1 and 365')); } try { const stats = await this.userStatsRepository.getUserGrowthStats({ interval, limit, }); return ok(stats); } catch (error) { return err( new Error( `Failed to retrieve growth stats: ${error instanceof Error ? error.message : 'Unknown error'}`, ), ); } } private async handleEngagementStats( query: GetUserStatsQuery, ): Promise> { // Apply defaults const interval = query.interval || 'day'; const limit = query.limit || 30; const includeTimeSeries = query.includeTimeSeries || false; // Validate parameters if (interval && !['day', 'week', 'month'].includes(interval)) { return err(new ValidationError(`Invalid interval: ${interval}`)); } if (limit < 1 || limit > 365) { return err(new ValidationError('Limit must be between 1 and 365')); } try { const stats = await this.userStatsRepository.getUserEngagementStats({ interval, limit, includeTimeSeries, }); return ok(stats); } catch (error) { return err( new Error( `Failed to retrieve engagement stats: ${error instanceof Error ? error.message : 'Unknown error'}`, ), ); } } private async handleActivityStats( query: GetUserStatsQuery, ): Promise> { // Apply defaults const interval = query.interval || 'day'; const limit = query.limit || 30; // Validate parameters if (!['day', 'week', 'month'].includes(interval)) { return err(new ValidationError(`Invalid interval: ${interval}`)); } if (limit < 1 || limit > 365) { return err(new ValidationError('Limit must be between 1 and 365')); } try { const stats = await this.userStatsRepository.getDailyActivityStats({ interval, limit, }); return ok(stats); } catch (error) { return err( new Error( `Failed to retrieve activity stats: ${error instanceof Error ? error.message : 'Unknown error'}`, ), ); } } private async handleBreakdownStats( query: GetUserStatsQuery, ): Promise> { // Apply defaults const interval = query.interval || 'day'; const limit = query.limit || 30; // Validate parameters if (!['day', 'week', 'month'].includes(interval)) { return err(new ValidationError(`Invalid interval: ${interval}`)); } if (limit < 1 || limit > 365) { return err(new ValidationError('Limit must be between 1 and 365')); } try { const stats = await this.userStatsRepository.getContentBreakdownStats({ interval, limit, }); return ok(stats); } catch (error) { return err( new Error( `Failed to retrieve breakdown stats: ${error instanceof Error ? error.message : 'Unknown error'}`, ), ); } } }