All files / src/services analyticsService.server.ts

78.84% Statements 82/104
76.47% Branches 13/17
100% Functions 6/6
77.21% Lines 61/79

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 792x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 3x 3x 2x 2x 2x 2x 1x 3x 1x 3x 1x 3x 1x 1x 1x 3x 2x 2x 1x 2x 2x             2x           2x 2x 2x 2x 3x 3x 1x 1x 1x 1x 1x 1x 3x 1x 3x 1x 4x 3x 3x 1x 2x 2x       2x         29x
// 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<AnalyticsJobData>) {
    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<WeeklyAnalyticsJobData>) {
    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();