252 lines
12 KiB
TypeScript
252 lines
12 KiB
TypeScript
import db from '../database/models/index.js';
|
|
import fs from 'fs';
|
|
import path from 'path';
|
|
import { fileURLToPath } from 'url';
|
|
import { Op } from 'sequelize';
|
|
|
|
const __filename = fileURLToPath(import.meta.url);
|
|
const __dirname = path.dirname(__filename);
|
|
|
|
const seedTemplates = async () => {
|
|
try {
|
|
const templatesDir = path.join(__dirname, '../emailtemplates');
|
|
|
|
// Legacy rows used lowercase codes; remove to avoid duplicate keys after rename
|
|
await db.EmailTemplate.destroy({
|
|
where: { templateCode: { [Op.in]: ['opportunity', 'non_opportunity'] } }
|
|
});
|
|
|
|
const templates = [
|
|
{
|
|
templateCode: 'OPPORTUNITY',
|
|
description: 'Opportunity link for dealership application assessment',
|
|
subject: 'Action Required: Royal Enfield Dealership Opportunity',
|
|
fileName: 'opportunity.html',
|
|
placeholders: ['applicantName', 'location']
|
|
},
|
|
{
|
|
templateCode: 'NON_OPPORTUNITY',
|
|
description: 'Regret email for non-opportunity applications',
|
|
subject: 'Update on your Royal Enfield Dealership Application',
|
|
fileName: 'non_opportunity.html',
|
|
placeholders: ['applicantName', 'location']
|
|
},
|
|
{
|
|
templateCode: 'INTERVIEW_SCHEDULED',
|
|
description: 'Notification for scheduled interview',
|
|
subject: 'Interview Scheduled: {{applicationId}}',
|
|
fileName: 'interview_scheduled.html',
|
|
placeholders: ['name', 'applicationId', 'level', 'dateTime', 'type', 'location']
|
|
},
|
|
{
|
|
templateCode: 'USER_ASSIGNED',
|
|
description: 'Notification for user assignment to an application',
|
|
subject: 'New Application Assignment: {{applicationId}}',
|
|
fileName: 'user_assigned.html',
|
|
placeholders: ['userName', 'applicationId', 'dealerName', 'participantType']
|
|
},
|
|
{
|
|
templateCode: 'QUESTIONNAIRE_SUBMITTED',
|
|
description: 'Acknowledgement for questionnaire submission',
|
|
subject: 'Questionnaire Submitted Successfully: {{applicationId}}',
|
|
fileName: 'questionnaire_submitted.html',
|
|
placeholders: ['applicantName', 'location', 'applicationId']
|
|
},
|
|
{
|
|
templateCode: 'APPLICANT_SHORTLISTED',
|
|
description: 'Notification for shortlisted applicants',
|
|
subject: 'Congratulations! You are Shortlisted: {{applicationId}}',
|
|
fileName: 'applicant_shortlisted.html',
|
|
placeholders: ['applicantName', 'location', 'applicationId']
|
|
},
|
|
{
|
|
templateCode: 'LOI_ISSUED',
|
|
description: 'Notification when Letter of Intent is issued',
|
|
subject: 'Letter of Intent (LOI) Issued: {{applicationId}}',
|
|
fileName: 'loi_issued.html',
|
|
placeholders: ['applicantName', 'applicationId']
|
|
},
|
|
{
|
|
templateCode: 'LOA_ISSUED',
|
|
description: 'Notification when Letter of Appointment is issued',
|
|
subject: 'Letter of Appointment (LOA) Issued: {{applicationId}}',
|
|
fileName: 'loa_issued.html',
|
|
placeholders: ['applicantName', 'applicationId', 'dealerCode']
|
|
},
|
|
{
|
|
templateCode: 'DEALER_CODE_READY',
|
|
description: 'Notification when SAP Dealer Codes are generated',
|
|
subject: 'SAP Dealer Codes Readiness for {{applicationId}}',
|
|
fileName: 'dealer_code_ready.html',
|
|
placeholders: ['applicantName', 'applicationId', 'salesCode', 'serviceCode']
|
|
},
|
|
{
|
|
templateCode: 'ONBOARDING_STATUS_UPDATE',
|
|
description: 'General onboarding status changes (excluding LOI/LOA/dealer-code specific mails)',
|
|
subject: 'Onboarding Status Update: {{status}} — {{applicationId}}',
|
|
fileName: 'onboarding_status_update.html',
|
|
placeholders: ['applicantName', 'applicationId', 'status', 'reason', 'salesCode', 'serviceCode']
|
|
},
|
|
{
|
|
templateCode: 'RESIGNATION_SUBMITTED',
|
|
description: 'Notification for new Resignation submission',
|
|
subject: 'New Resignation Request: {{resignationId}}',
|
|
fileName: 'resignation_submitted.html',
|
|
placeholders: ['dealerName', 'resignationId', 'lwd']
|
|
},
|
|
{
|
|
templateCode: 'RESIGNATION_APPROVED',
|
|
description: 'Notification when Resignation is approved',
|
|
subject: 'Resignation Request Approved: {{resignationId}}',
|
|
fileName: 'resignation_approved.html',
|
|
placeholders: ['dealerName', 'resignationId', 'lwd']
|
|
},
|
|
{
|
|
templateCode: 'TERMINATION_SCN_ISSUED',
|
|
description: 'Notification for Show Cause Notice issuance',
|
|
subject: 'URGENT: Show Cause Notice Issued: {{terminationId}}',
|
|
fileName: 'termination_scn.html',
|
|
placeholders: ['dealerName', 'terminationId', 'deadline']
|
|
},
|
|
{
|
|
templateCode: 'WORKNOTE_NOTIFICATION',
|
|
description: 'Notification for new work note or update',
|
|
subject: 'New Update on Application: {{applicationId}}',
|
|
fileName: 'worknote_notification.html',
|
|
placeholders: ['userName', 'applicationId', 'dealerName', 'message']
|
|
},
|
|
{
|
|
templateCode: 'GENERIC_NOTIFICATION',
|
|
description: 'Standard multi-purpose notification',
|
|
subject: '{{title}}',
|
|
fileName: 'generic_notification.html',
|
|
placeholders: ['title', 'message']
|
|
},
|
|
{
|
|
templateCode: 'QUESTIONNAIRE_REMINDER',
|
|
description: 'Periodic reminder to complete assessment',
|
|
subject: 'Reminder: Complete your Dealer Assessment',
|
|
fileName: 'questionnaire_reminder.html',
|
|
placeholders: ['applicantName', 'location']
|
|
},
|
|
{
|
|
templateCode: 'CONSTITUTIONAL_CHANGE_SUBMITTED',
|
|
description: 'Notification for new Constitutional Change request',
|
|
subject: 'New Constitutional Change Request: {{requestId}}',
|
|
fileName: 'constitutional_change_submitted.html',
|
|
placeholders: ['dealerName', 'changeType', 'requestId']
|
|
},
|
|
{
|
|
templateCode: 'RESIGNATION_UPDATE',
|
|
description: 'General status update for Resignation',
|
|
subject: 'Resignation Status Update: {{status}}',
|
|
fileName: 'resignation_update.html',
|
|
placeholders: ['dealerName', 'status', 'remarks']
|
|
},
|
|
{
|
|
templateCode: 'TERMINATION_UPDATE',
|
|
description: 'General status update for Termination',
|
|
subject: 'Termination Status Update: {{status}}',
|
|
fileName: 'termination_update.html',
|
|
placeholders: ['dealerName', 'status', 'remarks']
|
|
},
|
|
{
|
|
templateCode: 'CONSTITUTIONAL_CHANGE_UPDATE',
|
|
description: 'General status update for Constitutional Change',
|
|
subject: 'Constitutional Change Update: {{status}}',
|
|
fileName: 'constitutional_change_update.html',
|
|
placeholders: ['dealerName', 'status', 'remarks']
|
|
},
|
|
{
|
|
templateCode: 'RESIGNATION_RECEIVED',
|
|
description: 'Acknowledgement to dealer when resignation request is submitted',
|
|
subject: 'We received your resignation — {{resignationId}}',
|
|
fileName: 'resignation_received.html',
|
|
placeholders: ['dealerName', 'resignationId', 'lwd']
|
|
},
|
|
{
|
|
templateCode: 'RELOCATION_RECEIVED',
|
|
description: 'Acknowledgement to dealer when relocation request is submitted',
|
|
subject: 'Relocation request received — {{requestId}}',
|
|
fileName: 'relocation_received.html',
|
|
placeholders: ['dealerName', 'requestId']
|
|
},
|
|
{
|
|
templateCode: 'RELOCATION_SUBMITTED',
|
|
description: 'Internal notify (e.g. ASM) when a dealer submits relocation',
|
|
subject: 'New relocation request: {{requestId}}',
|
|
fileName: 'relocation_submitted.html',
|
|
placeholders: ['dealerName', 'requestId', 'outletCode']
|
|
},
|
|
{
|
|
templateCode: 'RELOCATION_UPDATE',
|
|
description: 'Dealer-visible status updates during relocation workflow',
|
|
subject: 'Relocation update — {{requestId}} ({{status}})',
|
|
fileName: 'relocation_update.html',
|
|
placeholders: ['dealerName', 'requestId', 'status', 'remarks']
|
|
},
|
|
{
|
|
templateCode: 'SLA_BREACH_WARNING',
|
|
description: 'Email when an application SLA tracking record breaches deadline',
|
|
subject: 'SLA breach: {{applicationId}} — {{stageName}}',
|
|
fileName: 'sla_breach_warning.html',
|
|
placeholders: ['applicationId', 'stageName', 'currentStage']
|
|
},
|
|
{
|
|
templateCode: 'SLA_REMINDER',
|
|
description: 'Reminder sent before SLA breach',
|
|
subject: 'SLA Reminder: {{applicationId}} — {{stageName}}',
|
|
fileName: 'sla_reminder.html',
|
|
placeholders: ['applicationId', 'stageName', 'link']
|
|
},
|
|
{
|
|
templateCode: 'SLA_BREACH',
|
|
description: 'Notification sent when SLA is breached',
|
|
subject: 'SLA BREACHED: {{applicationId}} — {{stageName}}',
|
|
fileName: 'sla_breach.html',
|
|
placeholders: ['applicationId', 'stageName', 'link']
|
|
},
|
|
{
|
|
templateCode: 'SLA_ESCALATION',
|
|
description: 'Notification sent for multi-level SLA escalations',
|
|
subject: 'SLA ESCALATION [L{{level}}]: {{applicationId}} — {{stageName}}',
|
|
fileName: 'sla_escalation.html',
|
|
placeholders: ['applicationId', 'stageName', 'level', 'timeValue', 'timeUnit', 'link']
|
|
}
|
|
];
|
|
|
|
for (const t of templates) {
|
|
let body = '';
|
|
try {
|
|
const filePath = path.join(templatesDir, t.fileName);
|
|
if (fs.existsSync(filePath)) {
|
|
body = fs.readFileSync(filePath, 'utf-8');
|
|
} else {
|
|
console.warn(`File not found: ${t.fileName}. Creating a placeholder body.`);
|
|
body = `<html><body><h1>${t.description}</h1><p>This is a placeholder for ${t.templateCode}</p></body></html>`;
|
|
}
|
|
|
|
await db.EmailTemplate.upsert({
|
|
templateCode: t.templateCode,
|
|
description: t.description,
|
|
subject: t.subject,
|
|
body: body,
|
|
placeholders: t.placeholders,
|
|
isActive: true
|
|
});
|
|
console.log(`Seeded/Updated template: ${t.templateCode}`);
|
|
} catch (err) {
|
|
console.error(`Failed to seed ${t.templateCode}:`, err);
|
|
}
|
|
}
|
|
|
|
console.log('Email template seeding completed.');
|
|
process.exit(0);
|
|
} catch (error) {
|
|
console.error('Seeding error:', error);
|
|
process.exit(1);
|
|
}
|
|
};
|
|
|
|
seedTemplates();
|