/**
* Migration: Add project task assigned email templates with modern styling
*
* Adds missing email templates for PROJECT_TASK_ASSIGNED events that were
* previously only available in dev seeds. Uses modern styling consistent
* with appointment and ticket notification templates.
*
* Templates: project-task-assigned-primary, project-task-assigned-additional
* Language: en (English only - project emails are for internal MSP users)
*/
// Template content
const templates = {
primary: {
subject: 'You have been assigned to task: {{task.name}}',
header: 'Task Assignment',
greeting: 'Hello{{#if recipientName}} {{recipientName}}{{/if}}, you have been assigned as the primary resource for a project task.',
assignedBadge: 'Primary Assignee',
taskLabel: 'Task',
projectLabel: 'Project',
dueDateLabel: 'Due Date',
assignedByLabel: 'Assigned By',
roleLabel: 'Role',
descriptionTitle: 'Description',
viewButton: 'View Task'
},
additional: {
subject: 'You have been added as additional resource to task: {{task.name}}',
header: 'Task Assignment',
greeting: 'Hello{{#if recipientName}} {{recipientName}}{{/if}}, you have been added as an additional resource for a project task.',
assignedBadge: 'Additional Resource',
taskLabel: 'Task',
projectLabel: 'Project',
dueDateLabel: 'Due Date',
assignedByLabel: 'Assigned By',
roleLabel: 'Role',
descriptionTitle: 'Description',
viewButton: 'View Task'
}
};
// Generate HTML for project task assigned (primary or additional)
function generateTaskAssignedHtml(t, isPrimary) {
const badgeColor = isPrimary
? 'rgba(16,185,129,0.12)'
: 'rgba(138,77,234,0.12)';
const badgeTextColor = isPrimary
? '#047857'
: '#5b38b0';
const headerGradient = isPrimary
? 'linear-gradient(135deg,#10b981,#059669)'
: 'linear-gradient(135deg,#8A4DEA,#40CFF9)';
const buttonColor = isPrimary ? '#10b981' : '#8A4DEA';
const footerBg = isPrimary ? '#f0fdf4' : '#f8f5ff';
const footerColor = isPrimary ? '#047857' : '#5b38b0';
return `
|
${t.header}
{{task.name}}
{{task.project}}
|
|
${t.greeting}
| ${t.taskLabel} |
{{task.name}} |
| ${t.projectLabel} |
{{task.project}} |
{{#if task.dueDate}}
| ${t.dueDateLabel} |
{{task.dueDate}} |
{{/if}}
{{#if task.assignedBy}}
| ${t.assignedByLabel} |
{{task.assignedBy}} |
{{/if}}
{{#if task.role}}
| ${t.roleLabel} |
{{task.role}} |
{{/if}}
{{#if task.description}}
${t.descriptionTitle}
{{task.description}}
{{/if}}
${t.viewButton}
|
| Powered by Alga PSA |
|
`;
}
// Generate text for project task assigned
function generateTaskAssignedText(t) {
return `${t.header}
${t.greeting}
${t.assignedBadge}
${t.taskLabel}: {{task.name}}
${t.projectLabel}: {{task.project}}
{{#if task.dueDate}}${t.dueDateLabel}: {{task.dueDate}}{{/if}}
{{#if task.assignedBy}}${t.assignedByLabel}: {{task.assignedBy}}{{/if}}
{{#if task.role}}${t.roleLabel}: {{task.role}}{{/if}}
{{#if task.description}}${t.descriptionTitle}:
{{task.description}}{{/if}}
${t.viewButton}: {{task.url}}`;
}
exports.up = async function(knex) {
console.log('Adding project task assigned email templates with modern styling...');
// Ensure Projects category exists
let projectsCategory = await knex('notification_categories')
.where({ name: 'Projects' })
.first();
if (!projectsCategory) {
[projectsCategory] = await knex('notification_categories')
.insert({
name: 'Projects',
description: 'Project-related notifications',
is_enabled: true,
is_default_enabled: true
})
.returning('*');
console.log(' Created Projects notification category');
}
// Create or get the notification subtype for project task assigned
let taskAssignedSubtype = await knex('notification_subtypes')
.where({ name: 'Project Task Assigned' })
.first();
if (!taskAssignedSubtype) {
[taskAssignedSubtype] = await knex('notification_subtypes')
.insert({
category_id: projectsCategory.id,
name: 'Project Task Assigned',
description: 'Notification when a user is assigned to a project task',
is_enabled: true,
is_default_enabled: true
})
.returning('*');
console.log(' Created notification subtype: Project Task Assigned');
}
// Upsert project-task-assigned-primary (English only)
const primary = await knex('system_email_templates')
.where({ name: 'project-task-assigned-primary', language_code: 'en' })
.first();
if (primary) {
await knex('system_email_templates')
.where({ id: primary.id })
.update({
subject: templates.primary.subject,
html_content: generateTaskAssignedHtml(templates.primary, true),
text_content: generateTaskAssignedText(templates.primary),
notification_subtype_id: taskAssignedSubtype.id,
updated_at: new Date()
});
console.log(' Updated: project-task-assigned-primary (en)');
} else {
await knex('system_email_templates').insert({
name: 'project-task-assigned-primary',
language_code: 'en',
subject: templates.primary.subject,
html_content: generateTaskAssignedHtml(templates.primary, true),
text_content: generateTaskAssignedText(templates.primary),
notification_subtype_id: taskAssignedSubtype.id,
created_at: new Date(),
updated_at: new Date()
});
console.log(' Created: project-task-assigned-primary (en)');
}
// Upsert project-task-assigned-additional (English only)
const additional = await knex('system_email_templates')
.where({ name: 'project-task-assigned-additional', language_code: 'en' })
.first();
if (additional) {
await knex('system_email_templates')
.where({ id: additional.id })
.update({
subject: templates.additional.subject,
html_content: generateTaskAssignedHtml(templates.additional, false),
text_content: generateTaskAssignedText(templates.additional),
notification_subtype_id: taskAssignedSubtype.id,
updated_at: new Date()
});
console.log(' Updated: project-task-assigned-additional (en)');
} else {
await knex('system_email_templates').insert({
name: 'project-task-assigned-additional',
language_code: 'en',
subject: templates.additional.subject,
html_content: generateTaskAssignedHtml(templates.additional, false),
text_content: generateTaskAssignedText(templates.additional),
notification_subtype_id: taskAssignedSubtype.id,
created_at: new Date(),
updated_at: new Date()
});
console.log(' Created: project-task-assigned-additional (en)');
}
console.log('Successfully added project task assigned email templates');
};
exports.down = async function(knex) {
console.log('Removing project task assigned email templates...');
await knex('system_email_templates')
.whereIn('name', ['project-task-assigned-primary', 'project-task-assigned-additional'])
.delete();
console.log('Removed project task assigned email templates');
};