import { getWebsiteServerEnv } from '@/lib/config/env'; import { Result } from '@/lib/contracts/Result'; import { DomainError, Service } from '@/lib/contracts/services/Service'; import { ApiError } from '@/lib/gateways/api/base/ApiError'; import { getGlobalApiLogger } from '@/lib/infrastructure/ApiRequestLogger'; import { getGlobalErrorHandler } from '@/lib/infrastructure/GlobalErrorHandler'; export interface ErrorStats { totalErrors: number; errorsByType: Record; errorsByTime: Array<{ time: string; count: number }>; recentErrors: Array<{ timestamp: string; message: string; type: string; context?: unknown; }>; apiStats: { totalRequests: number; successful: number; failed: number; averageDuration: number; slowestRequests: Array<{ url: string; duration: number }>; }; environment: { mode: string; version?: string; buildTime?: string; }; } export function getErrorAnalyticsStats(): ErrorStats { return ErrorAnalyticsService.getErrorAnalyticsStats(); } export class ErrorAnalyticsService implements Service { static getErrorAnalyticsStats(): ErrorStats { const globalHandler = getGlobalErrorHandler(); const apiLogger = getGlobalApiLogger(); const errorHistory = globalHandler.getErrorHistory(); const errorStats = globalHandler.getStats(); const apiStats = apiLogger.getStats(); // Group errors by time (last 10 minutes) const timeGroups = new Map(); const now = Date.now(); const tenMinutesAgo = now - (10 * 60 * 1000); errorHistory.forEach(entry => { const entryTime = new Date(entry.timestamp).getTime(); if (entryTime >= tenMinutesAgo) { const timeKey = new Date(entry.timestamp).toLocaleTimeString(); timeGroups.set(timeKey, (timeGroups.get(timeKey) || 0) + 1); } }); const errorsByTime = Array.from(timeGroups.entries()) .map(([time, count]) => ({ time, count })) .sort((a, b) => a.time.localeCompare(b.time)); const recentErrors = errorHistory.slice(-10).reverse().map(entry => ({ timestamp: entry.timestamp, message: entry.error.message, type: entry.error instanceof ApiError ? entry.error.type : entry.error.name || 'Error', context: entry.context, })); const slowestRequests = apiLogger.getSlowestRequests(5).map(log => ({ url: log.url, duration: log.response?.duration || 0, })); const env = getWebsiteServerEnv(); return { totalErrors: errorStats.total, errorsByType: errorStats.byType, errorsByTime, recentErrors, apiStats: { totalRequests: apiStats.total, successful: apiStats.successful, failed: apiStats.failed, averageDuration: apiStats.averageDuration, slowestRequests, }, environment: { mode: env.NODE_ENV || 'unknown', version: process.env.NEXT_PUBLIC_APP_VERSION, buildTime: process.env.NEXT_PUBLIC_BUILD_TIME, }, }; } async getErrorAnalyticsStats(): Promise> { try { return Result.ok(ErrorAnalyticsService.getErrorAnalyticsStats()); } catch (error: unknown) { return Result.err({ type: 'serverError', message: (error as Error).message || 'Failed to get error analytics stats' }); } } }