@@ -502,15 +502,26 @@ async function renderTenancyEmails(workerId: string, tenancyId: string, group: E
502502}
503503
504504async function queueReadyEmails ( ) : Promise < { queuedCount : number } > {
505- // Queue emails that are ready to send:
506- // - Fresh emails: scheduledAt has passed and no retry pending
507- // - Retry emails: both scheduledAt AND nextSendRetryAt have passed
508- //
505+ // Queue emails that are ready to send. Split into two queries for clarity and index usage.
509506 // We always require scheduledAt <= NOW() to respect the original scheduling intent.
510- // nextSendRetryAt should not bypass scheduledAt (e.g., if data is corrupted or manually edited).
511- //
507+
508+ // Query 1: Fresh emails (scheduledAt has passed, no retry pending)
509+ const freshEmails = await globalPrismaClient . $queryRaw < { id : string } [ ] > `
510+ UPDATE "EmailOutbox"
511+ SET "isQueued" = TRUE
512+ WHERE "isQueued" = FALSE
513+ AND "isPaused" = FALSE
514+ AND "skippedReason" IS NULL
515+ AND "finishedRenderingAt" IS NOT NULL
516+ AND "renderedHtml" IS NOT NULL
517+ AND "scheduledAt" <= NOW()
518+ AND "nextSendRetryAt" IS NULL
519+ RETURNING "id";
520+ ` ;
521+
522+ // Query 2: Retry emails (both scheduledAt AND nextSendRetryAt have passed)
512523 // Clear nextSendRetryAt when queuing so the email is in a clean "queued" state.
513- const res = await globalPrismaClient . $queryRaw < { id : string } [ ] > `
524+ const retryEmails = await globalPrismaClient . $queryRaw < { id : string } [ ] > `
514525 UPDATE "EmailOutbox"
515526 SET "isQueued" = TRUE, "nextSendRetryAt" = NULL
516527 WHERE "isQueued" = FALSE
@@ -519,17 +530,12 @@ async function queueReadyEmails(): Promise<{ queuedCount: number }> {
519530 AND "finishedRenderingAt" IS NOT NULL
520531 AND "renderedHtml" IS NOT NULL
521532 AND "scheduledAt" <= NOW()
522- AND (
523- -- Fresh emails: no retry pending
524- "nextSendRetryAt" IS NULL
525- OR
526- -- Retry emails: retry time has passed
527- "nextSendRetryAt" <= NOW()
528- )
533+ AND "nextSendRetryAt" <= NOW()
529534 RETURNING "id";
530535 ` ;
536+
531537 return {
532- queuedCount : res . length ,
538+ queuedCount : freshEmails . length + retryEmails . length ,
533539 } ;
534540}
535541
0 commit comments