feat(usage): distinguish real edits and template delivery with v5 consent (#1339)
* feat(usage): distinguish real edits and template delivery with v5 consent * fix(usage): exclude queued test messages and count reorders as edits - queueEmail carries usageEligible: false into email_data and the queue processor passes it on, so the dev tools' send-test-email no longer records email_template_delivery once the worker sends it. - event-types/reorder and categories/reorder-global compare the persisted order before and after and record the v5 edit markers only when it changed, matching the display_order edit already counted on PUT. - normalized() builds arrays with Array.from so a row array from the sqlite binding compares equal under Jest's separate realm. * fix(usage): cover per-gallery category order and workflow test runs - categories/reorder records category_editing when an event's override changes; reorder/:eventId records it when an override was actually removed. - send_email and the collections handoff pass usageEligible: false for a workflow test run (engine.testRun sets __test), so a non-dry test send is not counted as template delivery. --------- Co-authored-by: Paul Nothaft <[email protected]>
This commit is contained in:
co-authored by
Paul Nothaft
parent
69754f8a2c
commit
5c1e38d921
@@ -906,7 +906,7 @@ async function buildSignatureTextFor(language) {
|
||||
}
|
||||
}
|
||||
|
||||
async function sendTemplateEmail(to, templateKey, variables) {
|
||||
async function sendTemplateEmail(to, templateKey, variables, { usageEligible = true } = {}) {
|
||||
try {
|
||||
// Webhook transport (#1225) replaces SMTP entirely when configured, so an
|
||||
// instance using it has no SMTP settings to initialise and must not be
|
||||
@@ -987,6 +987,17 @@ async function sendTemplateEmail(to, templateKey, variables) {
|
||||
? await emailWebhookTransport.send(mail)
|
||||
: await transporter.sendMail(mail);
|
||||
|
||||
// Transport acceptance is the measured event, not rendering or inbox
|
||||
// delivery. The service accepts only the fixed bit under confirmed v5
|
||||
// consent; marker failure must never retry an already-sent message.
|
||||
if (usageEligible && (viaWebhook || info.accepted?.length > 0)) {
|
||||
try {
|
||||
await require('./productUsageService').markUsed(['email_template_delivery']);
|
||||
} catch {
|
||||
logger.warn('Product usage mail marker could not be recorded');
|
||||
}
|
||||
}
|
||||
|
||||
logger.info(`Email sent successfully: ${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.
|
||||
@@ -1275,7 +1286,8 @@ async function processEmailQueue({ ignoreSchedule = false, limit = 10, onlyId =
|
||||
sendResult = await sendTemplateEmail(
|
||||
email.recipient_email,
|
||||
email.email_type,
|
||||
emailData
|
||||
emailData,
|
||||
{ usageEligible: emailData.__usageEligible !== false }
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1436,6 +1448,9 @@ async function queueEmail(eventId, recipientEmail, emailType, emailData, options
|
||||
try {
|
||||
// Add eventId to emailData for language detection
|
||||
emailData.eventId = eventId;
|
||||
// An explicit test message (dev tools' send-test-email) must not count as
|
||||
// template delivery when the queue processor sends it later.
|
||||
if (options.usageEligible === false) emailData.__usageEligible = false;
|
||||
const row = {
|
||||
event_id: eventId,
|
||||
recipient_email: recipientEmail,
|
||||
|
||||
Reference in New Issue
Block a user