# RE Dealer Management System — Email Communications Catalogue

**Document Owner:** Dealer Development — Product / Engineering
**Last updated:** 2026-05-11
**Status:** Living document. Section A lists every email wired in the application. **Section B** covers the ten **onboarding document / LOI / LOA / FDD / architecture** templates that are now implemented; share **`RE_Dealer_Email_Content_Client_Brief.md`** with non-technical stakeholders for copy sign-off.

> Purpose: A single source of truth for every outbound mail the platform sends — what triggers it, who receives it, what channels it goes on, and the exact copy currently rendered to the recipient. Use this for stakeholder sign-off, copy review, and to plan the next set of communications (Document Collection, Statutory Document Collection, etc.).

---

## Table of Contents

1. [Conventions & Common Elements](#1-conventions--common-elements)
2. [Master Index of Email Templates](#2-master-index-of-email-templates)
3. [Section A — Currently Implemented Mails](#section-a--currently-implemented-mails)
   - A.1 Dealer Onboarding
   - A.2 Dealer Resignation
   - A.3 Dealer Termination
   - A.4 Constitutional Change
   - A.5 Dealer Relocation
   - A.6 Full & Final (F&F) Settlement
   - A.7 Workflow / Collaboration / Generic
   - A.8 SLA & Escalation Mails
4. [Section B — Onboarding extensions (implemented)](#section-b--onboarding-extensions-implemented)
5. [Appendix — Common Header / Footer / CTA Partials](#appendix--common-header--footer--cta-partials)

---

## 1. Conventions & Common Elements

- Every mail is rendered through a Handlebars template stored under `backend/src/emailtemplates/*.html` and seeded into the `email_templates` table (`backend/src/scripts/seed-master-emails.ts`, `seed-missing-templates.ts`, `seed-interview-templates.ts`).
- Master Configuration (`Admin → Master → Email Templates`) lets DD-Admin edit Subject, Body, and toggle Active without code changes.
- Each template ships with a fixed set of merge placeholders (e.g. `{{applicantName}}`, `{{applicationId}}`, `{{link}}`).
- Every mail is wrapped with:
  - **Header partial:** Royal Enfield black banner with logo (`partials/email_header.html`).
  - **Footer partial:** Copyright + "do not reply" line (`partials/email_footer.html`).
  - **Primary CTA partial:** Red action button rendered only when `ctaUrl` is supplied (`partials/primary_cta.html`).
- Channels per recipient are decided in code (`NotificationService.notify`) — typically a combination of `system` (in‑app), `email`, and `whatsapp` (when a mobile number is on file).

---

## 2. Master Index of Email Templates

| # | Template Code | Module | Recipient(s) | Channels | Status |
|---|---|---|---|---|---|
| 1 | `OPPORTUNITY` | Onboarding | Applicant | email | Implemented |
| 2 | `NON_OPPORTUNITY` | Onboarding | Applicant | email | Implemented |
| 3 | `QUESTIONNAIRE_SUBMITTED` | Onboarding | Applicant | email | Implemented |
| 4 | `QUESTIONNAIRE_REMINDER` | Onboarding | Applicant | email + whatsapp | Implemented |
| 5 | `APPLICANT_SHORTLISTED` | Onboarding | Applicant | email | Implemented |
| 6 | `APPLICANT_REJECTED` | Onboarding | Applicant | email + whatsapp | Implemented |
| 7 | `INTERVIEW_SCHEDULED` | Onboarding | Applicant / Panelist | email | Implemented (legacy) |
| 8 | `INTERVIEW_SCHEDULED_APPLICANT` | Onboarding | Applicant | email + whatsapp + system | Implemented |
| 9 | `INTERVIEW_SCHEDULED_PANELIST` | Onboarding | Panelist (Internal) | email + whatsapp + system | Implemented |
| 10 | `INTERVIEW_RESCHEDULED_APPLICANT` | Onboarding | Applicant | email + system | Implemented |
| 11 | `INTERVIEW_RESCHEDULED_PANELIST` | Onboarding | Panelist | email + system | Implemented |
| 12 | `INTERVIEW_CANCELLED_APPLICANT` | Onboarding | Applicant | email + system | Implemented |
| 13 | `INTERVIEW_CANCELLED_PANELIST` | Onboarding | Panelist | email + system | Implemented |
| 14 | `USER_ASSIGNED` | Collaboration | Internal user (participant) | email + system | Implemented |
| 15 | `LOI_ISSUED` | Onboarding | Applicant | email | Implemented |
| 16 | `LOA_ISSUED` | Onboarding | Applicant + internal | email + system | Implemented |
| 17 | `DEALER_CODE_READY` | Onboarding | Applicant + internal | email + system | Implemented |
| 18 | `ONBOARDING_STATUS_UPDATE` | Onboarding | Applicant | email + system | Implemented |
| 19 | `ONBOARDING_PAYMENT_VERIFIED` | Onboarding | DD-Admin / Internal | email + system | Implemented |
| 20 | `EOR_COMPLETED` | Onboarding | DD-Head + NBH | email + system | Implemented |
| 21 | `INAUGURATION_COMPLETED` | Onboarding | Internal teams | email + system | Implemented |
| 22 | `RESIGNATION_RECEIVED` | Resignation | Dealer | email + whatsapp | Implemented |
| 23 | `RESIGNATION_SUBMITTED` | Resignation | Internal (ASM, RBM, DD-ZM, …) | email + whatsapp + system | Implemented |
| 24 | `RESIGNATION_APPROVED` | Resignation | Dealer | email + system | Implemented |
| 25 | `RESIGNATION_UPDATE` | Resignation | Dealer | system (email optional) | Implemented |
| 26 | `TERMINATION_INITIATED` | Termination | Internal stakeholders | email + whatsapp + system | Implemented |
| 27 | `TERMINATION_SCN_ISSUED` | Termination | Dealer + Internal | email + whatsapp + system | Implemented |
| 28 | `TERMINATION_LETTER_ISSUED` | Termination | DD-Lead, DD-Admin, Finance | email + system | Implemented |
| 29 | `TERMINATION_FINAL_CLOSURE_DEALER` | Termination | Dealer | email + whatsapp + system | Implemented |
| 30 | `TERMINATION_UPDATE` | Termination | Dealer | system (email optional) | Implemented |
| 31 | `CONSTITUTIONAL_CHANGE_SUBMITTED` | Constitutional | Internal stakeholders | email + whatsapp + system | Implemented |
| 32 | `CONSTITUTIONAL_CHANGE_APPROVED` | Constitutional | Dealer | email + system | Implemented |
| 33 | `CONSTITUTIONAL_CHANGE_UPDATE` | Constitutional | Dealer | system (email optional) | Implemented |
| 34 | `RELOCATION_RECEIVED` | Relocation | Dealer | email + system | Implemented |
| 35 | `RELOCATION_SUBMITTED` | Relocation | ASM | email + whatsapp + system | Implemented |
| 36 | `RELOCATION_APPROVED` | Relocation | Dealer | email + system | Implemented |
| 37 | `RELOCATION_UPDATE` | Relocation | Dealer | system (email optional) | Implemented |
| 38 | `FNF_INITIATED` | F&F | Finance, Dept heads, DD-Admin | email + system | Implemented |
| 39 | `FNF_SUMMARY_PREPARED` | F&F | Finance | email + system | Implemented |
| 40 | `FNF_SETTLEMENT_APPROVED` | F&F | DD-Admin, Legal, Finance | email + system | Implemented |
| 41 | `WORKFLOW_ACTION_REQUIRED` | Workflow (cross-module) | Next actor | email + whatsapp + system | Implemented |
| 42 | `WORKFLOW_STATUS_UPDATE_DEALER` | Workflow (cross-module) | Dealer | system (terminal: + email + whatsapp) | Implemented |
| 43 | `WORKNOTE_NOTIFICATION` | Collaboration | Mentioned user | email | Implemented |
| 44 | `GENERIC_NOTIFICATION` | Cross-cutting | Any | email | Implemented |
| 45 | `SLA_REMINDER` | SLA | Stage owner | email + system | Implemented |
| 46 | `SLA_BREACH_WARNING` | SLA | Stage owner | email + system | Implemented |
| 47 | `SLA_BREACH` | SLA | Stage owner + escalation | email + system | Implemented |
| 48 | `SLA_ESCALATION` | SLA | Escalation level user | email + system | Implemented |
| **B.1** | `PROSPECT_DOCUMENT_REQUEST` | Onboarding | Applicant | email + whatsapp | **Live** |
| **B.2** | `STATUTORY_DOCUMENT_REQUEST` | Onboarding | Applicant | email | **Live** |
| **B.3** | `DOCUMENT_SUBMISSION_REMINDER` | Onboarding | Applicant | email + whatsapp | **Live** (bulk) |
| **B.4** | `DOCUMENT_RECEIVED_ACKNOWLEDGEMENT` | Onboarding | Applicant | email | **Live** |
| **B.5** | `DOCUMENT_REJECTED_RESUBMIT` | Onboarding | Applicant | email + whatsapp | **Live** |
| **B.6** | `FDD_DOCUMENT_REQUEST` | Onboarding | Applicant | email | **Live** |
| **B.7** | `LOI_ACKNOWLEDGEMENT_REQUEST` | Onboarding | Applicant | email + whatsapp | **Live** (bulk) |
| **B.8** | `SECURITY_DEPOSIT_REQUEST` | Onboarding | Applicant | email + whatsapp | **Live** |
| **B.9** | `DEALERSHIP_AGREEMENT_SIGNATURE_REQUEST` | Onboarding | Applicant | email | **Live** |
| **B.10** | `ARCHITECTURAL_PLAN_REQUEST` | Onboarding | Applicant | email | **Live** |
| **B.11** | *Orchestrator (no new template)* — Admin "Request Documents" action | Onboarding | Applicant | email + whatsapp (per bucket) | **Live** |

---

# Section A — Currently Implemented Mails

For every template below the document records:

- **Template Code**, **File path**, **Subject line**
- **Trigger (When sent)**
- **Recipients (To)**
- **Channels** (email / WhatsApp / in‑app)
- **Placeholders**
- **Current body copy** as rendered (after substituting partials)

---

## A.1 — Dealer Onboarding

### A.1.1 `OPPORTUNITY` — Opportunity Available

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/opportunity.html` |
| **Subject** | `Action Required: Royal Enfield Dealership Opportunity` |
| **Trigger** | Applicant applies for a location where a Dealer Development opportunity window is **open**. Sent automatically from `onboarding.controller.ts` on `submitApplication` and on bulk conversion of non-opportunity → opportunity. |
| **Recipient** | Applicant (external) |
| **Channels** | Email |
| **Placeholders** | `applicantName`, `location`, `applicationId`, `link`, `ctaLabel` |

**Body (rendered):**

> **Hi {{applicantName}},**
>
> Thank you for expressing interest in a Royal Enfield dealership opportunity for **{{location}}**.
>
> To proceed with your application, we require you to complete a mandatory business assessment questionnaire. This will help us evaluate your profile better.
>
> [ **Complete Questionnaire** ]  ← CTA button linking to `{{link}}`
>
> Please complete this at your earliest convenience. If you have any questions, feel free to contact our development team.
>
> Regards,
> Royal Enfield Team

---

### A.1.2 `NON_OPPORTUNITY` — Regret Email

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/non_opportunity.html` |
| **Subject** | `Update on your Royal Enfield Dealership Application` |
| **Trigger** | Applicant applies for a location where **no** opportunity window is open. |
| **Recipient** | Applicant |
| **Channels** | Email |
| **Placeholders** | `applicantName`, `location` |

**Body:**

> Dear {{applicantName}},
>
> Thank you for your interest in a Royal Enfield dealership for **{{location}}**.
>
> After careful review of your application and the current organizational requirements, we regret to inform you that we are unable to proceed with your request at this time.
>
> We will keep your profile in our database for future opportunities. We wish you the very best in your future endeavors.
>
> Regards,
> Royal Enfield Team

---

### A.1.3 `QUESTIONNAIRE_SUBMITTED` — Questionnaire Acknowledgement

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/questionnaire_submitted.html` |
| **Subject** | `Questionnaire Submitted Successfully: {{applicationId}}` |
| **Trigger** | Applicant submits the assessment questionnaire (`questionnaire.controller.ts` / `assessment.controller.ts`). |
| **Recipient** | Applicant |
| **Channels** | Email |
| **Placeholders** | `applicantName`, `location`, `applicationId` |

**Body:**

> Hi {{applicantName}},
>
> Your business assessment questionnaire for **{{location}}** (Application ID: {{applicationId}}) has been successfully submitted.
>
> Our team will review your responses and get back to you with the next steps.
>
> Regards,
> Royal Enfield Team

---

### A.1.4 `QUESTIONNAIRE_REMINDER` — Pending Questionnaire Reminder

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/questionnaire_reminder.html` |
| **Subject** | `Reminder: Complete your Dealer Assessment` |
| **Trigger** | Scheduled job (NotificationService) for applicants whose questionnaire is still pending. |
| **Recipient** | Applicant |
| **Channels** | Email + WhatsApp |
| **Placeholders** | `applicantName`, `location` |

**Body:**

> Hi {{applicantName}},
>
> This is a reminder that we are awaiting your response to the dealership assessment questionnaire for **{{location}}**.
>
> Completing this questionnaire is a mandatory step to move forward with your application.
>
> [ **Complete Questionnaire** ]
>
> If you have already submitted it, please ignore this email.

---

### A.1.5 `APPLICANT_SHORTLISTED` — Shortlist Notification

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/applicant_shortlisted.html` |
| **Subject** | `Congratulations! You are Shortlisted: {{applicationId}}` |
| **Trigger** | DD-Admin shortlists the application (`onboarding.controller.ts → shortlistApplication`). |
| **Recipient** | Applicant |
| **Channels** | Email |
| **Placeholders** | `applicantName`, `location`, `applicationId`, `portalLink`, `ctaLabel` |

**Body:**

> Hi {{applicantName}},
>
> We are pleased to inform you that your dealership application for **{{location}}** has been shortlisted for further evaluation.
>
> Our team will contact you shortly to schedule the next level of interviews. In the meantime, you can track your application status on our dealer portal.
>
> [ **Visit Dealer Portal** ]
>
> Regards,
> Royal Enfield Dealer Development Team

---

### A.1.6 `APPLICANT_REJECTED` — Rejection Notice

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/applicant_rejected.html` |
| **Subject** | `Update on Your Dealership Application — {{applicationId}}` |
| **Trigger** | `WorkflowService.transitionApplication` reaches any rejection stage (Level 1 / Level 2 / Level 3 / LOI / LOA). |
| **Recipient** | Applicant |
| **Channels** | Email + WhatsApp (if phone available) |
| **Placeholders** | `applicantName`, `applicationId`, `location`, `rejectionReason` |

**Body:**

> ## Application Rejected — {{applicationId}}
>
> Dear {{applicantName}},
>
> We regret to inform you that your Royal Enfield Dealership Application (**{{applicationId}}**) for location **{{location}}** has been **rejected** after careful evaluation.
>
> **Reason for Rejection:**
> {{rejectionReason}}
>
> We appreciate your interest in partnering with Royal Enfield. You may reapply in the future when opportunities are available in your area.
>
> For any queries, please contact your local RE representative or reach us at dealer-support@royalenfield.com.
>
> Best Regards,
> Royal Enfield Dealer Development Team

---

### A.1.7 `INTERVIEW_SCHEDULED` — Generic Interview Scheduled (legacy)

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/interview_scheduled.html` |
| **Subject** | `Interview Scheduled: {{applicationId}}` |
| **Trigger** | Legacy fallback when interview-specific variants are not available. |
| **Recipient** | Applicant / Panelist |
| **Channels** | Email |
| **Placeholders** | `name`, `applicationId`, `level`, `dateTime`, `type`, `location` |

**Body:**

> Hi {{name}},
>
> Your interview for the Royal Enfield dealership application (**{{applicationId}}**) has been scheduled.
>
> - **Interview Level:** {{level}}
> - **Date & Time:** {{dateTime}}
> - **Mode/Location:** {{location}}
> - **Type:** {{type}}
>
> Please ensure you are available at the scheduled time. If it's a virtual interview, the link will be shared separately or is included in the location field above.

---

### A.1.8 `INTERVIEW_SCHEDULED_APPLICANT`

| Field | Value |
|---|---|
| **Seeded by** | `seed-interview-templates.ts` |
| **Subject** | `Interview Scheduled: {{applicationId}}` |
| **Trigger** | DD-Admin schedules a Level 1 / 2 / 3 interview (`assessment.controller.ts`). |
| **Recipient** | Applicant |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `applicantName`, `applicationId`, `type`, `scheduledAt`, `meetLink`, `appLink` |

**Body:**

> Dear {{applicantName}},
>
> Your **{{type}}** for Royal Enfield Dealership Application ({{applicationId}}) has been scheduled.
>
> - **Scheduled Time:** {{scheduledAt}}
> - **Meeting Link/Location:** {{meetLink}}
>
> Please ensure you are available at the scheduled time.
>
> [ **Join Meeting** ]   [ View Application ]
>
> Best Regards,
> Royal Enfield Onboarding Team

---

### A.1.9 `INTERVIEW_SCHEDULED_PANELIST`

| Field | Value |
|---|---|
| **Seeded by** | `seed-interview-templates.ts` |
| **Subject** | `New Interview Assignment: {{applicationId}}` |
| **Trigger** | DD-Admin assigns / re-assigns a panelist. |
| **Recipient** | Panelist (Internal user: DD-ZM, RBM, ZBH, DD-Lead, NBH, DD-Head) |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `panelistName`, `applicantName`, `applicationId`, `type`, `scheduledAt`, `meetLink`, `appLink` |

**Body:**

> Hi {{panelistName}},
>
> You have been assigned as a panelist for **{{type}}** with **{{applicantName}}**.
>
> - **Application ID:** {{applicationId}}
> - **Scheduled Time:** {{scheduledAt}}
> - **Meeting Link/Location:** {{meetLink}}
>
> [ **Join Meeting** ]   [ Open Assessment Dashboard ]
>
> Please review the applicant's profile before the session.
>
> Regards,
> System Administrator

---

### A.1.10 `INTERVIEW_RESCHEDULED_APPLICANT`

| Field | Value |
|---|---|
| **Subject** | `Interview Rescheduled: {{applicationId}}` |
| **Trigger** | DD-Admin reschedules an interview. |
| **Recipient** | Applicant |
| **Channels** | Email + System |

**Body:**

> Dear {{applicantName}},
>
> Your **{{type}}** for Royal Enfield Dealership Application ({{applicationId}}) has been **rescheduled**.
>
> - **New Scheduled Time:** {{scheduledAt}}
> - **Meeting Link/Location:** {{meetLink}}
>
> [ **Join Meeting** ]  [ View Application ]
>
> Best Regards, Royal Enfield Onboarding Team

---

### A.1.11 `INTERVIEW_RESCHEDULED_PANELIST`

Same scenario as above, sent to panelist instead of applicant.

**Body:**

> Hi {{panelistName}},
>
> The **{{type}}** for **{{applicantName}}** ({{applicationId}}) has been **rescheduled**.
>
> - **New Scheduled Time:** {{scheduledAt}}
> - **Meeting Link/Location:** {{meetLink}}
>
> [ Join Meeting ]  [ Open Assessment Dashboard ]
>
> Please update your calendar accordingly.

---

### A.1.12 `INTERVIEW_CANCELLED_APPLICANT`

| Field | Value |
|---|---|
| **Subject** | `Interview Cancelled: {{applicationId}}` |
| **Recipient** | Applicant |
| **Channels** | Email + System |

**Body:**

> Dear {{applicantName}},
>
> We inform you that your **{{type}}** for Royal Enfield Dealership Application ({{applicationId}}) has been **cancelled**.
>
> Our team will reach out to you if a new session is required.
>
> Best Regards, Royal Enfield Onboarding Team

---

### A.1.13 `INTERVIEW_CANCELLED_PANELIST`

| Field | Value |
|---|---|
| **Subject** | `Interview Cancelled: {{applicationId}}` |
| **Recipient** | Panelist |
| **Channels** | Email + System |

**Body:**

> Hi {{panelistName}},
>
> The **{{type}}** for **{{applicantName}}** ({{applicationId}}) has been **cancelled**.
>
> You no longer need to attend this session.

---

### A.1.14 `USER_ASSIGNED` — Participant Assignment

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/user_assigned.html` |
| **Subject** | `New Application Assignment: {{applicationId}}` |
| **Trigger** | DD-Admin adds a participant to an application (`collaboration.controller.ts`). |
| **Recipient** | Internal user being added (e.g. FDD, Legal, Architecture, ASM) |
| **Channels** | Email + System |
| **Placeholders** | `userName`, `applicationId`, `dealerName`, `participantType` |

**Body:**

> Hi {{userName}},
>
> You have been assigned as a **{{participantType}}** for the following dealership application:
>
> - **Applicant:** {{dealerName}}
> - **Application ID:** {{applicationId}}
>
> Please log in to the portal to review the application and complete your tasks.

---

### A.1.15 `LOI_ISSUED` — Letter of Intent Issued

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/loi_issued.html` |
| **Subject** | `Letter of Intent (LOI) Issued: {{applicationId}}` |
| **Trigger** | DD-Admin issues the LOI after NBH approval (`loi.controller.ts → issueLoi`). |
| **Recipient** | Applicant |
| **Channels** | Email **only** (per SRS §6.16.3.6 — explicitly **no** WhatsApp for LOI/LOA documents) |
| **Placeholders** | `applicantName`, `applicationId`, `ctaLabel` |

**Body:**

> ## Congratulations {{applicantName}}!
>
> We are delighted to inform you that your Letter of Intent (LOI) for the Royal Enfield dealership has been issued for the application **{{applicationId}}**.
>
> Please log in to the portal to view and acknowledge the document to move to the next stage.
>
> [ **View LOI** ]

---

### A.1.16 `LOA_ISSUED` — Letter of Appointment Issued

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/loa_issued.html` |
| **Subject** | `Letter of Appointment (LOA) Issued: {{applicationId}}` |
| **Trigger** | LOA fully approved by DD-Head + NBH (`loa.controller.ts`). |
| **Recipient** | Applicant + DD-Admin, DD-Lead (internal copy) |
| **Channels** | Email + System |
| **Placeholders** | `applicantName`, `applicationId`, `dealerCode`, `ctaLabel` |

**Body:**

> ## Welcome to the Family!
>
> Dear {{applicantName}},
>
> We are honored to issue your Letter of Appointment (LOA) for the Royal Enfield dealership ({{applicationId}}). Your dealership is now officially authorized under the code: **{{dealerCode}}**.
>
> We look forward to a successful partnership.
>
> [ **View LOA** ]

---

### A.1.17 `DEALER_CODE_READY` — SAP Dealer Codes Generated

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/dealer_code_ready.html` |
| **Subject** | `SAP Dealer Codes Readiness for {{applicationId}}` |
| **Trigger** | DD-Admin triggers SAP Dealer Code creation (`WorkflowService` → `Dealer Code Generated`). |
| **Recipient** | Applicant + DD-Admin, Finance, Sales, Service heads |
| **Channels** | Email + System |
| **Placeholders** | `applicantName`, `applicationId`, `salesCode`, `serviceCode` |

**Body:**

> ## SAP Dealer Codes Generated
>
> Hi {{applicantName}},
>
> We are pleased to inform you that your SAP Dealer Codes for application **{{applicationId}}** are now ready and active in our system.
>
> ```
> Sales Code:    {{salesCode}}
> Service Code:  {{serviceCode}}
> ```
>
> You can now proceed with system onboarding and initial orders.

---

### A.1.18 `ONBOARDING_STATUS_UPDATE` — Generic Status Update

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/onboarding_status_update.html` |
| **Subject** | `Onboarding Status Update: {{status}} — {{applicationId}}` |
| **Trigger** | Any onboarding status change not covered by LOI / LOA / Dealer Code specific mails (`WorkflowService.transitionApplication`). |
| **Recipient** | Applicant |
| **Channels** | Email + System |
| **Placeholders** | `applicantName`, `applicationId`, `status`, `reason`, `salesCode`, `serviceCode` |

**Body:**

> Hi {{applicantName}},
>
> Your dealership onboarding application status has been updated.
>
> - **Current status:** {{status}}
> - **Application ID:** {{applicationId}}
> - **Details:** {{reason}}
>
> You can sign in to the dealer development portal for more information.
>
> [ **View Application** ]

---

### A.1.19 `ONBOARDING_PAYMENT_VERIFIED` — Security Deposit / Payment Verified

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/onboarding_payment_verified.html` |
| **Subject** | `Payment Verified: {{applicationId}}` |
| **Trigger** | Finance verifies the Security Deposit / initial payment (`settlement.controller.ts`). |
| **Recipient** | DD-Admin, DD-Lead, Finance Team (Internal copy). The applicant is acknowledged via the workflow status update. |
| **Channels** | Email + System |
| **Placeholders** | `applicationId`, `dealerName`, `paymentType`, `amount`, `link` |

**Body:**

> ## Payment Verified — {{applicationId}}
>
> Dear Team,
>
> Finance has successfully verified the **{{paymentType}}** for **{{dealerName}}** (Application ID: **{{applicationId}}**).
>
> - **Verified Amount:** ₹{{amount}}
> - **Status:** Verified & Approved
>
> The onboarding process can now proceed to the next stage.
>
> [ **View Application** ]

---

### A.1.20 `EOR_COMPLETED` — EOR Checklist 100% Complete

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/eor_completed.html` |
| **Subject** | `EOR Readiness 100% Completed: {{applicationId}}` |
| **Trigger** | All EOR checklist items verified (`eor.controller.ts`). |
| **Recipient** | DD-Head, NBH (also applies to relocation-EOR scenario for DD-Admin) |
| **Channels** | Email + System (alert-class — SRS §6.19.3.4) |
| **Placeholders** | `recipientName`, `applicantName`, `requestId`, `location`, `completedOn`, `link` |

**Body:**

> ## EOR Checklist Complete — {{requestId}}
>
> Dear {{recipientName}},
>
> All **Essential Operating Requirements (EOR)** for dealer application **{{requestId}}** (Applicant: **{{applicantName}}**) have been marked as completed and verified.
>
> **EOR Status: 100% Complete** — The dealership outlet is now ready for Inauguration review.
>
> | Field | Value |
> |---|---|
> | Application ID | {{requestId}} |
> | Applicant Name | {{applicantName}} |
> | Location | {{location}} |
> | Completed On | {{completedOn}} |
>
> Please review the EOR checklist and authorize the **Inauguration** stage to mark this dealership as live.
>
> [ **Authorize Inauguration** ]

---

### A.1.21 `INAUGURATION_COMPLETED` — Dealership Inauguration Logged

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/inauguration_completed.html` |
| **Subject** | `Dealership Inauguration Logged: {{applicationId}}` |
| **Trigger** | DD-Admin marks the inauguration as complete; dealership goes Live. |
| **Recipient** | DD-Admin, DD-Lead, NBH, Finance, Sales, Service |
| **Channels** | Email + System |
| **Placeholders** | `dealerName`, `applicationId`, `location`, `date` |

**Body:**

> ## Dealership Inauguration Logged — {{applicationId}}
>
> Dear Team,
>
> We are pleased to inform you that the inauguration for dealer **{{dealerName}}** (Application ID: **{{applicationId}}**) at **{{location}}** has been successfully logged on **{{date}}**.
>
> The dealership is now marked as **Active** in the system. All relevant teams are requested to update their records accordingly.

---

## A.2 — Dealer Resignation

### A.2.1 `RESIGNATION_RECEIVED` — Dealer Acknowledgement

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/resignation_received.html` |
| **Subject** | `We received your resignation — {{resignationId}}` |
| **Trigger** | Dealer submits resignation via portal (`workflow-email-notifications.ts → notifyResignationSubmittedEmails`). |
| **Recipient** | Dealer |
| **Channels** | Email + WhatsApp |
| **Placeholders** | `dealerName`, `resignationId`, `lwd`, `link`, `ctaLabel` |

**Body:**

> Hi {{dealerName}},
>
> We have received your resignation request **{{resignationId}}**.
>
> **Last working day (as submitted):** {{lwd}}
>
> Our team will review and progress clearances as per process. You can track status anytime on the portal.
>
> [ **View Request** ]

---

### A.2.2 `RESIGNATION_SUBMITTED` — Internal Notification

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/resignation_submitted.html` |
| **Subject** | `New Resignation Request: {{resignationId}}` |
| **Trigger** | Same event as A.2.1, but for internal reviewers. |
| **Recipient** | ASM (DD-ASM), RBM, DD-ZM, ZBH, DD-Lead, DD-Head, NBH, Legal, DD-Admin |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `dealerName`, `resignationId`, `lwd`, `link`, `ctaLabel` |

**Body:**

> Hi Team,
>
> A new resignation request has been submitted by **{{dealerName}}**.
>
> - **Request ID:** {{resignationId}}
> - **Proposed Last Working Day:** {{lwd}}
>
> Please log in to the Dealer Development portal to review and initiate the clearance process.
>
> [ **Review Resignation** ]

---

### A.2.3 `RESIGNATION_APPROVED` — Resignation Approved

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/resignation_approved.html` |
| **Subject** | `Resignation Request Approved: {{resignationId}}` |
| **Trigger** | NBH issues final approval; Legal uploads acceptance letter. |
| **Recipient** | Dealer |
| **Channels** | Email + System |
| **Placeholders** | `dealerName`, `resignationId`, `lwd` |

**Body:**

> ## Resignation Request Approved
>
> Dear {{dealerName}},
>
> Your resignation request (Request ID: {{resignationId}}) has been approved by the Dealer Development team.
>
> **Proposed Last Working Day:** {{lwd}}
>
> The clearance process has been initiated. Please ensure all department dues are cleared as per the timeline.

---

### A.2.4 `RESIGNATION_UPDATE` — Interim Status Update

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/resignation_update.html` |
| **Subject** | `Resignation Status Update: {{status}}` |
| **Trigger** | Any interim stage transition during resignation. |
| **Recipient** | Dealer |
| **Channels** | System (email optional via Admin) |
| **Placeholders** | `dealerName`, `status`, `remarks` |

**Body:**

> Hi {{dealerName}},
>
> This is to inform you that the status of your resignation request has been updated.
>
> - **Current Stage:** {{status}}
>
> {{remarks}}
>
> You can track the progress and clearance status on the dealer development portal.
>
> [ **View Status** ]

---

## A.3 — Dealer Termination

### A.3.1 `TERMINATION_INITIATED` — Case Initiation Internal Alert

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/termination_initiated.html` |
| **Subject** | `Dealer Termination Case Initiated — {{requestId}}` |
| **Trigger** | DD-ASM creates a termination request (`termination.controller.ts`). |
| **Recipient** | RBM, DD-ZM, ZBH, DD-Lead, Legal, NBH |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `recipientName`, `dealerName`, `requestId`, `category`, `initiatedBy`, `currentStage`, `remarks`, `link`, `ctaLabel` |

**Body (key bits):**

> ## Dealer Termination Initiated — {{requestId}}
>
> Dear {{recipientName}},
>
> A formal termination process has been initiated for dealer **{{dealerName}}** (Request: **{{requestId}}**).
>
> | Field | Value |
> |---|---|
> | Request ID | {{requestId}} |
> | Dealer Name | {{dealerName}} |
> | Termination Category | {{category}} |
> | Initiated By | {{initiatedBy}} |
> | Current Stage | {{currentStage}} |
>
> **Remarks:** {{remarks}}
>
> Please review the termination case and provide your evaluation as required. All decisions must be documented with mandatory work notes.
>
> [ **Review Termination Case** ]
>
> *This notification is confidential and intended only for the named recipient. Do not share this information externally without authorization.*

---

### A.3.2 `TERMINATION_SCN_ISSUED` — Show Cause Notice

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/termination_scn.html` |
| **Subject** | `URGENT: Show Cause Notice Issued: {{terminationId}}` |
| **Trigger** | Legal uploads & issues SCN (`TerminationWorkflowService` / `termination.controller.ts → issueScn`). |
| **Recipient** | Dealer + DD-Admin / Legal copy |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `dealerName`, `terminationId`, `deadline`, `link`, `ctaLabel` |

**Body:**

> ## URGENT: Show Cause Notice Issued
>
> Dear {{dealerName}},
>
> This is to inform you that a **Show Cause Notice** has been issued regarding your dealership contract (Request ID: {{terminationId}}).
>
> You are required to submit your response on the dealer development portal by **{{deadline}}**. Failure to respond may lead to further action as per the dealership agreement.
>
> [ **Submit Response** ]

---

### A.3.3 `TERMINATION_LETTER_ISSUED` — Internal Letter Generated Alert

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/termination_letter_issued.html` |
| **Subject** | `Termination Letter Generated: {{requestId}}` |
| **Trigger** | Legal generates/uploads the official termination letter (`workflow-email-notifications.ts` → terminal event override). |
| **Recipient** | DD-Lead, DD-Admin, Finance |
| **Channels** | Email + System |
| **Placeholders** | `recipientName`, `dealerName`, `requestId`, `link`, `ctaLabel` |

**Body:**

> ## Termination Letter Generated — {{requestId}}
>
> Dear {{recipientName}},
>
> The official **Termination Letter** has been generated and uploaded to the portal for dealer **{{dealerName}}** (Request ID: **{{requestId}}**).
>
> This letter is now visible to the DD-Lead, DD-Admin, and Finance teams. Please proceed with the necessary administrative and financial closure steps.
>
> [ **View Letter** ]

---

### A.3.4 `TERMINATION_FINAL_CLOSURE_DEALER` — Final Closure to Dealer

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/termination_final_closure.html` |
| **Subject** | `Official Notice: Termination of Dealership — {{requestId}}` |
| **Trigger** | Workflow reaches `TERMINATION_STAGES.TERMINATED` (terminal event for dealer). |
| **Recipient** | Dealer |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `dealerName`, `requestId`, `terminationDate`, `link`, `ctaLabel` |

**Body:**

> ## Notice of Termination — {{requestId}}
>
> Dear {{dealerName}},
>
> This is the official notification that your dealership agreement with Royal Enfield (Request ID: **{{requestId}}**) has been formally terminated effective **{{terminationDate}}**.
>
> The final Termination Letter is available for your reference in the dealer portal. Your portal access will remain active for a limited period to allow you to download relevant documents and track the Full & Final (F&F) settlement progress.
>
> [ **View Letter & Portal** ]
>
> For any clarifications regarding the settlement process, please contact the Dealer Development Admin team.
>
> Best Regards,
> Royal Enfield Dealer Development Team

---

### A.3.5 `TERMINATION_UPDATE` — Interim Status to Dealer

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/termination_update.html` |
| **Subject** | `Termination Status Update: {{status}}` |
| **Recipient** | Dealer |
| **Channels** | System (email optional) |
| **Placeholders** | `dealerName`, `status`, `remarks` |

**Body:**

> Hi {{dealerName}},
>
> This is to inform you that the status of your dealership termination request has been updated.
>
> - **Current Stage:** {{status}}
>
> {{remarks}}
>
> Please log in to the portal to check if any actions are required from your end.

---

## A.4 — Constitutional Change

### A.4.1 `CONSTITUTIONAL_CHANGE_SUBMITTED` — Internal Alert

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/constitutional_change_submitted.html` |
| **Subject** | `New Constitutional Change Request: {{requestId}}` |
| **Trigger** | Dealer submits constitutional change request (`constitutional.controller.ts`). |
| **Recipient** | ASM, RBM, DD-ZM, ZBH, DD-Lead, DD-Head, NBH, Legal |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `dealerName`, `changeType`, `requestId`, `link`, `ctaLabel` |

**Body:**

> Hi Team,
>
> A new Constitutional Change request has been submitted by **{{dealerName}}**.
>
> - **Request Type:** {{changeType}}
> - **Request ID:** {{requestId}}
>
> Please log in to the Dealer Development portal to review the request and documents.
>
> [ **Review Request** ]

---

### A.4.2 `CONSTITUTIONAL_CHANGE_APPROVED` — Final Approval to Dealer

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/constitutional_change_approved.html` |
| **Subject** | `Constitutional Change Approved — {{requestId}}` |
| **Trigger** | Workflow reaches `CONSTITUTIONAL_STAGES.COMPLETED` (terminal). |
| **Recipient** | Dealer |
| **Channels** | Email + System |
| **Placeholders** | `dealerName`, `requestId`, `proposedConstitution`, `link` |

**Body:**

> ## Constitutional Change Approved — {{requestId}}
>
> Dear {{dealerName}},
>
> We are pleased to inform you that your request for a **Change in Constitution** (Request ID: **{{requestId}}**) has been officially approved by the Royal Enfield management.
>
> - **New Constitution:** {{proposedConstitution}}
> - **Status:** Approved & Updated
>
> The system records have been updated to reflect this change. You can now proceed with the legally compliant transition as per the approved structure.
>
> [ **View Request Details** ]

---

### A.4.3 `CONSTITUTIONAL_CHANGE_UPDATE` — Interim Update

| Field | Value |
|---|---|
| **Subject** | `Constitutional Change Update: {{status}}` |
| **Recipient** | Dealer |
| **Channels** | System (email optional) |

**Body:**

> Hi {{dealerName}},
>
> This is to inform you that your Constitutional Change request has been updated.
>
> - **Current Stage:** {{status}}
>
> {{remarks}}
>
> [ **View Status** ]

---

## A.5 — Dealer Relocation

### A.5.1 `RELOCATION_RECEIVED` — Dealer Acknowledgement

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/relocation_received.html` |
| **Subject** | `Relocation request received — {{requestId}}` |
| **Trigger** | Dealer submits a relocation request. |
| **Recipient** | Dealer |
| **Channels** | Email + System |
| **Placeholders** | `dealerName`, `requestId`, `link`, `ctaLabel`, `distance` |

**Body:**

> ## Relocation Request Received — {{requestId}}
>
> Dear {{dealerName}},
>
> We have received your request for dealership relocation (Request ID: **{{requestId}}**).
>
> The internal feasibility assessment and multi-level review process have been initiated. You will be notified of any document requirements or status updates via the portal and email.
>
> **Current Status:** ASM Review (In Progress)
>
> [ **Track Request** ]
>
> You can track the real-time progress of your request by logging into the Dealer Portal.

---

### A.5.2 `RELOCATION_SUBMITTED` — Internal Alert to ASM

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/relocation_submitted.html` |
| **Subject** | `New relocation request: {{requestId}}` |
| **Trigger** | Same event as A.5.1, sent to assigned ASM. |
| **Recipient** | ASM |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `dealerName`, `requestId`, `outletCode`, `link`, `ctaLabel`, `distance` |

**Body:**

> ## New Relocation Request: {{requestId}}
>
> Dear Team,
>
> A new dealership relocation request has been submitted by **{{dealerName}}** for outlet **{{outletCode}}**.
>
> - Request ID: {{requestId}}
> - Outlet Code: {{outletCode}}
> - Distance from existing site: {{distance}} km
>
> Please log in to the Dealer Development portal to review the proposed location, property documents, and feasibility details.
>
> [ **Review Request** ]

---

### A.5.3 `RELOCATION_APPROVED` — Final Approval to Dealer

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/relocation_approved.html` |
| **Subject** | `Relocation Approved — {{requestId}}` |
| **Recipient** | Dealer |
| **Channels** | Email + System |
| **Placeholders** | `dealerName`, `requestId`, `newLocation`, `link` |

**Body:**

> ## Relocation Approved — {{requestId}}
>
> Dear {{dealerName}},
>
> We are pleased to inform you that your request for **Dealership Relocation** (Request ID: **{{requestId}}**) has been officially approved by the Royal Enfield management.
>
> - **New Location:** {{newLocation}}
> - **Status:** Approved & Records Updated
>
> Our team will coordinate with you for the physical transition and site readiness audit. You can track the next steps via the portal.
>
> [ **View Request Details** ]

---

### A.5.4 `RELOCATION_UPDATE` — Interim Status

| Field | Value |
|---|---|
| **Subject** | `Relocation update — {{requestId}} ({{status}})` |
| **Recipient** | Dealer |
| **Channels** | System (email optional) |

**Body:**

> Hi {{dealerName}},
>
> Your relocation request **{{requestId}}** has been updated.
>
> - **Current stage:** {{status}}
>
> {{remarks}}
>
> [ **View Status** ]

---

## A.6 — Full & Final (F&F) Settlement

### A.6.1 `FNF_INITIATED` — F&F Triggered

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/fnf_initiated.html` |
| **Subject** | `F&F Settlement Initiated — {{requestId}}` |
| **Trigger** | F&F case is created on or after the Last Working Day (resignation closure / termination closure / settlement controller). |
| **Recipient** | Finance, Spares Manager, Service Manager, Accounts Manager, DD-Admin, DD-Lead, ZBH, RBM |
| **Channels** | Email + System |
| **Placeholders** | `recipientName`, `dealerName`, `requestId`, `lwd`, `initiatedBy`, `link`, `ctaLabel` |

**Body:**

> ## Full & Final Settlement Initiated — {{requestId}}
>
> Dear {{recipientName}},
>
> The Full & Final (F&F) settlement process has been initiated for dealer **{{dealerName}}** (Request: **{{requestId}}**) effective from the Last Working Day.
>
> | Field | Value |
> |---|---|
> | Request ID | {{requestId}} |
> | Dealer Name | {{dealerName}} |
> | Initiated By | {{initiatedBy}} |
> | Last Working Day | {{lwd}} |
>
> All department clearances (NOC, Payables, Receivables, etc.) must be submitted within the stipulated timeline. Please log in and update your department's clearance status.
>
> [ **View F&F Settlement** ]

---

### A.6.2 `FNF_SUMMARY_PREPARED` — Summary Ready for Finance

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/fnf_summary_prepared.html` |
| **Subject** | `F&F Settlement Summary Prepared: {{fnfId}}` |
| **Trigger** | All 16 department clearances received; Finance auto-summary computed. |
| **Recipient** | Finance team |
| **Channels** | Email + System |
| **Placeholders** | `fnfId`, `dealerName`, `netAmount`, `link`, `ctaLabel` |

**Body:**

> ## F&F Settlement Summary Prepared — {{fnfId}}
>
> Dear Finance Team,
>
> The initial Full & Final (F&F) settlement summary has been prepared for **{{dealerName}}** (F&F ID: **{{fnfId}}**).
>
> - **Calculated Net Amount:** ₹{{netAmount}}
> - **Status:** Pending Final Approval
>
> Please review the consolidated departmental responses and the settlement summary to proceed with final approval and payment processing.
>
> [ **Review & Approve** ]
>
> *Confidential: This summary contains sensitive financial data. Review only via authorized portal access.*

---

### A.6.3 `FNF_SETTLEMENT_APPROVED` — Final F&F Approval

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/fnf_settlement_approved.html` |
| **Subject** | `F&F Settlement Approved: {{fnfId}}` |
| **Trigger** | Finance approves the final settlement summary. |
| **Recipient** | DD-Admin, Legal, Finance |
| **Channels** | Email + System |
| **Placeholders** | `fnfId`, `dealerName`, `settlementAmount`, `link`, `ctaLabel` |

**Body:**

> ## F&F Settlement Approved — {{fnfId}}
>
> Dear Team,
>
> The final Full & Final (F&F) settlement for dealer **{{dealerName}}** (F&F ID: **{{fnfId}}**) has been **Approved** by Finance.
>
> - **Settlement Amount:** ₹{{settlementAmount}}
> - **Status:** Approved & Closed
>
> The DD-Admin and Legal teams are requested to update their records and proceed with final account closure.
>
> [ **View Settlement** ]

---

## A.7 — Workflow / Collaboration / Generic

### A.7.1 `WORKFLOW_ACTION_REQUIRED` — Generic Next-Actor Alert

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/workflow_action_required.html` |
| **Subject** | `Action Required: {{requestId}} — {{targetStage}}` |
| **Trigger** | Cross-module workflow transition reaches the next actor's stage (or a send-back to ASM occurs). |
| **Recipient** | Next assigned actor (role-based; DD-ZM / RBM / ZBH / DD-Lead / DD-Head / NBH / Legal / Finance / FDD / Architecture) |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `requestId`, `dealerName`, `targetStage`, `remarks`, `link`, `ctaLabel` |

**Body:**

> ## Action Required: {{requestId}}
>
> Hi,
>
> The request **{{requestId}}** (Dealer: **{{dealerName}}**) has reached the **{{targetStage}}** stage and requires your review and action.
>
> **Remarks from previous stage:** {{remarks}}
>
> Please log in to the RE Dealer Management Portal to review the case details and take action.
>
> [ **Review & Take Action** ]
>
> *This is an automated notification. Please do not reply to this email.*

---

### A.7.2 `WORKFLOW_STATUS_UPDATE_DEALER` — Generic Dealer Update

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/workflow_status_update_dealer.html` |
| **Subject** | `Update on Your Request — {{requestId}}` |
| **Trigger** | Any interim or terminal workflow event (Resignation / Termination / Constitutional / Relocation / Onboarding) that affects the dealer. |
| **Recipient** | Dealer |
| **Channels** | System always; Email + WhatsApp on terminal events (rejection / completion / revocation) |
| **Placeholders** | `requestId`, `dealerName`, `targetStage`, `remarks`, `link`, `ctaLabel` |

**Body:**

> ## Update on Your Request — {{requestId}}
>
> Dear {{dealerName}},
>
> Your request **{{requestId}}** has been updated. Current status: **{{targetStage}}**.
>
> **Note:** {{remarks}}
>
> You can track the live progress of your request on the dealer portal:
>
> [ **View Request** ]

---

### A.7.3 `WORKNOTE_NOTIFICATION` — Mention Notification

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/worknote_notification.html` |
| **Subject** | `New Update on Application: {{applicationId}}` |
| **Trigger** | A user is @mentioned in a work note (`collaboration.controller.ts`). |
| **Recipient** | The mentioned user |
| **Channels** | Email |
| **Placeholders** | `userName`, `applicationId`, `dealerName`, `message` |

**Body:**

> Hi {{userName}},
>
> You have a new work note or update on an application you are participating in.
>
> - **Application:** {{dealerName}} ({{applicationId}})
> - **Update:** {{message}}
>
> [ **View Worknote** ]

---

### A.7.4 `GENERIC_NOTIFICATION` — Fallback Template

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/generic_notification.html` |
| **Subject** | `{{title}}` |
| **Trigger** | Used by NotificationService when no specific template applies. |
| **Recipient** | Any user |
| **Channels** | Email |
| **Placeholders** | `title`, `message` |

**Body:**

> ## {{title}}
>
> {{message}}
>
> Please log in to the portal for more details.

---

## A.8 — SLA & Escalation Mails

### A.8.1 `SLA_REMINDER` — Approaching Deadline

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/sla_reminder.html` |
| **Subject** | `SLA Reminder: {{applicationId}} — {{stageName}}` |
| **Trigger** | SLA scheduler detects stage nearing TAT. |
| **Recipient** | Current stage owner |
| **Channels** | Email + System |
| **Placeholders** | `applicationId`, `stageName`, `link` |

**Body:**

> ## SLA Reminder
>
> This is a reminder that the following application is approaching its SLA deadline.
>
> - **Application ID:** {{applicationId}}
> - **SLA Stage:** {{stageName}}
>
> Please ensure this stage is completed promptly to avoid a breach.
>
> [ **Open Case** ]

---

### A.8.2 `SLA_BREACH_WARNING`

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/sla_breach_warning.html` |
| **Subject** | `SLA breach: {{applicationId}} — {{stageName}}` |
| **Trigger** | An SLA tracking record breaches its deadline. |
| **Recipient** | Stage owner |
| **Channels** | Email + System |
| **Placeholders** | `applicationId`, `stageName`, `currentStage` |

**Body:**

> ## SLA breach alert
>
> The following application has breached SLA for a workflow stage.
>
> - Application ID: {{applicationId}}
> - SLA stage: {{stageName}}
> - Current stage: {{currentStage}}
>
> Please take immediate action in the portal.
>
> [ **Open Case** ]

---

### A.8.3 `SLA_BREACH`

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/sla_breach.html` |
| **Subject** | `SLA BREACHED: {{applicationId}} — {{stageName}}` |
| **Trigger** | Confirmed breach event. |
| **Recipient** | Stage owner + escalation cohort |
| **Channels** | Email + System |

**Body:**

> ## SLA BREACHED
>
> The following application has exceeded its allotted Turnaround Time (TAT).
>
> - **Application ID:** {{applicationId}}
> - **SLA Stage:** {{stageName}}
>
> Action is required immediately to minimize further delay.
>
> [ **Open Case** ]

---

### A.8.4 `SLA_ESCALATION` — Multi-Level Escalation

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/sla_escalation.html` |
| **Subject** | `SLA ESCALATION [L{{level}}]: {{applicationId}} — {{stageName}}` |
| **Trigger** | Escalation chain L1 → L2 → L3 triggered when previous level does not act. |
| **Recipient** | Escalation level user (typically RBM → ZBH → DD-Head / NBH) |
| **Channels** | Email + System |
| **Placeholders** | `applicationId`, `stageName`, `level`, `timeValue`, `timeUnit`, `link` |

**Body:**

> ## SLA ESCALATION [Level {{level}}]
>
> The following application remains incomplete after an SLA breach for **{{stageName}}** and has been escalated to you.
>
> - **Application ID:** {{applicationId}}
> - **Escalation Level:** Level {{level}}
> - **Delay:** {{timeValue}} {{timeUnit}} past breach
>
> Please review and intervene to resolve the pending activity.
>
> [ **Open Case** ]

---

# Section B — Onboarding extensions (implemented)

> **For clients / Marketing / Legal:** Use **`RE_Dealer_Email_Content_Client_Brief.md`** in this folder — no code, only audiences, triggers, and sign-off.  
> Subsections **B.1–B.10** below keep technical fields (files, placeholders) and sample prose for administrators.

Templates are in `backend/src/emailtemplates/`, codes in `allowed-email-template-codes.ts`, seeds in `seed-master-emails.ts`, and triggers in `onboarding.controller.ts`, `loi.controller.ts`, `loa.controller.ts`, and `fdd.controller.ts` as noted per template.

---

## B.1 `PROSPECT_DOCUMENT_REQUEST` — Prospect document collection *(implemented)*

| Field | Value |
|---|---|
| **File** | `backend/src/emailtemplates/prospect_document_request.html` |
| **Subject** | `Documents Required — Royal Enfield Dealership Application {{applicationId}}` |
| **Triggers** | (a) **Automatic** — fires once at shortlist time (`onboarding.controller.ts → bulkShortlist`). (b) **Manual** — DD-Admin / Super Admin / DD Lead / DD Head presses **Request Documents** in the Application sidebar post-LOI-approval (see **B.11**). |
| **Recipient** | Applicant; WhatsApp if mobile on file. |
| **Placeholders** | `applicantName`, `location`, `applicationId`, `dueDate`, `documentList`, `link`, `ctaLabel`, `isShortlistContext` |
| **Context flag** | `isShortlistContext` (boolean). Set to `true` **only** by the shortlist trigger so the celebratory opening renders. The admin "Request Documents" action does *not* set this flag, so subsequent reminders read as neutral follow-ups instead of re-congratulating the prospect. |

**At shortlist (`isShortlistContext = true`):**

> Hi {{applicantName}},
>
> Congratulations on being shortlisted for the Royal Enfield Dealership opportunity at **{{location}}** (Application ID: **{{applicationId}}**).
>
> Please upload the documents listed below on the Dealer Portal by **{{dueDate}}**:
>
> {{documentList}}
>
> *(Final document list is determined by your application type — please refer to the portal for the authoritative checklist.)*
>
> [ **Upload Documents** ] → opens `{{link}}`
>
> All documents must be clear, in PDF / JPG format, and under 10 MB per file. For any clarifications, contact your local RE representative or write to dealer-support@royalenfield.com.
>
> Regards,
> Royal Enfield Dealer Development Team

**On admin follow-up (`isShortlistContext` omitted / falsy):**

> Hi {{applicantName}},
>
> We need a few documents to keep your Royal Enfield dealership application **{{applicationId}}** for **{{location}}** moving forward.
>
> Please upload the documents listed below on the Dealer Portal by **{{dueDate}}**:
>
> {{documentList}}
>
> [ **Upload Documents** ] → opens `{{link}}`
>
> Regards,
> Royal Enfield Dealer Development Team

---

## B.2 `STATUTORY_DOCUMENT_REQUEST` — Statutory Documents Collection (Post LOI)

| Field | Value |
|---|---|
| **Subject** | `Statutory Documents Required — {{applicationId}}` |
| **Trigger** | Sent after the LOI is issued. Aligns with the Architectural Work stage and Statutory Document Collection sub-stage of Module 1.8.2 in the test stories. |
| **Recipient** | Applicant (now Dealer-in-making) |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `applicantName`, `applicationId`, `dealerCode`, `statutoryList`, `dueDate`, `uploadLink`, `ctaLabel` |

**Proposed body:**

> Hi {{applicantName}},
>
> With the Letter of Intent issued for application **{{applicationId}}**, we now need the statutory documents necessary to open the dealership at the agreed location.
>
> Please upload the following on the Dealer Portal by **{{dueDate}}**:
>
> 1. **GST Registration Certificate**
> 2. **Trade License / Shop & Establishment Certificate** from the local municipal authority
> 3. **MSME / Udyam Registration Certificate** (if applicable)
> 4. **Fire Safety NOC** from the local fire department
> 5. **Pollution Control Board NOC**
> 6. **Building Plan Approval** from the local municipal corporation
> 7. **Electricity / Power Sanction Letter** (commercial)
> 8. **Lease Agreement / Sale Deed** (registered) of the dealership premises
> 9. **Property Tax Receipt** (latest)
> 10. **Insurance** — Building, Inventory & Public Liability
> 11. **Bank Account Opening Letter** in the dealership entity's name
> 12. **Memorandum / Articles of Association** (for Pvt. Ltd. entities) **or** Partnership Deed (for LLPs / Firms)
> 13. **Authorized Signatory List** + Board Resolution (where applicable)
>
> [ **Upload Statutory Documents** ] → `{{uploadLink}}`
>
> These documents are mandatory for the issuance of the Letter of Appointment (LOA) and SAP Dealer Codes. Any delay or missing documents will postpone your onboarding timeline. Our DD-Admin team will reach out for clarifications if anything needs re-submission.
>
> Regards,
> Royal Enfield Dealer Development Team

---

## B.3 `DOCUMENT_SUBMISSION_REMINDER` — Pending Document Reminder

| Field | Value |
|---|---|
| **Subject** | `Reminder: Pending documents for {{applicationId}}` |
| **Trigger** | Cron job — fires if a prospect / dealer has not uploaded all required documents within the configured SLA (e.g. T+3 days after `PROSPECT_DOCUMENT_REQUEST` / `STATUTORY_DOCUMENT_REQUEST`). |
| **Recipient** | Applicant |
| **Channels** | Email + WhatsApp |
| **Placeholders** | `applicantName`, `applicationId`, `pendingDocuments`, `dueDate`, `uploadLink` |

**Proposed body:**

> Hi {{applicantName}},
>
> Friendly reminder — the following documents are still pending against your application **{{applicationId}}**:
>
> {{pendingDocuments}}
>
> Please upload them by **{{dueDate}}** to avoid delays in your application processing.
>
> [ **Upload Pending Documents** ]
>
> If you have already uploaded these documents, please ignore this email.

---

## B.4 `DOCUMENT_RECEIVED_ACKNOWLEDGEMENT`

| Field | Value |
|---|---|
| **Subject** | `Documents received — {{applicationId}}` |
| **Trigger** | When the prospect / dealer uploads all mandatory documents for a category. |
| **Recipient** | Applicant + DD-Admin (cc) |
| **Channels** | Email |
| **Placeholders** | `applicantName`, `applicationId`, `documentCategory`, `receivedOn`, `link` |

**Proposed body:**

> Hi {{applicantName}},
>
> Thank you. We have received the following documents for your dealership application **{{applicationId}}** (Category: **{{documentCategory}}**) on **{{receivedOn}}**.
>
> Our DD-Admin and Legal teams will now verify the submitted documents. You will receive a separate notification if any document needs to be re-submitted, or once the verification is complete.
>
> [ **View Submission** ]

---

## B.5 `DOCUMENT_REJECTED_RESUBMIT` — Resubmission Request

| Field | Value |
|---|---|
| **Subject** | `Action Required: Re-submit documents for {{applicationId}}` |
| **Trigger** | DD-Admin / Legal marks a submitted document as Rejected / Re-submission Required. |
| **Recipient** | Applicant |
| **Channels** | Email + WhatsApp + System |
| **Placeholders** | `applicantName`, `applicationId`, `documentName`, `rejectionReason`, `dueDate`, `uploadLink` |

**Proposed body:**

> Hi {{applicantName}},
>
> One or more documents you uploaded for application **{{applicationId}}** could not be accepted.
>
> - **Document:** {{documentName}}
> - **Reason:** {{rejectionReason}}
>
> Please re-upload the corrected document on the Dealer Portal by **{{dueDate}}**.
>
> [ **Re-Upload Document** ]
>
> If you have any queries regarding the reason, please contact your assigned DD representative or write to dealer-support@royalenfield.com.

---

## B.6 `FDD_DOCUMENT_REQUEST` — FDD (Financial Due Diligence) Document Collection

| Field | Value |
|---|---|
| **Subject** | `FDD Documents Required — {{applicationId}}` |
| **Trigger** | DD-Admin assigns an FDD partner; the partner needs to receive a complete document checklist from the applicant. |
| **Recipient** | Applicant (cc: FDD partner, DD-Admin) |
| **Channels** | Email |
| **Placeholders** | `applicantName`, `applicationId`, `fddPartnerName`, `documentChecklist`, `dueDate`, `uploadLink` |

**Proposed body:**

> Hi {{applicantName}},
>
> As part of the Financial Due Diligence (FDD) for your dealership application **{{applicationId}}**, **{{fddPartnerName}}** has been engaged to perform the assessment.
>
> Please upload the following documents on the Dealer Portal by **{{dueDate}}**:
>
> {{documentChecklist}}
>
> Typical documents include audited financial statements (last 3 FYs), GST returns (last 12 months), bank statements (last 12 months), proof of working capital, existing loan obligations, and director / partner net worth statements.
>
> [ **Upload FDD Documents** ]
>
> The FDD partner will independently contact you for any clarifications. Any non-disclosure will impact your application evaluation.

---

## B.7 `LOI_ACKNOWLEDGEMENT_REQUEST`

| Field | Value |
|---|---|
| **Subject** | `Action Required: Acknowledge your Letter of Intent — {{applicationId}}` |
| **Trigger** | Within 24h of `LOI_ISSUED` if the applicant has not signed / acknowledged the LOI in the portal. |
| **Recipient** | Applicant |
| **Channels** | Email + WhatsApp |
| **Placeholders** | `applicantName`, `applicationId`, `loiLink`, `dueDate` |

**Proposed body:**

> Hi {{applicantName}},
>
> Your Letter of Intent (LOI) for **{{applicationId}}** is awaiting your acknowledgement.
>
> Please log in to the Dealer Portal, review the document, and digitally acknowledge it by **{{dueDate}}**. Without your acknowledgement we cannot proceed to the next stage of onboarding.
>
> [ **Acknowledge LOI** ]

---

## B.8 `SECURITY_DEPOSIT_REQUEST`

| Field | Value |
|---|---|
| **Subject** | `Security Deposit Payment Required — {{applicationId}}` |
| **Trigger** | After LOI is acknowledged by the applicant; before LOA processing. |
| **Recipient** | Applicant |
| **Channels** | Email |
| **Placeholders** | `applicantName`, `applicationId`, `amount`, `paymentLink`, `bankDetails`, `dueDate` |

**Proposed body:**

> Hi {{applicantName}},
>
> Per the terms of your Letter of Intent for **{{applicationId}}**, the next step is to remit the **Security Deposit of ₹{{amount}}** before **{{dueDate}}**.
>
> You may pay through any of the following channels:
>
> - Online payment via the Dealer Portal: [ **Pay Now** ] → `{{paymentLink}}`
> - RTGS / NEFT to the following account:
>
> ```
> {{bankDetails}}
> ```
>
> After remitting, please upload the payment confirmation (UTR / Transaction reference) on the portal. Finance will verify within 2 working days and we will notify you (see `ONBOARDING_PAYMENT_VERIFIED`).

---

## B.9 `DEALERSHIP_AGREEMENT_SIGNATURE_REQUEST`

| Field | Value |
|---|---|
| **Subject** | `Dealership Agreement ready for signature — {{applicationId}}` |
| **Trigger** | LOA is issued — Legal generates the dealership agreement; awaiting applicant + Royal Enfield authorised signatory's e-sign. |
| **Recipient** | Applicant |
| **Channels** | Email |
| **Placeholders** | `applicantName`, `applicationId`, `dealerCode`, `agreementLink`, `dueDate` |

**Proposed body:**

> Hi {{applicantName}},
>
> Congratulations once again on your appointment as a Royal Enfield Dealer ({{dealerCode}}).
>
> The **Dealership Agreement** for application **{{applicationId}}** is now ready for your signature. Please review the document in full and e-sign it on the Dealer Portal by **{{dueDate}}**.
>
> [ **Review & Sign Agreement** ]
>
> Once your signature is recorded, the document is automatically routed to Royal Enfield's authorised signatory for counter-signature.

---

## B.10 `ARCHITECTURAL_PLAN_REQUEST`

| Field | Value |
|---|---|
| **Subject** | `Architectural Plan & Site Inputs Required — {{applicationId}}` |
| **Trigger** | DD-Admin assigns the Architecture team to a freshly issued LOI (Test Story 1.8.1). |
| **Recipient** | Applicant (cc: Architecture Lead) |
| **Channels** | Email |
| **Placeholders** | `applicantName`, `applicationId`, `architectName`, `inputsList`, `dueDate`, `uploadLink` |

**Proposed body:**

> Hi {{applicantName}},
>
> Our Architecture team (led by **{{architectName}}**) is ready to begin the dealership site design for **{{applicationId}}**.
>
> To kick this off, please share the following on the portal by **{{dueDate}}**:
>
> {{inputsList}}
>
> Typical inputs needed:
>
> 1. Site dimensions and orientation drawings
> 2. Photographs of site (front, side, internal) and surroundings
> 3. Civic / municipal site approvals and zoning details
> 4. Electricity load sanction letter
> 5. Soil-test report (if available)
> 6. Proposed entry, parking, signage location preferences
>
> [ **Upload Site Inputs** ]
>
> Once these are received, the Architecture team will share a draft plan within 7 working days.

---

## B.11 On-Demand Document Request — Admin "Request Documents" action *(implemented)*

This is **not a new email template** — it is an **orchestration layer** wired into the application details sidebar that fans out to the existing applicant document templates (`B.1`, `B.2`, `B.6`, `B.10`) based on what the admin selects. It exists so a reviewer can re-poke the prospect for *exactly the documents that are still missing* at any point post-LOI without having to wait for a stage transition or send a generic broadcast.

### Where it lives

| Field | Value |
|---|---|
| **UI entry point** | Amber "Request Documents" button in the application sidebar action area. |
| **Backend endpoint** | `POST /onboarding/applications/:id/request-documents` (`onboarding.controller.ts → requestProspectDocuments`). |
| **Route registration** | `onboarding.routes.ts`. |
| **Audit action** | `DOCUMENT_REQUEST_SENT` — written to `AuditLog` with per-category email status, skipped uploads, due-days, and the requesting role. |

### Visibility gating

| Layer | Rule |
|---|---|
| **Role** | Visible only when current user is `DD Admin`, `Super Admin`, `DD Lead`, or `DD Head`. Server enforces the same allowlist on the endpoint. |
| **Stage** | Only when `application.overallStatus` is in the post-LOI corridor — i.e. `Security Deposit` / `Security Details` / `Payment Pending` / `LOI Issuance Pending` / `LOI Issued` / `Dealer Code Generation` / `Architecture Team Assigned` / `Architecture Document Upload` / `Architecture Team Completion` / `Statutory *` / `LOA Pending`. |

### Request body

```json
{
  "documentTypes": ["Letter of Intent", "GST Certificate", "Bank Statement"],
  "dueDays": 10,
  "customMessage": "Please prioritise these — Finance review depends on them."
}
```

### Server-side orchestration

1. **Drop already-uploaded types.** The endpoint queries `OnboardingDocument` for the requested types and removes any that already exist. Their names are returned in `skippedAlreadyUploaded`.
2. **Categorise via `DocumentStageConfig.stageCode`** into one of: `LOI`, `Statutory`, `Architecture`, `FDD`, `Other`.
3. **Fan out — one email per non-empty bucket**, reusing the existing applicant templates:

| Bucket | Template Code | List Placeholder | Notes |
|---|---|---|---|
| LOI | `PROSPECT_DOCUMENT_REQUEST` | `documentList` | Neutral copy (no shortlist congrats) because the orchestrator does not pass `isShortlistContext`. |
| Statutory | `STATUTORY_DOCUMENT_REQUEST` | `statutoryList` | |
| Architecture | `ARCHITECTURAL_PLAN_REQUEST` | `inputsList` | Adds `architectName: 'Royal Enfield Architecture Team'` for the salutation line. |
| FDD | `FDD_DOCUMENT_REQUEST` | `documentChecklist` | Adds `fddPartnerName: 'Assigned FDD Partner'` for the body line. |
| Other | `PROSPECT_DOCUMENT_REQUEST` | `documentList` | Fallback for unclassified types; same neutral copy. |

4. **Channels per email** — `email` always; `whatsapp` added when the applicant has a mobile number on file. The `customMessage` is dropped into each email's `message` body line, while the per-bucket `listKey` carries the numbered list of selected documents.
5. **Response payload** lets the UI render an accurate toast:

```json
{
  "success": true,
  "data": {
    "requested": ["Letter of Intent", "Bank Statement"],
    "skippedAlreadyUploaded": ["GST Certificate"],
    "emailsSent": [
      { "category": "LOI", "status": "sent", "docCount": 1, "items": ["Letter of Intent"] },
      { "category": "FDD", "status": "sent", "docCount": 1, "items": ["Bank Statement"] }
    ]
  }
}
```

### Recipient experience

The applicant receives **N emails**, where N is the number of non-empty buckets. Each email is self-contained — it only mentions the documents in that category and uses the wording of the corresponding existing template. There is no "we sent you 4 separate emails" preamble; this preserves backwards-compatible inbox behaviour with single-category sends from the stage-transition triggers.

### Why this matters for copy

- The `PROSPECT_DOCUMENT_REQUEST` template was previously hard-coded with the shortlist congrats line. Anyone reviewing the copy should know that this line is now **conditional on `isShortlistContext`** and will *not* appear when the admin re-requests documents later. See B.1 for both variants.
- The other three templates (`STATUTORY_*`, `ARCHITECTURAL_*`, `FDD_*`) were already neutral on tone, so no copy change was needed for the on-demand flow.

---

# Appendix — Common Header / Footer / CTA Partials

### Header Partial — `partials/email_header.html`

Renders the black Royal Enfield banner with the centred logo. Used by every templated email.

```html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
    body { font-family: Arial, Helvetica, sans-serif; color: #333; line-height: 1.6; margin: 0; padding: 0; }
    .container { max-width: 600px; margin: 0 auto; border: 1px solid #eee; }
    .header  { background-color: #000000; padding: 24px 16px; text-align: center; }
    .header img { display: block; margin: 0 auto; max-width: 320px; width: 100%; height: auto; }
    .content { padding: 30px; }
    .footer  { background-color: #f8f9fa; padding: 20px; text-align: center; font-size: 12px; color: #777; }
    .status-badge { display: inline-block; padding: 6px 12px; background-color: #f8f9fa; border: 1px solid #ddd; border-radius: 4px; font-weight: bold; margin: 10px 0; }
    .details { background-color: #f9f9f9; padding: 15px; border-radius: 4px; border-left: 4px solid #e31837; margin: 20px 0; }
    .code-box { background-color: #f4f4f4; padding: 15px; border: 1px dashed #e31837; text-align: center; font-family: monospace; font-size: 18px; margin: 20px 0; }
</style>
</head>
<body>
<div class="container">
  <div class="header">
    <img src="__EMAIL_HEADER_LOGO_SRC__" alt="Royal Enfield" width="320" />
  </div>
  <div class="content">
```

### Footer Partial — `partials/email_footer.html`

```html
  </div>
  <div class="footer">
    <p>&copy; {{year}} Royal Enfield. All rights reserved.</p>
    <p>This is an automated message, please do not reply.</p>
  </div>
</div>
</body>
</html>
```

### Primary CTA Partial — `partials/primary_cta.html`

Renders a red action button when a CTA URL is supplied.

```html
{{#if ctaUrl}}
<div style="text-align:center;margin-top:20px;">
  <a href="{{ctaUrl}}"
     style="display:inline-block;padding:12px 24px;background-color:#e31837;
            color:#fff;text-decoration:none;border-radius:4px;font-weight:bold;">
    {{#if ctaLabel}}{{ctaLabel}}{{else}}View details{{/if}}
  </a>
</div>
{{/if}}
```

---

## Change Log

| Date | Author | Description |
|---|---|---|
| 2026-05-11 | Engineering | Section B templates implemented in app; added `RE_Dealer_Email_Content_Client_Brief.md` for client copy prep. |
| 2026-05-26 | Engineering | **B.1** `PROSPECT_DOCUMENT_REQUEST` — body made conditional on new `isShortlistContext` placeholder so follow-up re-requests do not repeat the shortlist congratulations. Added **B.11** documenting the admin **Request Documents** action (`POST /onboarding/applications/:id/request-documents`) which orchestrates per-category emails reusing B.1/B.2/B.6/B.10. |
| 2026-05-26 | Engineering | **All prospect / applicant templates** — `link` placeholder now points to the prospect portal (`/prospective-login?next=/prospective-dashboard/application/:id`) instead of the internal admin screen `/applications/:id`, which the applicant cannot access. Added helper `getProspectPortalUrl()` (`backend/src/common/utils/frontendUrl.ts`) and updated `ProspectiveLoginPage` to honour the `next` query parameter for post-OTP deep-linking. Also fixed a long-standing typo where several emails linked to `/prospect-login` (singular) — the actual route is `/prospective-login`. Affects: B.1, B.2, B.3, B.4, B.5, B.6, B.9 acknowledgement chase, all milestone applicant emails via `WorkflowService` (B.5 LOA, dealer code, shortlist, rejection), interview applicant emails (B.7 / B.8), and bulk document-reminder send. Internal-user emails (workflow approvers, panelists, FDD partner) continue to use `/applications/:id`. |
