/** * @file seed-missing-templates.ts * @description Seeds the 6 email templates that are referenced in workflow code * but were missing from the DB and the allowed-email-template-codes list. * * Run with: npx ts-node src/scripts/seed-missing-templates.ts */ import db from '../database/models/index.js'; const seedMissingTemplates = async () => { try { console.log('--- Seeding Missing Workflow Email Templates ---'); const templates = [ // ── 1. Workflow Action Required ──────────────────────────────────────── // Used in: workflow-email-notifications.ts (next-actor, send-back notifications) // constitutional.controller.ts // Recipients: DD-ZM, RBM, ZBH, DD-Lead, DD-Head, NBH, Legal, Finance, FDD // Channels: system + email + whatsapp (when phone available) { templateCode: 'WORKFLOW_ACTION_REQUIRED', description: 'Sent to the next actor in any workflow when their action is required. Used across Onboarding, Resignation, Termination, Constitutional, and Relocation.', subject: 'Action Required: {{requestId}} — {{targetStage}}', body: `

Action Required

Hi,

The request {{requestId}} {{#if dealerName}}(Dealer: {{dealerName}}){{/if}} has reached the {{targetStage}} stage and requires your review and action.

{{#if remarks}}
Remarks:
{{remarks}}
{{/if}}

Please log in to the RE Dealer Management Portal to review and act:

{{#if ctaLabel}}{{ctaLabel}}{{else}}Review & Take Action{{/if}}

This is an automated notification. Do not reply to this email.

`, placeholders: ['requestId', 'dealerName', 'targetStage', 'link', 'remarks', 'ctaLabel'] }, // ── 2. Workflow Status Update — Dealer ───────────────────────────────── // Used in: workflow-email-notifications.ts (dealer on interim + terminal events) // Recipients: Dealer / Applicant // Channels: system always; email+whatsapp on terminal (rejection/completion) { templateCode: 'WORKFLOW_STATUS_UPDATE_DEALER', description: 'Milestone/status update sent to the dealer or applicant when their request moves to a new stage.', subject: 'Update on Your Request — {{requestId}}', body: `

Request Status Update

Dear {{dealerName}},

Your request {{requestId}} has been updated. Current status: {{targetStage}}.

{{#if remarks}}
Note: {{remarks}}
{{/if}}

Track the live progress of your request:

View Request

For queries, contact your assigned Area Sales Manager.

`, placeholders: ['requestId', 'dealerName', 'targetStage', 'link', 'remarks'] }, // ── 3. F&F Initiated ─────────────────────────────────────────────────── // Used in: resignation.controller.ts (when F&F is triggered on LWD) // termination.controller.ts (post-termination F&F) // Recipients: Finance team, Department heads, DD-Admin // Channels: system + email { templateCode: 'FNF_INITIATED', description: 'Notifies Finance and department heads when Full & Final (F&F) settlement is triggered on the Last Working Day.', subject: 'F&F Settlement Initiated — {{requestId}}', body: `

Full & Final Settlement Initiated

Dear {{recipientName}},

The Full & Final (F&F) settlement process has been initiated for dealer {{dealerName}} (Request: {{requestId}}).

Request ID {{requestId}}
Dealer Name {{dealerName}}
Last Working Day {{lwd}}
Initiated By {{initiatedBy}}

Please update your department clearance status promptly.

View F&F Settlement

Per Royal Enfield policy, F&F settlement is initiated only on or after the Last Working Day.

`, placeholders: ['recipientName', 'dealerName', 'requestId', 'lwd', 'initiatedBy', 'link'] }, // ── 4. EOR Completed ─────────────────────────────────────────────────── // Used in: eor.controller.ts (when all EOR checklist items are complete) // Recipients: DD-Head, NBH // Channels: system (alert only — no email per SRS §6.19.3.4 design choice) // Adding email template so Admin can optionally enable { templateCode: 'EOR_COMPLETED', description: 'Alert to DD-Head and NBH when 100% of EOR (Essential Operating Requirements) checklist items are verified. Signals readiness for Inauguration stage.', subject: 'EOR Checklist Complete — Ready for Inauguration: {{requestId}}', body: `

✓ EOR Checklist — 100% Complete

Dear {{recipientName}},

All Essential Operating Requirements (EOR) for dealer application {{requestId}} (Applicant: {{applicantName}}) have been completed and verified.

EOR Status: 100% Complete
The dealership is now ready for Inauguration review.
Application ID {{requestId}}
Applicant {{applicantName}}
Location {{location}}
Completed On {{completedOn}}

Please review and authorize the Inauguration stage to mark this dealership as Live.

Authorize Inauguration
`, placeholders: ['recipientName', 'applicantName', 'requestId', 'location', 'completedOn', 'link'] }, // ── 5. Applicant Rejected ────────────────────────────────────────────── // Used in: WorkflowService.transitionApplication (any rejection) // Recipients: Applicant (external) // Channels: email (SRS §6.12.3 — rejection via email) // WhatsApp if mobileNumber present { templateCode: 'APPLICANT_REJECTED', description: 'Sent to the applicant/dealer when their application is rejected at any stage of the onboarding process.', subject: 'Update on Your Dealership Application — {{applicationId}}', body: `

Application Status Update

Dear {{applicantName}},

We regret to inform you that your Royal Enfield Dealership Application ({{applicationId}}) for location {{location}} has been rejected after careful evaluation.

{{#if rejectionReason}}
Reason:
{{rejectionReason}}
{{/if}}

We appreciate your interest in partnering with Royal Enfield. You may reapply when opportunities are available in your area in the future.

For any queries, contact us at dealer-support@royalenfield.com.

Best Regards,
Royal Enfield Dealer Development Team

`, placeholders: ['applicantName', 'applicationId', 'location', 'rejectionReason'] }, // ── 6. Termination Initiated ─────────────────────────────────────────── // Used in: termination.controller.ts (case creation) // Recipients: RBM, DD-ZM, ZBH, DD-Lead, Legal, NBH // Channels: system + email + whatsapp { templateCode: 'TERMINATION_INITIATED', description: 'Notifies internal stakeholders (RBM, DD-ZM, ZBH, Legal, NBH) when a dealer termination case is formally initiated by ASM.', subject: 'Dealer Termination Case Initiated — {{requestId}}', body: `

Dealer Termination Case Initiated

Dear {{recipientName}},

A formal termination process has been initiated for dealer {{dealerName}} (Request ID: {{requestId}}).

Request ID {{requestId}}
Dealer Name {{dealerName}}
Termination Category {{category}}
Initiated By {{initiatedBy}}
Current Stage {{currentStage}}
{{#if remarks}}
Remarks:
{{remarks}}
{{/if}}

Please review the case and provide your evaluation with mandatory work notes.

Review Termination Case

This notification is confidential. Do not share externally without authorization.

`, placeholders: ['recipientName', 'dealerName', 'requestId', 'category', 'initiatedBy', 'currentStage', 'remarks', 'link'] } ]; for (const t of templates) { const [, created] = await db.EmailTemplate.upsert({ ...t, isActive: true }); console.log(`${created ? 'Created' : 'Updated'}: ${t.templateCode}`); } console.log('\n--- Missing Templates Seeded Successfully ---'); console.log(`Total: ${templates.length} templates seeded.`); process.exit(0); } catch (error) { console.error('Error seeding missing templates:', error); process.exit(1); } }; seedMissingTemplates();