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 | 12x 12x 12x 12x 12x 12x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | import { Processor, WorkerHost } from '@nestjs/bullmq';
import { Job } from 'bullmq';
import { Injectable, Logger } from '@nestjs/common';
import { PrismaService } from '@app/modules/prisma/prisma.service';
import { InjectQueue } from '@nestjs/bullmq';
import { Queue } from 'bullmq';
interface ExpiredPayload { requestId: number; bidId: number; rank: number }
@Processor('quick-rent:payment-window-expired')
@Injectable()
export class QuickRentPaymentWindowExpiredProcessor extends WorkerHost {
private readonly logger = new Logger(QuickRentPaymentWindowExpiredProcessor.name);
constructor(
private readonly prisma: PrismaService,
@InjectQueue('quick-rent:payment-window-expired') private readonly selfQueue: Queue,
@InjectQueue('notifications') private readonly notificationsQueue: Queue
) { super(); }
async process(job: Job<ExpiredPayload>): Promise<void> {
const { requestId, bidId, rank } = job.data;
// Get the bid to find bidder and agency info
const bid = await this.prisma.client.quickRentBid.findUnique({ where: { id: bidId } });
Iif (!bid) return;
const access = await this.prisma.client.quickRentLeadAccess.findFirst({
where: {
requestId,
bidderId: bid.bidderId ?? undefined,
agencyId: bid.agencyId ?? undefined
}
});
Iif (access && access.paidAt) {
return;
}
// Find next highest bidder
const bids = await this.prisma.client.quickRentBid.findMany({
where: { requestId },
orderBy: [{ amountCents: 'desc' }, { createdAt: 'asc' }]
});
const currentIndex = bids.findIndex((b: { id: number }) => b.id === bidId);
const next = bids[currentIndex + 1];
if (!next) {
await this.prisma.client.quickRentRequest.update({
where: { id: requestId },
data: { status: 'EXPIRED' }
});
return;
}
// Notify next bidder with second-chance offer
await this.notificationsQueue.add('send', {
type: 'QUICK_RENT_SECOND_CHANCE',
payload: { requestId, bidId: next.id }
});
// Re-enqueue self with next bidder and same 1-hour delay
await this.selfQueue.add('check', {
requestId,
bidId: next.id,
rank: rank + 1
}, { delay: 60 * 60 * 1000 });
}
}
|