feat(crm): Project Overview phase 3 — persist sent email HTML

processEmailQueue now stores the actual rendered HTML in email_queue
.rendered_html on a successful send (sendTemplateEmail returns it). Guarded
by hasColumnCached so installs without migration 119 just skip it; never
blocks the send. Powers the cockpit's exact-sent email preview.
This commit is contained in:
Luca
2026-06-06 04:00:16 +02:00
parent eb263137b9
commit 874c91f944
+16 -8
View File
@@ -763,7 +763,9 @@ async function sendTemplateEmail(to, templateKey, variables) {
});
logger.info(`Email sent successfully: ${info.messageId} (${language})`);
return { success: true, messageId: info.messageId, language };
// Return the rendered HTML so the queue processor can persist the ACTUAL
// sent body (email_queue.rendered_html) for the Project Overview preview.
return { success: true, messageId: info.messageId, language, html: htmlBody };
} catch (error) {
logger.error('Error sending template email:', error);
throw error;
@@ -839,19 +841,25 @@ async function processEmailQueue({ ignoreSchedule = false, limit = 10 } = {}) {
? JSON.parse(email.email_data || '{}')
: email.email_data || {};
await sendTemplateEmail(
const sendResult = await sendTemplateEmail(
email.recipient_email,
email.email_type,
emailData
);
// Mark as sent
// Mark as sent, persisting the actual rendered HTML for the Project
// Overview email preview (guarded — older installs without migration
// 119 just skip it).
const sentUpdate = { status: 'sent', sent_at: new Date() };
try {
const { hasColumnCached } = require('../utils/schemaCache');
if (sendResult && sendResult.html && await hasColumnCached('email_queue', 'rendered_html')) {
sentUpdate.rendered_html = sendResult.html;
}
} catch (_) { /* best-effort — never block the send on the preview */ }
await db('email_queue')
.where('id', email.id)
.update({
status: 'sent',
sent_at: new Date()
});
.update(sentUpdate);
result.sent += 1;
logger.info(`Email ${email.id} sent successfully`);