/** * Allowed email template triggers — keep aligned with backend * `backend/src/constants/allowed-email-template-codes.ts` and `seed-master-emails.ts`. */ export const ALLOWED_EMAIL_TEMPLATE_CODES = [ 'APPLICANT_SHORTLISTED', 'APPLICANT_REJECTED', 'ARCHITECTURAL_PLAN_REQUEST', 'CONSTITUTIONAL_CHANGE_SUBMITTED', 'DEALERSHIP_AGREEMENT_SIGNATURE_REQUEST', 'CONSTITUTIONAL_CHANGE_APPROVED', 'CONSTITUTIONAL_CHANGE_UPDATE', 'DEALER_CODE_READY', 'DOCUMENT_RECEIVED_ACKNOWLEDGEMENT', 'DOCUMENT_REJECTED_RESUBMIT', 'DOCUMENT_SUBMISSION_REMINDER', 'EOR_COMPLETED', 'FDD_DOCUMENT_REQUEST', 'FNF_INITIATED', 'FNF_LWD_READY', 'FNF_SUMMARY_PREPARED', 'FNF_SETTLEMENT_APPROVED', 'GENERIC_NOTIFICATION', 'INAUGURATION_COMPLETED', 'INTERVIEW_SCHEDULED', 'INTERVIEW_SCHEDULED_APPLICANT', 'INTERVIEW_SCHEDULED_PANELIST', 'INTERVIEW_RESCHEDULED_APPLICANT', 'INTERVIEW_RESCHEDULED_PANELIST', 'INTERVIEW_CANCELLED_APPLICANT', 'INTERVIEW_CANCELLED_PANELIST', 'LOA_ISSUED', 'LOI_ACKNOWLEDGEMENT_REQUEST', 'LOI_ISSUED', 'NON_OPPORTUNITY', 'ONBOARDING_PAYMENT_VERIFIED', 'ONBOARDING_STATUS_UPDATE', 'OPPORTUNITY', 'PROSPECT_DOCUMENT_REQUEST', 'QUESTIONNAIRE_REMINDER', 'QUESTIONNAIRE_SUBMITTED', 'SECURITY_DEPOSIT_REQUEST', 'RELOCATION_RECEIVED', 'RELOCATION_SUBMITTED', 'RELOCATION_APPROVED', 'RELOCATION_UPDATE', 'RESIGNATION_APPROVED', 'RESIGNATION_RECEIVED', 'RESIGNATION_SUBMITTED', 'RESIGNATION_UPDATE', 'SLA_BREACH_WARNING', 'STATUTORY_DOCUMENT_REQUEST', 'SLA_REMINDER', 'SLA_BREACH', 'SLA_ESCALATION', 'TERMINATION_INITIATED', 'TERMINATION_SCN_ISSUED', 'TERMINATION_LETTER_ISSUED', 'TERMINATION_FINAL_CLOSURE_DEALER', 'TERMINATION_UPDATE', 'USER_ASSIGNED', 'WORKNOTE_NOTIFICATION', 'WORKFLOW_ACTION_REQUIRED', 'WORKFLOW_STATUS_UPDATE_DEALER' ] as const; const ALLOWED_SET = new Set(ALLOWED_EMAIL_TEMPLATE_CODES); export function isAllowedEmailTemplateCode(code: string): boolean { return ALLOWED_SET.has(code.trim().toUpperCase()); }