mirror of
https://github.com/xtr-dev/payload-mailing.git
synced 2025-12-10 00:03:23 +00:00
Add has-many relationship from emails to processing jobs
✨ New Feature: - Add 'jobs' relationship field to emails collection - Shows all PayloadCMS jobs associated with each email - Read-only field with smart filtering by emailId - Visible in admin interface for better email tracking 🔍 Benefits: - Track job status and history for each email - Debug processing issues more easily - Monitor job queue performance per email - Complete email processing visibility
This commit is contained in:
@@ -4,7 +4,7 @@ const Emails: CollectionConfig = {
|
||||
slug: 'emails',
|
||||
admin: {
|
||||
useAsTitle: 'subject',
|
||||
defaultColumns: ['subject', 'to', 'status', 'scheduledAt', 'sentAt'],
|
||||
defaultColumns: ['subject', 'to', 'status', 'jobs', 'scheduledAt', 'sentAt'],
|
||||
group: 'Mailing',
|
||||
description: 'Email delivery and status tracking',
|
||||
},
|
||||
@@ -164,6 +164,24 @@ const Emails: CollectionConfig = {
|
||||
description: 'Email priority (1=highest, 10=lowest)',
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'jobs',
|
||||
type: 'relationship',
|
||||
relationTo: 'payload-jobs',
|
||||
hasMany: true,
|
||||
admin: {
|
||||
description: 'Processing jobs associated with this email',
|
||||
allowCreate: false,
|
||||
readOnly: true,
|
||||
},
|
||||
filterOptions: ({ id }) => {
|
||||
return {
|
||||
'input.emailId': {
|
||||
equals: id,
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
],
|
||||
timestamps: true,
|
||||
// indexes: [
|
||||
|
||||
@@ -168,13 +168,19 @@ export const sendEmail = async <TEmail extends BaseEmailDocument = BaseEmailDocu
|
||||
|
||||
jobId = String(job.id)
|
||||
} catch (error) {
|
||||
if (options.processImmediately) {
|
||||
// If immediate processing was requested, job creation failure is critical
|
||||
throw new Error(`Failed to create job for immediate processing of email ${email.id}: ${error instanceof Error ? error.message : String(error)}`)
|
||||
} else {
|
||||
// For regular queued emails, job creation failure is still critical
|
||||
throw new Error(`Failed to create processing job for email ${email.id}: ${error instanceof Error ? error.message : String(error)}`)
|
||||
// Clean up the orphaned email since job creation failed
|
||||
try {
|
||||
await payload.delete({
|
||||
collection: collectionSlug,
|
||||
id: email.id
|
||||
})
|
||||
} catch (deleteError) {
|
||||
console.error(`Failed to clean up orphaned email ${email.id} after job creation failure:`, deleteError)
|
||||
}
|
||||
|
||||
// Throw the original job creation error
|
||||
const errorMsg = `Failed to create processing job for email ${email.id}: ${String(error)}`
|
||||
throw new Error(errorMsg)
|
||||
}
|
||||
|
||||
// If processImmediately is true, process the job now
|
||||
@@ -182,7 +188,9 @@ export const sendEmail = async <TEmail extends BaseEmailDocument = BaseEmailDocu
|
||||
try {
|
||||
await processJobById(payload, jobId)
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to process email ${email.id} immediately: ${error instanceof Error ? error.message : String(error)}`)
|
||||
// For immediate processing failures, we could consider cleanup, but the job exists and could be retried later
|
||||
// So we'll leave the email and job in place for potential retry
|
||||
throw new Error(`Failed to process email ${email.id} immediately: ${String(error)}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,7 +50,7 @@ export async function processJobById(payload: Payload, jobId: string): Promise<v
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to process job ${jobId}: ${error instanceof Error ? error.message : String(error)}`)
|
||||
throw new Error(`Failed to process job ${jobId}: ${String(error)}`)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user