From 0d7b50d1a8b9c643b911ddc8f43b31188a57ff5e Mon Sep 17 00:00:00 2001 From: sonusharma6-dsa Date: Fri, 5 Jun 2026 00:04:59 +0530 Subject: [PATCH 1/2] test: resolve Vitest constructor TypeError in PDFParse mock --- .../module/ats/__tests__/ats.service.test.ts | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/server/src/module/ats/__tests__/ats.service.test.ts b/server/src/module/ats/__tests__/ats.service.test.ts index 5e9148aee..1dc24c963 100644 --- a/server/src/module/ats/__tests__/ats.service.test.ts +++ b/server/src/module/ats/__tests__/ats.service.test.ts @@ -106,11 +106,12 @@ function mockCacheMiss() { function mockValidPdf(text = VALID_RESUME_TEXT) { vi.mocked(PDFParse).mockImplementation( - () => - ({ + function () { + return { getText: vi.fn().mockResolvedValue({ text }), destroy: vi.fn().mockResolvedValue(undefined), - }) as any, + } as any; + } ); } @@ -183,11 +184,12 @@ describe("AtsService", () => { mockUserOwnsResume(); mockCacheMiss(); vi.mocked(PDFParse).mockImplementation( - () => - ({ + function () { + return { getText: vi.fn().mockResolvedValue({ text: "too short" }), destroy: vi.fn().mockResolvedValue(undefined), - }) as any, + } as any; + } ); await expect( @@ -466,11 +468,12 @@ describe("AtsService", () => { it("throws when PDF text extraction yields insufficient content", async () => { mockUserOwnsResume(); vi.mocked(PDFParse).mockImplementation( - () => - ({ + function () { + return { getText: vi.fn().mockResolvedValue({ text: "tiny" }), destroy: vi.fn().mockResolvedValue(undefined), - }) as any, + } as any; + } ); await expect( From 9384a09544e0c553638f0958ffd92bbbd6ec18b2 Mon Sep 17 00:00:00 2001 From: sonusharma6-dsa Date: Thu, 4 Jun 2026 23:24:21 +0530 Subject: [PATCH 2/2] fix: resolve issue #1385 - Invalidate Profile Caches on Subscription Expiration Cron --- server/src/cron/subscription-expiry.ts | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/server/src/cron/subscription-expiry.ts b/server/src/cron/subscription-expiry.ts index e1c6f8e65..fea46dfce 100644 --- a/server/src/cron/subscription-expiry.ts +++ b/server/src/cron/subscription-expiry.ts @@ -12,21 +12,37 @@ let cronJob: cron.ScheduledTask | null = null; async function expireSubscriptions(): Promise { const now = new Date(); - const result = await prisma.user.updateMany({ + // Find users whose subscriptions are expiring + const expiringUsers = await prisma.user.findMany({ where: { subscriptionStatus: "ACTIVE", subscriptionEndDate: { lt: now }, subscriptionPlan: { in: ["MONTHLY", "YEARLY"] }, }, + select: { id: true }, + }); + + if (expiringUsers.length === 0) return; + + const userIds = expiringUsers.map((u) => u.id); + + // Update them in bulk + await prisma.user.updateMany({ + where: { id: { in: userIds } }, data: { subscriptionStatus: "EXPIRED", subscriptionPlan: "FREE", }, }); - if (result.count > 0) { - console.log(`[Cron] Expired ${result.count} subscription(s)`); + // Invalidate cache for each user + const { cacheDel } = await import("../utils/cache.js"); + for (const userId of userIds) { + await cacheDel(`profile:me:${userId}`).catch(() => {}); + await cacheDel(`profile:public:${userId}`).catch(() => {}); } + + console.log(`[Cron] Expired ${userIds.length} subscription(s) and cleared profile cache.`); } export function startSubscriptionExpiryCron(): void {