From c04716006e82f3c61bf4fec08c48a48261f7ff01 Mon Sep 17 00:00:00 2001 From: Alzer Del Zeyger <75466035+Dx-Alz-xD@users.noreply.github.com> Date: Wed, 11 Nov 2026 19:32:00 +0530 Subject: [PATCH] fix(upcoming): let a single request run the daily sync two requests right after the cutoff could both see an old lastSyncedDate and both rebuild the list, leaving duplicate subjects or an empty list between the delete and the insert. claim the day with an atomic update first, and insert the new subjects before deleting the old ones --- src/lib/services/upcoming-sync.ts | 35 +++++++++++++++++++------------ 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/src/lib/services/upcoming-sync.ts b/src/lib/services/upcoming-sync.ts index 5f0f52b..5da25c2 100644 --- a/src/lib/services/upcoming-sync.ts +++ b/src/lib/services/upcoming-sync.ts @@ -86,19 +86,28 @@ export async function checkAndSyncUpcomingSlots(): Promise { .sort((a, b) => b.count - a.count) .slice(0, targetUniqueCount); - await UpcomingSlot.findOneAndUpdate( - {}, - { $set: { slot: scheduledSlot, lastSyncedDate: today } }, - { upsert: true, new: true, setDefaultsOnInsert: true }, + const todaysSlot = { $set: { slot: scheduledSlot, lastSyncedDate: today } }; + const wonTheSync = currentSlotDoc + ? await UpcomingSlot.findOneAndUpdate( + { _id: currentSlotDoc._id, lastSyncedDate: { $ne: today } }, + todaysSlot, + ) + : await UpcomingSlot.findOneAndUpdate({}, todaysSlot, { + upsert: true, + new: true, + setDefaultsOnInsert: true, + }); + + if (!wonTheSync) return; + + const freshSubjects = await UpcomingSubject.insertMany( + ranked.map((item) => ({ + subject: item.subject, + slots: item.slots, + })), ); - await UpcomingSubject.deleteMany({}); - if (ranked.length > 0) { - await UpcomingSubject.insertMany( - ranked.map((item) => ({ - subject: item.subject, - slots: item.slots, - })), - ); - } + await UpcomingSubject.deleteMany({ + _id: { $nin: freshSubjects.map((subject) => subject._id) }, + }); }