// src/services/analyticsService.server.ts import type { Job } from 'bullmq'; import { logger as globalLogger } from './logger.server'; import type { AnalyticsJobData, WeeklyAnalyticsJobData } from '../types/job-data'; /** * A service class to encapsulate business logic for analytics-related background jobs. */ export class AnalyticsService { /** * Processes a job to generate a daily analytics report. * This is currently a mock implementation. * @param job The BullMQ job object. */ async processDailyReportJob(job: Job) { const { reportDate } = job.data; const logger = globalLogger.child({ jobId: job.id, jobName: job.name, reportDate, }); logger.info(`Picked up daily analytics job.`); try { // This is mock logic, but we keep it in the service if (reportDate === 'FAIL') { throw new Error('This is a test failure for the analytics job.'); } // Simulate work await new Promise((resolve) => setTimeout(resolve, 10000)); logger.info(`Successfully generated report for ${reportDate}.`); return { status: 'success', reportDate }; } catch (error) { const wrappedError = error instanceof Error ? error : new Error(String(error)); logger.error( { err: wrappedError, attemptsMade: job.attemptsMade, }, `Daily analytics job failed.`, ); throw wrappedError; } } /** * Processes a job to generate a weekly analytics report. * This is currently a mock implementation. * @param job The BullMQ job object. */ async processWeeklyReportJob(job: Job) { const { reportYear, reportWeek } = job.data; const logger = globalLogger.child({ jobId: job.id, jobName: job.name, reportYear, reportWeek, }); logger.info(`Picked up weekly analytics job.`); try { // Mock logic await new Promise((resolve) => setTimeout(resolve, 30000)); logger.info(`Successfully generated weekly report for week ${reportWeek}, ${reportYear}.`); return { status: 'success', reportYear, reportWeek }; } catch (error) { const wrappedError = error instanceof Error ? error : new Error(String(error)); logger.error( { err: wrappedError, attemptsMade: job.attemptsMade }, `Weekly analytics job failed.`, ); throw wrappedError; } } } export const analyticsService = new AnalyticsService();