All files / src/modules/billing usage-aggregate.processor.ts

100% Statements 18/18
87.5% Branches 14/16
100% Functions 2/2
100% Lines 14/14

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 301x 1x   1x       1x 1x 1x     1x   1x     1x 1x 3x   2x 2x   1x          
import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Injectable, Logger } from '@nestjs/common';
import { Job } from 'bullmq';
import { PrismaService } from '@app/modules/prisma/prisma.service';
 
@Processor('usage-ledger')
@Injectable()
export class UsageAggregateProcessor extends WorkerHost {
  private readonly logger = new Logger(UsageAggregateProcessor.name);
  constructor(private readonly prisma: PrismaService) { super(); }
 
  async process(job: Job): Promise<void> {
    this.logger.log(`Running monthly usage aggregation job ${job.id}`);
    // Placeholder aggregation: ensure a row per active subscription user (extend later)
    const firstOfMonth = new Date(Date.UTC(new Date().getUTCFullYear(), new Date().getUTCMonth(), 1));
    // Example: backfill zero-usage rows for current month to ensure reporting continuity
    // @ts-ignore
    const subs = await this.prisma.client.subscription.findMany({ where: { status: 'ACTIVE' }, select: { userId: true, agencyId: true } });
    for (const s of subs) {
      if (!s.userId && !s.agencyId) continue;
      // @ts-ignore
      const existing = await this.prisma.client.usageLedger.findFirst({ where: { userId: s.userId ?? null, agencyId: s.agencyId ?? null, month: firstOfMonth } });
      if (!existing) {
        // @ts-ignore
        await this.prisma.client.usageLedger.create({ data: { userId: s.userId ?? null, agencyId: s.agencyId ?? null, subjectType: 'INIT', subjectId: null as any, month: firstOfMonth, units: 0 } });
      }
    }
  }
}